]> git.openstreetmap.org Git - rails.git/blobdiff - vendor/assets/iD/iD/mapillary-js/mapillary.js
Update to iD v2.9.0
[rails.git] / vendor / assets / iD / iD / mapillary-js / mapillary.js
index 5ffb3a7e1499dc7bebec3d7c15cb6aa619c17c73..40cbd5b8fb21eeb21b522315920e7a2ee89c7353 100644 (file)
@@ -156,7 +156,7 @@ function getSegDistSq(px, py, a, b) {
     return dx * dx + dy * dy;
 }
 
-},{"tinyqueue":232}],2:[function(require,module,exports){
+},{"tinyqueue":241}],2:[function(require,module,exports){
 /*
  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
  *
@@ -5394,7 +5394,7 @@ var BehaviorSubject = (function (_super) {
 }(Subject_1.Subject));
 exports.BehaviorSubject = BehaviorSubject;
 
-},{"./Subject":34,"./util/ObjectUnsubscribedError":211}],27:[function(require,module,exports){
+},{"./Subject":34,"./util/ObjectUnsubscribedError":220}],27:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -5865,7 +5865,7 @@ var Observable = (function () {
 }());
 exports.Observable = Observable;
 
-},{"./symbol/observable":206,"./util/pipe":226,"./util/root":227,"./util/toSubscriber":229}],30:[function(require,module,exports){
+},{"./symbol/observable":215,"./util/pipe":235,"./util/root":236,"./util/toSubscriber":238}],30:[function(require,module,exports){
 "use strict";
 exports.empty = {
     closed: true,
@@ -6008,7 +6008,7 @@ var ReplayEvent = (function () {
     return ReplayEvent;
 }());
 
-},{"./Subject":34,"./SubjectSubscription":35,"./Subscription":37,"./operators/observeOn":174,"./scheduler/queue":204,"./util/ObjectUnsubscribedError":211}],33:[function(require,module,exports){
+},{"./Subject":34,"./SubjectSubscription":35,"./Subscription":37,"./operators/observeOn":183,"./scheduler/queue":213,"./util/ObjectUnsubscribedError":220}],33:[function(require,module,exports){
 "use strict";
 /**
  * An execution context and a data structure to order tasks and schedule their
@@ -6227,7 +6227,7 @@ var AnonymousSubject = (function (_super) {
 }(Subject));
 exports.AnonymousSubject = AnonymousSubject;
 
-},{"./Observable":29,"./SubjectSubscription":35,"./Subscriber":36,"./Subscription":37,"./symbol/rxSubscriber":207,"./util/ObjectUnsubscribedError":211}],35:[function(require,module,exports){
+},{"./Observable":29,"./SubjectSubscription":35,"./Subscriber":36,"./Subscription":37,"./symbol/rxSubscriber":216,"./util/ObjectUnsubscribedError":220}],35:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -6533,7 +6533,7 @@ var SafeSubscriber = (function (_super) {
     return SafeSubscriber;
 }(Subscriber));
 
-},{"./Observer":30,"./Subscription":37,"./symbol/rxSubscriber":207,"./util/isFunction":220}],37:[function(require,module,exports){
+},{"./Observer":30,"./Subscription":37,"./symbol/rxSubscriber":216,"./util/isFunction":229}],37:[function(require,module,exports){
 "use strict";
 var isArray_1 = require('./util/isArray');
 var isObject_1 = require('./util/isObject');
@@ -6727,317 +6727,335 @@ function flattenUnsubscriptionErrors(errors) {
     return errors.reduce(function (errs, err) { return errs.concat((err instanceof UnsubscriptionError_1.UnsubscriptionError) ? err.errors : err); }, []);
 }
 
-},{"./util/UnsubscriptionError":214,"./util/errorObject":215,"./util/isArray":217,"./util/isFunction":220,"./util/isObject":222,"./util/tryCatch":230}],38:[function(require,module,exports){
+},{"./util/UnsubscriptionError":223,"./util/errorObject":224,"./util/isArray":226,"./util/isFunction":229,"./util/isObject":231,"./util/tryCatch":239}],38:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var combineLatest_1 = require('../../observable/combineLatest');
 Observable_1.Observable.combineLatest = combineLatest_1.combineLatest;
 
-},{"../../Observable":29,"../../observable/combineLatest":101}],39:[function(require,module,exports){
+},{"../../Observable":29,"../../observable/combineLatest":104}],39:[function(require,module,exports){
+"use strict";
+var Observable_1 = require('../../Observable');
+var concat_1 = require('../../observable/concat');
+Observable_1.Observable.concat = concat_1.concat;
+
+},{"../../Observable":29,"../../observable/concat":105}],40:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var defer_1 = require('../../observable/defer');
 Observable_1.Observable.defer = defer_1.defer;
 
-},{"../../Observable":29,"../../observable/defer":103}],40:[function(require,module,exports){
+},{"../../Observable":29,"../../observable/defer":106}],41:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var empty_1 = require('../../observable/empty');
 Observable_1.Observable.empty = empty_1.empty;
 
-},{"../../Observable":29,"../../observable/empty":104}],41:[function(require,module,exports){
+},{"../../Observable":29,"../../observable/empty":107}],42:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var from_1 = require('../../observable/from');
 Observable_1.Observable.from = from_1.from;
 
-},{"../../Observable":29,"../../observable/from":105}],42:[function(require,module,exports){
+},{"../../Observable":29,"../../observable/from":108}],43:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var fromEvent_1 = require('../../observable/fromEvent');
 Observable_1.Observable.fromEvent = fromEvent_1.fromEvent;
 
-},{"../../Observable":29,"../../observable/fromEvent":106}],43:[function(require,module,exports){
+},{"../../Observable":29,"../../observable/fromEvent":109}],44:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var fromPromise_1 = require('../../observable/fromPromise');
 Observable_1.Observable.fromPromise = fromPromise_1.fromPromise;
 
-},{"../../Observable":29,"../../observable/fromPromise":107}],44:[function(require,module,exports){
+},{"../../Observable":29,"../../observable/fromPromise":110}],45:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var merge_1 = require('../../observable/merge');
 Observable_1.Observable.merge = merge_1.merge;
 
-},{"../../Observable":29,"../../observable/merge":108}],45:[function(require,module,exports){
+},{"../../Observable":29,"../../observable/merge":111}],46:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var of_1 = require('../../observable/of');
 Observable_1.Observable.of = of_1.of;
 
-},{"../../Observable":29,"../../observable/of":109}],46:[function(require,module,exports){
+},{"../../Observable":29,"../../observable/of":112}],47:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var throw_1 = require('../../observable/throw');
 Observable_1.Observable.throw = throw_1._throw;
 
-},{"../../Observable":29,"../../observable/throw":110}],47:[function(require,module,exports){
+},{"../../Observable":29,"../../observable/throw":113}],48:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var timer_1 = require('../../observable/timer');
 Observable_1.Observable.timer = timer_1.timer;
 
-},{"../../Observable":29,"../../observable/timer":111}],48:[function(require,module,exports){
+},{"../../Observable":29,"../../observable/timer":114}],49:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var zip_1 = require('../../observable/zip');
 Observable_1.Observable.zip = zip_1.zip;
 
-},{"../../Observable":29,"../../observable/zip":112}],49:[function(require,module,exports){
+},{"../../Observable":29,"../../observable/zip":115}],50:[function(require,module,exports){
+"use strict";
+var Observable_1 = require('../../Observable');
+var auditTime_1 = require('../../operator/auditTime');
+Observable_1.Observable.prototype.auditTime = auditTime_1.auditTime;
+
+},{"../../Observable":29,"../../operator/auditTime":116}],51:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var buffer_1 = require('../../operator/buffer');
 Observable_1.Observable.prototype.buffer = buffer_1.buffer;
 
-},{"../../Observable":29,"../../operator/buffer":113}],50:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/buffer":117}],52:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var bufferCount_1 = require('../../operator/bufferCount');
 Observable_1.Observable.prototype.bufferCount = bufferCount_1.bufferCount;
 
-},{"../../Observable":29,"../../operator/bufferCount":114}],51:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/bufferCount":118}],53:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var bufferWhen_1 = require('../../operator/bufferWhen');
 Observable_1.Observable.prototype.bufferWhen = bufferWhen_1.bufferWhen;
 
-},{"../../Observable":29,"../../operator/bufferWhen":115}],52:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/bufferWhen":119}],54:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var catch_1 = require('../../operator/catch');
 Observable_1.Observable.prototype.catch = catch_1._catch;
 Observable_1.Observable.prototype._catch = catch_1._catch;
 
-},{"../../Observable":29,"../../operator/catch":116}],53:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/catch":120}],55:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var combineLatest_1 = require('../../operator/combineLatest');
 Observable_1.Observable.prototype.combineLatest = combineLatest_1.combineLatest;
 
-},{"../../Observable":29,"../../operator/combineLatest":117}],54:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/combineLatest":121}],56:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var concat_1 = require('../../operator/concat');
 Observable_1.Observable.prototype.concat = concat_1.concat;
 
-},{"../../Observable":29,"../../operator/concat":118}],55:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/concat":122}],57:[function(require,module,exports){
+"use strict";
+var Observable_1 = require('../../Observable');
+var count_1 = require('../../operator/count');
+Observable_1.Observable.prototype.count = count_1.count;
+
+},{"../../Observable":29,"../../operator/count":123}],58:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var debounceTime_1 = require('../../operator/debounceTime');
 Observable_1.Observable.prototype.debounceTime = debounceTime_1.debounceTime;
 
-},{"../../Observable":29,"../../operator/debounceTime":119}],56:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/debounceTime":124}],59:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var delay_1 = require('../../operator/delay');
 Observable_1.Observable.prototype.delay = delay_1.delay;
 
-},{"../../Observable":29,"../../operator/delay":120}],57:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/delay":125}],60:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var distinct_1 = require('../../operator/distinct');
 Observable_1.Observable.prototype.distinct = distinct_1.distinct;
 
-},{"../../Observable":29,"../../operator/distinct":121}],58:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/distinct":126}],61:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var distinctUntilChanged_1 = require('../../operator/distinctUntilChanged');
 Observable_1.Observable.prototype.distinctUntilChanged = distinctUntilChanged_1.distinctUntilChanged;
 
-},{"../../Observable":29,"../../operator/distinctUntilChanged":122}],59:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/distinctUntilChanged":127}],62:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var do_1 = require('../../operator/do');
 Observable_1.Observable.prototype.do = do_1._do;
 Observable_1.Observable.prototype._do = do_1._do;
 
-},{"../../Observable":29,"../../operator/do":123}],60:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/do":128}],63:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var expand_1 = require('../../operator/expand');
 Observable_1.Observable.prototype.expand = expand_1.expand;
 
-},{"../../Observable":29,"../../operator/expand":124}],61:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/expand":129}],64:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var filter_1 = require('../../operator/filter');
 Observable_1.Observable.prototype.filter = filter_1.filter;
 
-},{"../../Observable":29,"../../operator/filter":125}],62:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/filter":130}],65:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var finally_1 = require('../../operator/finally');
 Observable_1.Observable.prototype.finally = finally_1._finally;
 Observable_1.Observable.prototype._finally = finally_1._finally;
 
-},{"../../Observable":29,"../../operator/finally":126}],63:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/finally":131}],66:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var first_1 = require('../../operator/first');
 Observable_1.Observable.prototype.first = first_1.first;
 
-},{"../../Observable":29,"../../operator/first":127}],64:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/first":132}],67:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var last_1 = require('../../operator/last');
 Observable_1.Observable.prototype.last = last_1.last;
 
-},{"../../Observable":29,"../../operator/last":128}],65:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/last":133}],68:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var map_1 = require('../../operator/map');
 Observable_1.Observable.prototype.map = map_1.map;
 
-},{"../../Observable":29,"../../operator/map":129}],66:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/map":134}],69:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var merge_1 = require('../../operator/merge');
 Observable_1.Observable.prototype.merge = merge_1.merge;
 
-},{"../../Observable":29,"../../operator/merge":130}],67:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/merge":135}],70:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var mergeAll_1 = require('../../operator/mergeAll');
 Observable_1.Observable.prototype.mergeAll = mergeAll_1.mergeAll;
 
-},{"../../Observable":29,"../../operator/mergeAll":131}],68:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/mergeAll":136}],71:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var mergeMap_1 = require('../../operator/mergeMap');
 Observable_1.Observable.prototype.mergeMap = mergeMap_1.mergeMap;
 Observable_1.Observable.prototype.flatMap = mergeMap_1.mergeMap;
 
-},{"../../Observable":29,"../../operator/mergeMap":132}],69:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/mergeMap":137}],72:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var pairwise_1 = require('../../operator/pairwise');
 Observable_1.Observable.prototype.pairwise = pairwise_1.pairwise;
 
-},{"../../Observable":29,"../../operator/pairwise":133}],70:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/pairwise":138}],73:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var pluck_1 = require('../../operator/pluck');
 Observable_1.Observable.prototype.pluck = pluck_1.pluck;
 
-},{"../../Observable":29,"../../operator/pluck":134}],71:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/pluck":139}],74:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var publish_1 = require('../../operator/publish');
 Observable_1.Observable.prototype.publish = publish_1.publish;
 
-},{"../../Observable":29,"../../operator/publish":135}],72:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/publish":140}],75:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var publishReplay_1 = require('../../operator/publishReplay');
 Observable_1.Observable.prototype.publishReplay = publishReplay_1.publishReplay;
 
-},{"../../Observable":29,"../../operator/publishReplay":136}],73:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/publishReplay":141}],76:[function(require,module,exports){
+"use strict";
+var Observable_1 = require('../../Observable');
+var reduce_1 = require('../../operator/reduce');
+Observable_1.Observable.prototype.reduce = reduce_1.reduce;
+
+},{"../../Observable":29,"../../operator/reduce":142}],77:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var retry_1 = require('../../operator/retry');
 Observable_1.Observable.prototype.retry = retry_1.retry;
 
-},{"../../Observable":29,"../../operator/retry":137}],74:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/retry":143}],78:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var sample_1 = require('../../operator/sample');
 Observable_1.Observable.prototype.sample = sample_1.sample;
 
-},{"../../Observable":29,"../../operator/sample":138}],75:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/sample":144}],79:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var scan_1 = require('../../operator/scan');
 Observable_1.Observable.prototype.scan = scan_1.scan;
 
-},{"../../Observable":29,"../../operator/scan":139}],76:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/scan":145}],80:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var share_1 = require('../../operator/share');
 Observable_1.Observable.prototype.share = share_1.share;
 
-},{"../../Observable":29,"../../operator/share":140}],77:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/share":146}],81:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var skip_1 = require('../../operator/skip');
 Observable_1.Observable.prototype.skip = skip_1.skip;
 
-},{"../../Observable":29,"../../operator/skip":141}],78:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/skip":147}],82:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var skipUntil_1 = require('../../operator/skipUntil');
 Observable_1.Observable.prototype.skipUntil = skipUntil_1.skipUntil;
 
-},{"../../Observable":29,"../../operator/skipUntil":142}],79:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/skipUntil":148}],83:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var skipWhile_1 = require('../../operator/skipWhile');
 Observable_1.Observable.prototype.skipWhile = skipWhile_1.skipWhile;
 
-},{"../../Observable":29,"../../operator/skipWhile":143}],80:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/skipWhile":149}],84:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var startWith_1 = require('../../operator/startWith');
 Observable_1.Observable.prototype.startWith = startWith_1.startWith;
 
-},{"../../Observable":29,"../../operator/startWith":144}],81:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/startWith":150}],85:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var switchMap_1 = require('../../operator/switchMap');
 Observable_1.Observable.prototype.switchMap = switchMap_1.switchMap;
 
-},{"../../Observable":29,"../../operator/switchMap":145}],82:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/switchMap":151}],86:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var take_1 = require('../../operator/take');
 Observable_1.Observable.prototype.take = take_1.take;
 
-},{"../../Observable":29,"../../operator/take":146}],83:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/take":152}],87:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var takeUntil_1 = require('../../operator/takeUntil');
 Observable_1.Observable.prototype.takeUntil = takeUntil_1.takeUntil;
 
-},{"../../Observable":29,"../../operator/takeUntil":147}],84:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/takeUntil":153}],88:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var takeWhile_1 = require('../../operator/takeWhile');
 Observable_1.Observable.prototype.takeWhile = takeWhile_1.takeWhile;
 
-},{"../../Observable":29,"../../operator/takeWhile":148}],85:[function(require,module,exports){
-"use strict";
-var Observable_1 = require('../../Observable');
-var throttleTime_1 = require('../../operator/throttleTime');
-Observable_1.Observable.prototype.throttleTime = throttleTime_1.throttleTime;
-
-},{"../../Observable":29,"../../operator/throttleTime":149}],86:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/takeWhile":154}],89:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var timeout_1 = require('../../operator/timeout');
 Observable_1.Observable.prototype.timeout = timeout_1.timeout;
 
-},{"../../Observable":29,"../../operator/timeout":150}],87:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/timeout":155}],90:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var withLatestFrom_1 = require('../../operator/withLatestFrom');
 Observable_1.Observable.prototype.withLatestFrom = withLatestFrom_1.withLatestFrom;
 
-},{"../../Observable":29,"../../operator/withLatestFrom":151}],88:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/withLatestFrom":156}],91:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../../Observable');
 var zip_1 = require('../../operator/zip');
 Observable_1.Observable.prototype.zip = zip_1.zipProto;
 
-},{"../../Observable":29,"../../operator/zip":152}],89:[function(require,module,exports){
+},{"../../Observable":29,"../../operator/zip":157}],92:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -7108,7 +7126,7 @@ var ArrayLikeObservable = (function (_super) {
 }(Observable_1.Observable));
 exports.ArrayLikeObservable = ArrayLikeObservable;
 
-},{"../Observable":29,"./EmptyObservable":93,"./ScalarObservable":99}],90:[function(require,module,exports){
+},{"../Observable":29,"./EmptyObservable":96,"./ScalarObservable":102}],93:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -7231,7 +7249,7 @@ var ArrayObservable = (function (_super) {
 }(Observable_1.Observable));
 exports.ArrayObservable = ArrayObservable;
 
-},{"../Observable":29,"../util/isScheduler":224,"./EmptyObservable":93,"./ScalarObservable":99}],91:[function(require,module,exports){
+},{"../Observable":29,"../util/isScheduler":233,"./EmptyObservable":96,"./ScalarObservable":102}],94:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -7402,7 +7420,7 @@ var RefCountSubscriber = (function (_super) {
     return RefCountSubscriber;
 }(Subscriber_1.Subscriber));
 
-},{"../Observable":29,"../Subject":34,"../Subscriber":36,"../Subscription":37,"../operators/refCount":179}],92:[function(require,module,exports){
+},{"../Observable":29,"../Subject":34,"../Subscriber":36,"../Subscription":37,"../operators/refCount":189}],95:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -7502,7 +7520,7 @@ var DeferSubscriber = (function (_super) {
     return DeferSubscriber;
 }(OuterSubscriber_1.OuterSubscriber));
 
-},{"../Observable":29,"../OuterSubscriber":31,"../util/subscribeToResult":228}],93:[function(require,module,exports){
+},{"../Observable":29,"../OuterSubscriber":31,"../util/subscribeToResult":237}],96:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -7584,7 +7602,7 @@ var EmptyObservable = (function (_super) {
 }(Observable_1.Observable));
 exports.EmptyObservable = EmptyObservable;
 
-},{"../Observable":29}],94:[function(require,module,exports){
+},{"../Observable":29}],97:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -7668,7 +7686,7 @@ var ErrorObservable = (function (_super) {
 }(Observable_1.Observable));
 exports.ErrorObservable = ErrorObservable;
 
-},{"../Observable":29}],95:[function(require,module,exports){
+},{"../Observable":29}],98:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -7885,7 +7903,7 @@ var FromEventObservable = (function (_super) {
 }(Observable_1.Observable));
 exports.FromEventObservable = FromEventObservable;
 
-},{"../Observable":29,"../Subscription":37,"../util/errorObject":215,"../util/isFunction":220,"../util/tryCatch":230}],96:[function(require,module,exports){
+},{"../Observable":29,"../Subscription":37,"../util/errorObject":224,"../util/isFunction":229,"../util/tryCatch":239}],99:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -8008,7 +8026,7 @@ var FromObservable = (function (_super) {
 }(Observable_1.Observable));
 exports.FromObservable = FromObservable;
 
-},{"../Observable":29,"../operators/observeOn":174,"../symbol/iterator":205,"../symbol/observable":206,"../util/isArray":217,"../util/isArrayLike":218,"../util/isPromise":223,"./ArrayLikeObservable":89,"./ArrayObservable":90,"./IteratorObservable":97,"./PromiseObservable":98}],97:[function(require,module,exports){
+},{"../Observable":29,"../operators/observeOn":183,"../symbol/iterator":214,"../symbol/observable":215,"../util/isArray":226,"../util/isArrayLike":227,"../util/isPromise":232,"./ArrayLikeObservable":92,"./ArrayObservable":93,"./IteratorObservable":100,"./PromiseObservable":101}],100:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -8172,7 +8190,7 @@ function sign(value) {
     return valueAsNumber < 0 ? -1 : 1;
 }
 
-},{"../Observable":29,"../symbol/iterator":205,"../util/root":227}],98:[function(require,module,exports){
+},{"../Observable":29,"../symbol/iterator":214,"../util/root":236}],101:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -8294,7 +8312,7 @@ function dispatchError(arg) {
     }
 }
 
-},{"../Observable":29,"../util/root":227}],99:[function(require,module,exports){
+},{"../Observable":29,"../util/root":236}],102:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -8353,7 +8371,7 @@ var ScalarObservable = (function (_super) {
 }(Observable_1.Observable));
 exports.ScalarObservable = ScalarObservable;
 
-},{"../Observable":29}],100:[function(require,module,exports){
+},{"../Observable":29}],103:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -8461,7 +8479,7 @@ var TimerObservable = (function (_super) {
 }(Observable_1.Observable));
 exports.TimerObservable = TimerObservable;
 
-},{"../Observable":29,"../scheduler/async":203,"../util/isDate":219,"../util/isNumeric":221,"../util/isScheduler":224}],101:[function(require,module,exports){
+},{"../Observable":29,"../scheduler/async":212,"../util/isDate":228,"../util/isNumeric":230,"../util/isScheduler":233}],104:[function(require,module,exports){
 "use strict";
 var isScheduler_1 = require('../util/isScheduler');
 var isArray_1 = require('../util/isArray');
@@ -8598,7 +8616,7 @@ function combineLatest() {
 }
 exports.combineLatest = combineLatest;
 
-},{"../operators/combineLatest":157,"../util/isArray":217,"../util/isScheduler":224,"./ArrayObservable":90}],102:[function(require,module,exports){
+},{"../operators/combineLatest":164,"../util/isArray":226,"../util/isScheduler":233,"./ArrayObservable":93}],105:[function(require,module,exports){
 "use strict";
 var isScheduler_1 = require('../util/isScheduler');
 var of_1 = require('./of');
@@ -8710,57 +8728,109 @@ function concat() {
 }
 exports.concat = concat;
 
-},{"../operators/concatAll":159,"../util/isScheduler":224,"./from":105,"./of":109}],103:[function(require,module,exports){
+},{"../operators/concatAll":166,"../util/isScheduler":233,"./from":108,"./of":112}],106:[function(require,module,exports){
 "use strict";
 var DeferObservable_1 = require('./DeferObservable');
 exports.defer = DeferObservable_1.DeferObservable.create;
 
-},{"./DeferObservable":92}],104:[function(require,module,exports){
+},{"./DeferObservable":95}],107:[function(require,module,exports){
 "use strict";
 var EmptyObservable_1 = require('./EmptyObservable');
 exports.empty = EmptyObservable_1.EmptyObservable.create;
 
-},{"./EmptyObservable":93}],105:[function(require,module,exports){
+},{"./EmptyObservable":96}],108:[function(require,module,exports){
 "use strict";
 var FromObservable_1 = require('./FromObservable');
 exports.from = FromObservable_1.FromObservable.create;
 
-},{"./FromObservable":96}],106:[function(require,module,exports){
+},{"./FromObservable":99}],109:[function(require,module,exports){
 "use strict";
 var FromEventObservable_1 = require('./FromEventObservable');
 exports.fromEvent = FromEventObservable_1.FromEventObservable.create;
 
-},{"./FromEventObservable":95}],107:[function(require,module,exports){
+},{"./FromEventObservable":98}],110:[function(require,module,exports){
 "use strict";
 var PromiseObservable_1 = require('./PromiseObservable');
 exports.fromPromise = PromiseObservable_1.PromiseObservable.create;
 
-},{"./PromiseObservable":98}],108:[function(require,module,exports){
+},{"./PromiseObservable":101}],111:[function(require,module,exports){
 "use strict";
 var merge_1 = require('../operator/merge');
 exports.merge = merge_1.mergeStatic;
 
-},{"../operator/merge":130}],109:[function(require,module,exports){
+},{"../operator/merge":135}],112:[function(require,module,exports){
 "use strict";
 var ArrayObservable_1 = require('./ArrayObservable');
 exports.of = ArrayObservable_1.ArrayObservable.of;
 
-},{"./ArrayObservable":90}],110:[function(require,module,exports){
+},{"./ArrayObservable":93}],113:[function(require,module,exports){
 "use strict";
 var ErrorObservable_1 = require('./ErrorObservable');
 exports._throw = ErrorObservable_1.ErrorObservable.create;
 
-},{"./ErrorObservable":94}],111:[function(require,module,exports){
+},{"./ErrorObservable":97}],114:[function(require,module,exports){
 "use strict";
 var TimerObservable_1 = require('./TimerObservable');
 exports.timer = TimerObservable_1.TimerObservable.create;
 
-},{"./TimerObservable":100}],112:[function(require,module,exports){
+},{"./TimerObservable":103}],115:[function(require,module,exports){
 "use strict";
 var zip_1 = require('../operators/zip');
 exports.zip = zip_1.zipStatic;
 
-},{"../operators/zip":197}],113:[function(require,module,exports){
+},{"../operators/zip":206}],116:[function(require,module,exports){
+"use strict";
+var async_1 = require('../scheduler/async');
+var auditTime_1 = require('../operators/auditTime');
+/**
+ * Ignores source values for `duration` milliseconds, then emits the most recent
+ * value from the source Observable, then repeats this process.
+ *
+ * <span class="informal">When it sees a source values, it ignores that plus
+ * the next ones for `duration` milliseconds, and then it emits the most recent
+ * value from the source.</span>
+ *
+ * <img src="./img/auditTime.png" width="100%">
+ *
+ * `auditTime` is similar to `throttleTime`, but emits the last value from the
+ * silenced time window, instead of the first value. `auditTime` emits the most
+ * recent value from the source Observable on the output Observable as soon as
+ * its internal timer becomes disabled, and ignores source values while the
+ * timer is enabled. Initially, the timer is disabled. As soon as the first
+ * source value arrives, the timer is enabled. After `duration` milliseconds (or
+ * the time unit determined internally by the optional `scheduler`) has passed,
+ * the timer is disabled, then the most recent source value is emitted on the
+ * output Observable, and this process repeats for the next source value.
+ * Optionally takes a {@link IScheduler} for managing timers.
+ *
+ * @example <caption>Emit clicks at a rate of at most one click per second</caption>
+ * var clicks = Rx.Observable.fromEvent(document, 'click');
+ * var result = clicks.auditTime(1000);
+ * result.subscribe(x => console.log(x));
+ *
+ * @see {@link audit}
+ * @see {@link debounceTime}
+ * @see {@link delay}
+ * @see {@link sampleTime}
+ * @see {@link throttleTime}
+ *
+ * @param {number} duration Time to wait before emitting the most recent source
+ * value, measured in milliseconds or the time unit determined internally
+ * by the optional `scheduler`.
+ * @param {Scheduler} [scheduler=async] The {@link IScheduler} to use for
+ * managing the timers that handle the rate-limiting behavior.
+ * @return {Observable<T>} An Observable that performs rate-limiting of
+ * emissions from the source Observable.
+ * @method auditTime
+ * @owner Observable
+ */
+function auditTime(duration, scheduler) {
+    if (scheduler === void 0) { scheduler = async_1.async; }
+    return auditTime_1.auditTime(duration, scheduler)(this);
+}
+exports.auditTime = auditTime;
+
+},{"../operators/auditTime":159,"../scheduler/async":212}],117:[function(require,module,exports){
 "use strict";
 var buffer_1 = require('../operators/buffer');
 /**
@@ -8800,7 +8870,7 @@ function buffer(closingNotifier) {
 }
 exports.buffer = buffer;
 
-},{"../operators/buffer":153}],114:[function(require,module,exports){
+},{"../operators/buffer":160}],118:[function(require,module,exports){
 "use strict";
 var bufferCount_1 = require('../operators/bufferCount');
 /**
@@ -8850,7 +8920,7 @@ function bufferCount(bufferSize, startBufferEvery) {
 }
 exports.bufferCount = bufferCount;
 
-},{"../operators/bufferCount":154}],115:[function(require,module,exports){
+},{"../operators/bufferCount":161}],119:[function(require,module,exports){
 "use strict";
 var bufferWhen_1 = require('../operators/bufferWhen');
 /**
@@ -8891,7 +8961,7 @@ function bufferWhen(closingSelector) {
 }
 exports.bufferWhen = bufferWhen;
 
-},{"../operators/bufferWhen":155}],116:[function(require,module,exports){
+},{"../operators/bufferWhen":162}],120:[function(require,module,exports){
 "use strict";
 var catchError_1 = require('../operators/catchError');
 /**
@@ -8958,7 +9028,7 @@ function _catch(selector) {
 }
 exports._catch = _catch;
 
-},{"../operators/catchError":156}],117:[function(require,module,exports){
+},{"../operators/catchError":163}],121:[function(require,module,exports){
 "use strict";
 var combineLatest_1 = require('../operators/combineLatest');
 /* tslint:enable:max-line-length */
@@ -9014,7 +9084,7 @@ function combineLatest() {
 }
 exports.combineLatest = combineLatest;
 
-},{"../operators/combineLatest":157}],118:[function(require,module,exports){
+},{"../operators/combineLatest":164}],122:[function(require,module,exports){
 "use strict";
 var concat_1 = require('../operators/concat');
 /* tslint:enable:max-line-length */
@@ -9076,7 +9146,63 @@ function concat() {
 }
 exports.concat = concat;
 
-},{"../operators/concat":158}],119:[function(require,module,exports){
+},{"../operators/concat":165}],123:[function(require,module,exports){
+"use strict";
+var count_1 = require('../operators/count');
+/**
+ * Counts the number of emissions on the source and emits that number when the
+ * source completes.
+ *
+ * <span class="informal">Tells how many values were emitted, when the source
+ * completes.</span>
+ *
+ * <img src="./img/count.png" width="100%">
+ *
+ * `count` transforms an Observable that emits values into an Observable that
+ * emits a single value that represents the number of values emitted by the
+ * source Observable. If the source Observable terminates with an error, `count`
+ * will pass this error notification along without emitting a value first. If
+ * the source Observable does not terminate at all, `count` will neither emit
+ * a value nor terminate. This operator takes an optional `predicate` function
+ * as argument, in which case the output emission will represent the number of
+ * source values that matched `true` with the `predicate`.
+ *
+ * @example <caption>Counts how many seconds have passed before the first click happened</caption>
+ * var seconds = Rx.Observable.interval(1000);
+ * var clicks = Rx.Observable.fromEvent(document, 'click');
+ * var secondsBeforeClick = seconds.takeUntil(clicks);
+ * var result = secondsBeforeClick.count();
+ * result.subscribe(x => console.log(x));
+ *
+ * @example <caption>Counts how many odd numbers are there between 1 and 7</caption>
+ * var numbers = Rx.Observable.range(1, 7);
+ * var result = numbers.count(i => i % 2 === 1);
+ * result.subscribe(x => console.log(x));
+ *
+ * // Results in:
+ * // 4
+ *
+ * @see {@link max}
+ * @see {@link min}
+ * @see {@link reduce}
+ *
+ * @param {function(value: T, i: number, source: Observable<T>): boolean} [predicate] A
+ * boolean function to select what values are to be counted. It is provided with
+ * arguments of:
+ * - `value`: the value from the source Observable.
+ * - `index`: the (zero-based) "index" of the value from the source Observable.
+ * - `source`: the source Observable instance itself.
+ * @return {Observable} An Observable of one number that represents the count as
+ * described above.
+ * @method count
+ * @owner Observable
+ */
+function count(predicate) {
+    return count_1.count(predicate)(this);
+}
+exports.count = count;
+
+},{"../operators/count":167}],124:[function(require,module,exports){
 "use strict";
 var async_1 = require('../scheduler/async');
 var debounceTime_1 = require('../operators/debounceTime');
@@ -9132,7 +9258,7 @@ function debounceTime(dueTime, scheduler) {
 }
 exports.debounceTime = debounceTime;
 
-},{"../operators/debounceTime":160,"../scheduler/async":203}],120:[function(require,module,exports){
+},{"../operators/debounceTime":168,"../scheduler/async":212}],125:[function(require,module,exports){
 "use strict";
 var async_1 = require('../scheduler/async');
 var delay_1 = require('../operators/delay');
@@ -9181,7 +9307,7 @@ function delay(delay, scheduler) {
 }
 exports.delay = delay;
 
-},{"../operators/delay":161,"../scheduler/async":203}],121:[function(require,module,exports){
+},{"../operators/delay":170,"../scheduler/async":212}],126:[function(require,module,exports){
 "use strict";
 var distinct_1 = require('../operators/distinct');
 /**
@@ -9234,7 +9360,7 @@ function distinct(keySelector, flushes) {
 }
 exports.distinct = distinct;
 
-},{"../operators/distinct":162}],122:[function(require,module,exports){
+},{"../operators/distinct":171}],127:[function(require,module,exports){
 "use strict";
 var distinctUntilChanged_1 = require('../operators/distinctUntilChanged');
 /* tslint:enable:max-line-length */
@@ -9282,7 +9408,7 @@ function distinctUntilChanged(compare, keySelector) {
 }
 exports.distinctUntilChanged = distinctUntilChanged;
 
-},{"../operators/distinctUntilChanged":163}],123:[function(require,module,exports){
+},{"../operators/distinctUntilChanged":172}],128:[function(require,module,exports){
 "use strict";
 var tap_1 = require('../operators/tap');
 /* tslint:enable:max-line-length */
@@ -9334,7 +9460,7 @@ function _do(nextOrObserver, error, complete) {
 }
 exports._do = _do;
 
-},{"../operators/tap":192}],124:[function(require,module,exports){
+},{"../operators/tap":203}],129:[function(require,module,exports){
 "use strict";
 var expand_1 = require('../operators/expand');
 /* tslint:enable:max-line-length */
@@ -9391,7 +9517,7 @@ function expand(project, concurrent, scheduler) {
 }
 exports.expand = expand;
 
-},{"../operators/expand":164}],125:[function(require,module,exports){
+},{"../operators/expand":173}],130:[function(require,module,exports){
 "use strict";
 var filter_1 = require('../operators/filter');
 /* tslint:enable:max-line-length */
@@ -9439,7 +9565,7 @@ function filter(predicate, thisArg) {
 }
 exports.filter = filter;
 
-},{"../operators/filter":165}],126:[function(require,module,exports){
+},{"../operators/filter":174}],131:[function(require,module,exports){
 "use strict";
 var finalize_1 = require('../operators/finalize');
 /**
@@ -9455,7 +9581,7 @@ function _finally(callback) {
 }
 exports._finally = _finally;
 
-},{"../operators/finalize":166}],127:[function(require,module,exports){
+},{"../operators/finalize":175}],132:[function(require,module,exports){
 "use strict";
 var first_1 = require('../operators/first');
 /**
@@ -9512,7 +9638,7 @@ function first(predicate, resultSelector, defaultValue) {
 }
 exports.first = first;
 
-},{"../operators/first":167}],128:[function(require,module,exports){
+},{"../operators/first":176}],133:[function(require,module,exports){
 "use strict";
 var last_1 = require('../operators/last');
 /* tslint:enable:max-line-length */
@@ -9538,7 +9664,7 @@ function last(predicate, resultSelector, defaultValue) {
 }
 exports.last = last;
 
-},{"../operators/last":168}],129:[function(require,module,exports){
+},{"../operators/last":177}],134:[function(require,module,exports){
 "use strict";
 var map_1 = require('../operators/map');
 /**
@@ -9579,7 +9705,7 @@ function map(project, thisArg) {
 }
 exports.map = map;
 
-},{"../operators/map":169}],130:[function(require,module,exports){
+},{"../operators/map":178}],135:[function(require,module,exports){
 "use strict";
 var merge_1 = require('../operators/merge');
 var merge_2 = require('../operators/merge');
@@ -9640,7 +9766,7 @@ function merge() {
 }
 exports.merge = merge;
 
-},{"../operators/merge":170}],131:[function(require,module,exports){
+},{"../operators/merge":179}],136:[function(require,module,exports){
 "use strict";
 var mergeAll_1 = require('../operators/mergeAll');
 /**
@@ -9693,7 +9819,7 @@ function mergeAll(concurrent) {
 }
 exports.mergeAll = mergeAll;
 
-},{"../operators/mergeAll":171}],132:[function(require,module,exports){
+},{"../operators/mergeAll":180}],137:[function(require,module,exports){
 "use strict";
 var mergeMap_1 = require('../operators/mergeMap');
 /* tslint:enable:max-line-length */
@@ -9761,7 +9887,7 @@ function mergeMap(project, resultSelector, concurrent) {
 }
 exports.mergeMap = mergeMap;
 
-},{"../operators/mergeMap":172}],133:[function(require,module,exports){
+},{"../operators/mergeMap":181}],138:[function(require,module,exports){
 "use strict";
 var pairwise_1 = require('../operators/pairwise');
 /**
@@ -9804,7 +9930,7 @@ function pairwise() {
 }
 exports.pairwise = pairwise;
 
-},{"../operators/pairwise":175}],134:[function(require,module,exports){
+},{"../operators/pairwise":184}],139:[function(require,module,exports){
 "use strict";
 var pluck_1 = require('../operators/pluck');
 /**
@@ -9842,7 +9968,7 @@ function pluck() {
 }
 exports.pluck = pluck;
 
-},{"../operators/pluck":176}],135:[function(require,module,exports){
+},{"../operators/pluck":185}],140:[function(require,module,exports){
 "use strict";
 var publish_1 = require('../operators/publish');
 /* tslint:enable:max-line-length */
@@ -9864,7 +9990,7 @@ function publish(selector) {
 }
 exports.publish = publish;
 
-},{"../operators/publish":177}],136:[function(require,module,exports){
+},{"../operators/publish":186}],141:[function(require,module,exports){
 "use strict";
 var publishReplay_1 = require('../operators/publishReplay');
 /* tslint:enable:max-line-length */
@@ -9882,7 +10008,68 @@ function publishReplay(bufferSize, windowTime, selectorOrScheduler, scheduler) {
 }
 exports.publishReplay = publishReplay;
 
-},{"../operators/publishReplay":178}],137:[function(require,module,exports){
+},{"../operators/publishReplay":187}],142:[function(require,module,exports){
+"use strict";
+var reduce_1 = require('../operators/reduce');
+/* tslint:enable:max-line-length */
+/**
+ * Applies an accumulator function over the source Observable, and returns the
+ * accumulated result when the source completes, given an optional seed value.
+ *
+ * <span class="informal">Combines together all values emitted on the source,
+ * using an accumulator function that knows how to join a new source value into
+ * the accumulation from the past.</span>
+ *
+ * <img src="./img/reduce.png" width="100%">
+ *
+ * Like
+ * [Array.prototype.reduce()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce),
+ * `reduce` applies an `accumulator` function against an accumulation and each
+ * value of the source Observable (from the past) to reduce it to a single
+ * value, emitted on the output Observable. Note that `reduce` will only emit
+ * one value, only when the source Observable completes. It is equivalent to
+ * applying operator {@link scan} followed by operator {@link last}.
+ *
+ * Returns an Observable that applies a specified `accumulator` function to each
+ * item emitted by the source Observable. If a `seed` value is specified, then
+ * that value will be used as the initial value for the accumulator. If no seed
+ * value is specified, the first item of the source is used as the seed.
+ *
+ * @example <caption>Count the number of click events that happened in 5 seconds</caption>
+ * var clicksInFiveSeconds = Rx.Observable.fromEvent(document, 'click')
+ *   .takeUntil(Rx.Observable.interval(5000));
+ * var ones = clicksInFiveSeconds.mapTo(1);
+ * var seed = 0;
+ * var count = ones.reduce((acc, one) => acc + one, seed);
+ * count.subscribe(x => console.log(x));
+ *
+ * @see {@link count}
+ * @see {@link expand}
+ * @see {@link mergeScan}
+ * @see {@link scan}
+ *
+ * @param {function(acc: R, value: T, index: number): R} accumulator The accumulator function
+ * called on each source value.
+ * @param {R} [seed] The initial accumulation value.
+ * @return {Observable<R>} An Observable that emits a single value that is the
+ * result of accumulating the values emitted by the source Observable.
+ * @method reduce
+ * @owner Observable
+ */
+function reduce(accumulator, seed) {
+    // providing a seed of `undefined` *should* be valid and trigger
+    // hasSeed! so don't use `seed !== undefined` checks!
+    // For this reason, we have to check it here at the original call site
+    // otherwise inside Operator/Subscriber we won't know if `undefined`
+    // means they didn't provide anything or if they literally provided `undefined`
+    if (arguments.length >= 2) {
+        return reduce_1.reduce(accumulator, seed)(this);
+    }
+    return reduce_1.reduce(accumulator)(this);
+}
+exports.reduce = reduce;
+
+},{"../operators/reduce":188}],143:[function(require,module,exports){
 "use strict";
 var retry_1 = require('../operators/retry');
 /**
@@ -9907,7 +10094,7 @@ function retry(count) {
 }
 exports.retry = retry;
 
-},{"../operators/retry":180}],138:[function(require,module,exports){
+},{"../operators/retry":190}],144:[function(require,module,exports){
 "use strict";
 var sample_1 = require('../operators/sample');
 /**
@@ -9949,7 +10136,7 @@ function sample(notifier) {
 }
 exports.sample = sample;
 
-},{"../operators/sample":181}],139:[function(require,module,exports){
+},{"../operators/sample":191}],145:[function(require,module,exports){
 "use strict";
 var scan_1 = require('../operators/scan');
 /* tslint:enable:max-line-length */
@@ -9998,7 +10185,7 @@ function scan(accumulator, seed) {
 }
 exports.scan = scan;
 
-},{"../operators/scan":182}],140:[function(require,module,exports){
+},{"../operators/scan":192}],146:[function(require,module,exports){
 "use strict";
 var share_1 = require('../operators/share');
 /**
@@ -10023,7 +10210,7 @@ function share() {
 exports.share = share;
 ;
 
-},{"../operators/share":183}],141:[function(require,module,exports){
+},{"../operators/share":193}],147:[function(require,module,exports){
 "use strict";
 var skip_1 = require('../operators/skip');
 /**
@@ -10042,7 +10229,7 @@ function skip(count) {
 }
 exports.skip = skip;
 
-},{"../operators/skip":184}],142:[function(require,module,exports){
+},{"../operators/skip":194}],148:[function(require,module,exports){
 "use strict";
 var skipUntil_1 = require('../operators/skipUntil');
 /**
@@ -10062,7 +10249,7 @@ function skipUntil(notifier) {
 }
 exports.skipUntil = skipUntil;
 
-},{"../operators/skipUntil":185}],143:[function(require,module,exports){
+},{"../operators/skipUntil":195}],149:[function(require,module,exports){
 "use strict";
 var skipWhile_1 = require('../operators/skipWhile');
 /**
@@ -10082,7 +10269,7 @@ function skipWhile(predicate) {
 }
 exports.skipWhile = skipWhile;
 
-},{"../operators/skipWhile":186}],144:[function(require,module,exports){
+},{"../operators/skipWhile":196}],150:[function(require,module,exports){
 "use strict";
 var startWith_1 = require('../operators/startWith');
 /* tslint:enable:max-line-length */
@@ -10109,7 +10296,7 @@ function startWith() {
 }
 exports.startWith = startWith;
 
-},{"../operators/startWith":187}],145:[function(require,module,exports){
+},{"../operators/startWith":197}],151:[function(require,module,exports){
 "use strict";
 var switchMap_1 = require('../operators/switchMap');
 /* tslint:enable:max-line-length */
@@ -10165,7 +10352,7 @@ function switchMap(project, resultSelector) {
 }
 exports.switchMap = switchMap;
 
-},{"../operators/switchMap":188}],146:[function(require,module,exports){
+},{"../operators/switchMap":198}],152:[function(require,module,exports){
 "use strict";
 var take_1 = require('../operators/take');
 /**
@@ -10206,7 +10393,7 @@ function take(count) {
 }
 exports.take = take;
 
-},{"../operators/take":189}],147:[function(require,module,exports){
+},{"../operators/take":199}],153:[function(require,module,exports){
 "use strict";
 var takeUntil_1 = require('../operators/takeUntil');
 /**
@@ -10247,7 +10434,7 @@ function takeUntil(notifier) {
 }
 exports.takeUntil = takeUntil;
 
-},{"../operators/takeUntil":190}],148:[function(require,module,exports){
+},{"../operators/takeUntil":201}],154:[function(require,module,exports){
 "use strict";
 var takeWhile_1 = require('../operators/takeWhile');
 /**
@@ -10291,58 +10478,7 @@ function takeWhile(predicate) {
 }
 exports.takeWhile = takeWhile;
 
-},{"../operators/takeWhile":191}],149:[function(require,module,exports){
-"use strict";
-var async_1 = require('../scheduler/async');
-var throttle_1 = require('../operators/throttle');
-var throttleTime_1 = require('../operators/throttleTime');
-/**
- * Emits a value from the source Observable, then ignores subsequent source
- * values for `duration` milliseconds, then repeats this process.
- *
- * <span class="informal">Lets a value pass, then ignores source values for the
- * next `duration` milliseconds.</span>
- *
- * <img src="./img/throttleTime.png" width="100%">
- *
- * `throttleTime` emits the source Observable values on the output Observable
- * when its internal timer is disabled, and ignores source values when the timer
- * is enabled. Initially, the timer is disabled. As soon as the first source
- * value arrives, it is forwarded to the output Observable, and then the timer
- * is enabled. After `duration` milliseconds (or the time unit determined
- * internally by the optional `scheduler`) has passed, the timer is disabled,
- * and this process repeats for the next source value. Optionally takes a
- * {@link IScheduler} for managing timers.
- *
- * @example <caption>Emit clicks at a rate of at most one click per second</caption>
- * var clicks = Rx.Observable.fromEvent(document, 'click');
- * var result = clicks.throttleTime(1000);
- * result.subscribe(x => console.log(x));
- *
- * @see {@link auditTime}
- * @see {@link debounceTime}
- * @see {@link delay}
- * @see {@link sampleTime}
- * @see {@link throttle}
- *
- * @param {number} duration Time to wait before emitting another value after
- * emitting the last value, measured in milliseconds or the time unit determined
- * internally by the optional `scheduler`.
- * @param {Scheduler} [scheduler=async] The {@link IScheduler} to use for
- * managing the timers that handle the throttling.
- * @return {Observable<T>} An Observable that performs the throttle operation to
- * limit the rate of emissions from the source.
- * @method throttleTime
- * @owner Observable
- */
-function throttleTime(duration, scheduler, config) {
-    if (scheduler === void 0) { scheduler = async_1.async; }
-    if (config === void 0) { config = throttle_1.defaultThrottleConfig; }
-    return throttleTime_1.throttleTime(duration, scheduler, config)(this);
-}
-exports.throttleTime = throttleTime;
-
-},{"../operators/throttle":193,"../operators/throttleTime":194,"../scheduler/async":203}],150:[function(require,module,exports){
+},{"../operators/takeWhile":202}],155:[function(require,module,exports){
 "use strict";
 var async_1 = require('../scheduler/async');
 var timeout_1 = require('../operators/timeout');
@@ -10417,7 +10553,7 @@ function timeout(due, scheduler) {
 }
 exports.timeout = timeout;
 
-},{"../operators/timeout":195,"../scheduler/async":203}],151:[function(require,module,exports){
+},{"../operators/timeout":204,"../scheduler/async":212}],156:[function(require,module,exports){
 "use strict";
 var withLatestFrom_1 = require('../operators/withLatestFrom');
 /* tslint:enable:max-line-length */
@@ -10468,7 +10604,7 @@ function withLatestFrom() {
 }
 exports.withLatestFrom = withLatestFrom;
 
-},{"../operators/withLatestFrom":196}],152:[function(require,module,exports){
+},{"../operators/withLatestFrom":205}],157:[function(require,module,exports){
 "use strict";
 var zip_1 = require('../operators/zip');
 /* tslint:enable:max-line-length */
@@ -10487,7 +10623,179 @@ function zipProto() {
 }
 exports.zipProto = zipProto;
 
-},{"../operators/zip":197}],153:[function(require,module,exports){
+},{"../operators/zip":206}],158:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var tryCatch_1 = require('../util/tryCatch');
+var errorObject_1 = require('../util/errorObject');
+var OuterSubscriber_1 = require('../OuterSubscriber');
+var subscribeToResult_1 = require('../util/subscribeToResult');
+/**
+ * Ignores source values for a duration determined by another Observable, then
+ * emits the most recent value from the source Observable, then repeats this
+ * process.
+ *
+ * <span class="informal">It's like {@link auditTime}, but the silencing
+ * duration is determined by a second Observable.</span>
+ *
+ * <img src="./img/audit.png" width="100%">
+ *
+ * `audit` is similar to `throttle`, but emits the last value from the silenced
+ * time window, instead of the first value. `audit` emits the most recent value
+ * from the source Observable on the output Observable as soon as its internal
+ * timer becomes disabled, and ignores source values while the timer is enabled.
+ * Initially, the timer is disabled. As soon as the first source value arrives,
+ * the timer is enabled by calling the `durationSelector` function with the
+ * source value, which returns the "duration" Observable. When the duration
+ * Observable emits a value or completes, the timer is disabled, then the most
+ * recent source value is emitted on the output Observable, and this process
+ * repeats for the next source value.
+ *
+ * @example <caption>Emit clicks at a rate of at most one click per second</caption>
+ * var clicks = Rx.Observable.fromEvent(document, 'click');
+ * var result = clicks.audit(ev => Rx.Observable.interval(1000));
+ * result.subscribe(x => console.log(x));
+ *
+ * @see {@link auditTime}
+ * @see {@link debounce}
+ * @see {@link delayWhen}
+ * @see {@link sample}
+ * @see {@link throttle}
+ *
+ * @param {function(value: T): SubscribableOrPromise} durationSelector A function
+ * that receives a value from the source Observable, for computing the silencing
+ * duration, returned as an Observable or a Promise.
+ * @return {Observable<T>} An Observable that performs rate-limiting of
+ * emissions from the source Observable.
+ * @method audit
+ * @owner Observable
+ */
+function audit(durationSelector) {
+    return function auditOperatorFunction(source) {
+        return source.lift(new AuditOperator(durationSelector));
+    };
+}
+exports.audit = audit;
+var AuditOperator = (function () {
+    function AuditOperator(durationSelector) {
+        this.durationSelector = durationSelector;
+    }
+    AuditOperator.prototype.call = function (subscriber, source) {
+        return source.subscribe(new AuditSubscriber(subscriber, this.durationSelector));
+    };
+    return AuditOperator;
+}());
+/**
+ * We need this JSDoc comment for affecting ESDoc.
+ * @ignore
+ * @extends {Ignored}
+ */
+var AuditSubscriber = (function (_super) {
+    __extends(AuditSubscriber, _super);
+    function AuditSubscriber(destination, durationSelector) {
+        _super.call(this, destination);
+        this.durationSelector = durationSelector;
+        this.hasValue = false;
+    }
+    AuditSubscriber.prototype._next = function (value) {
+        this.value = value;
+        this.hasValue = true;
+        if (!this.throttled) {
+            var duration = tryCatch_1.tryCatch(this.durationSelector)(value);
+            if (duration === errorObject_1.errorObject) {
+                this.destination.error(errorObject_1.errorObject.e);
+            }
+            else {
+                var innerSubscription = subscribeToResult_1.subscribeToResult(this, duration);
+                if (innerSubscription.closed) {
+                    this.clearThrottle();
+                }
+                else {
+                    this.add(this.throttled = innerSubscription);
+                }
+            }
+        }
+    };
+    AuditSubscriber.prototype.clearThrottle = function () {
+        var _a = this, value = _a.value, hasValue = _a.hasValue, throttled = _a.throttled;
+        if (throttled) {
+            this.remove(throttled);
+            this.throttled = null;
+            throttled.unsubscribe();
+        }
+        if (hasValue) {
+            this.value = null;
+            this.hasValue = false;
+            this.destination.next(value);
+        }
+    };
+    AuditSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex) {
+        this.clearThrottle();
+    };
+    AuditSubscriber.prototype.notifyComplete = function () {
+        this.clearThrottle();
+    };
+    return AuditSubscriber;
+}(OuterSubscriber_1.OuterSubscriber));
+
+},{"../OuterSubscriber":31,"../util/errorObject":224,"../util/subscribeToResult":237,"../util/tryCatch":239}],159:[function(require,module,exports){
+"use strict";
+var async_1 = require('../scheduler/async');
+var audit_1 = require('./audit');
+var timer_1 = require('../observable/timer');
+/**
+ * Ignores source values for `duration` milliseconds, then emits the most recent
+ * value from the source Observable, then repeats this process.
+ *
+ * <span class="informal">When it sees a source values, it ignores that plus
+ * the next ones for `duration` milliseconds, and then it emits the most recent
+ * value from the source.</span>
+ *
+ * <img src="./img/auditTime.png" width="100%">
+ *
+ * `auditTime` is similar to `throttleTime`, but emits the last value from the
+ * silenced time window, instead of the first value. `auditTime` emits the most
+ * recent value from the source Observable on the output Observable as soon as
+ * its internal timer becomes disabled, and ignores source values while the
+ * timer is enabled. Initially, the timer is disabled. As soon as the first
+ * source value arrives, the timer is enabled. After `duration` milliseconds (or
+ * the time unit determined internally by the optional `scheduler`) has passed,
+ * the timer is disabled, then the most recent source value is emitted on the
+ * output Observable, and this process repeats for the next source value.
+ * Optionally takes a {@link IScheduler} for managing timers.
+ *
+ * @example <caption>Emit clicks at a rate of at most one click per second</caption>
+ * var clicks = Rx.Observable.fromEvent(document, 'click');
+ * var result = clicks.auditTime(1000);
+ * result.subscribe(x => console.log(x));
+ *
+ * @see {@link audit}
+ * @see {@link debounceTime}
+ * @see {@link delay}
+ * @see {@link sampleTime}
+ * @see {@link throttleTime}
+ *
+ * @param {number} duration Time to wait before emitting the most recent source
+ * value, measured in milliseconds or the time unit determined internally
+ * by the optional `scheduler`.
+ * @param {Scheduler} [scheduler=async] The {@link IScheduler} to use for
+ * managing the timers that handle the rate-limiting behavior.
+ * @return {Observable<T>} An Observable that performs rate-limiting of
+ * emissions from the source Observable.
+ * @method auditTime
+ * @owner Observable
+ */
+function auditTime(duration, scheduler) {
+    if (scheduler === void 0) { scheduler = async_1.async; }
+    return audit_1.audit(function () { return timer_1.timer(duration, scheduler); });
+}
+exports.auditTime = auditTime;
+
+},{"../observable/timer":114,"../scheduler/async":212,"./audit":158}],160:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -10566,7 +10874,7 @@ var BufferSubscriber = (function (_super) {
     return BufferSubscriber;
 }(OuterSubscriber_1.OuterSubscriber));
 
-},{"../OuterSubscriber":31,"../util/subscribeToResult":228}],154:[function(require,module,exports){
+},{"../OuterSubscriber":31,"../util/subscribeToResult":237}],161:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -10709,7 +11017,7 @@ var BufferSkipCountSubscriber = (function (_super) {
     return BufferSkipCountSubscriber;
 }(Subscriber_1.Subscriber));
 
-},{"../Subscriber":36}],155:[function(require,module,exports){
+},{"../Subscriber":36}],162:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -10834,7 +11142,7 @@ var BufferWhenSubscriber = (function (_super) {
     return BufferWhenSubscriber;
 }(OuterSubscriber_1.OuterSubscriber));
 
-},{"../OuterSubscriber":31,"../Subscription":37,"../util/errorObject":215,"../util/subscribeToResult":228,"../util/tryCatch":230}],156:[function(require,module,exports){
+},{"../OuterSubscriber":31,"../Subscription":37,"../util/errorObject":224,"../util/subscribeToResult":237,"../util/tryCatch":239}],163:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -10951,7 +11259,7 @@ var CatchSubscriber = (function (_super) {
     return CatchSubscriber;
 }(OuterSubscriber_1.OuterSubscriber));
 
-},{"../OuterSubscriber":31,"../util/subscribeToResult":228}],157:[function(require,module,exports){
+},{"../OuterSubscriber":31,"../util/subscribeToResult":237}],164:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -11103,7 +11411,7 @@ var CombineLatestSubscriber = (function (_super) {
 }(OuterSubscriber_1.OuterSubscriber));
 exports.CombineLatestSubscriber = CombineLatestSubscriber;
 
-},{"../OuterSubscriber":31,"../observable/ArrayObservable":90,"../util/isArray":217,"../util/subscribeToResult":228}],158:[function(require,module,exports){
+},{"../OuterSubscriber":31,"../observable/ArrayObservable":93,"../util/isArray":226,"../util/subscribeToResult":237}],165:[function(require,module,exports){
 "use strict";
 var concat_1 = require('../observable/concat');
 /* tslint:enable:max-line-length */
@@ -11165,7 +11473,7 @@ function concat() {
 }
 exports.concat = concat;
 
-},{"../observable/concat":102}],159:[function(require,module,exports){
+},{"../observable/concat":105}],166:[function(require,module,exports){
 "use strict";
 var mergeAll_1 = require('./mergeAll');
 /**
@@ -11221,7 +11529,119 @@ function concatAll() {
 }
 exports.concatAll = concatAll;
 
-},{"./mergeAll":171}],160:[function(require,module,exports){
+},{"./mergeAll":180}],167:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var Subscriber_1 = require('../Subscriber');
+/**
+ * Counts the number of emissions on the source and emits that number when the
+ * source completes.
+ *
+ * <span class="informal">Tells how many values were emitted, when the source
+ * completes.</span>
+ *
+ * <img src="./img/count.png" width="100%">
+ *
+ * `count` transforms an Observable that emits values into an Observable that
+ * emits a single value that represents the number of values emitted by the
+ * source Observable. If the source Observable terminates with an error, `count`
+ * will pass this error notification along without emitting a value first. If
+ * the source Observable does not terminate at all, `count` will neither emit
+ * a value nor terminate. This operator takes an optional `predicate` function
+ * as argument, in which case the output emission will represent the number of
+ * source values that matched `true` with the `predicate`.
+ *
+ * @example <caption>Counts how many seconds have passed before the first click happened</caption>
+ * var seconds = Rx.Observable.interval(1000);
+ * var clicks = Rx.Observable.fromEvent(document, 'click');
+ * var secondsBeforeClick = seconds.takeUntil(clicks);
+ * var result = secondsBeforeClick.count();
+ * result.subscribe(x => console.log(x));
+ *
+ * @example <caption>Counts how many odd numbers are there between 1 and 7</caption>
+ * var numbers = Rx.Observable.range(1, 7);
+ * var result = numbers.count(i => i % 2 === 1);
+ * result.subscribe(x => console.log(x));
+ *
+ * // Results in:
+ * // 4
+ *
+ * @see {@link max}
+ * @see {@link min}
+ * @see {@link reduce}
+ *
+ * @param {function(value: T, i: number, source: Observable<T>): boolean} [predicate] A
+ * boolean function to select what values are to be counted. It is provided with
+ * arguments of:
+ * - `value`: the value from the source Observable.
+ * - `index`: the (zero-based) "index" of the value from the source Observable.
+ * - `source`: the source Observable instance itself.
+ * @return {Observable} An Observable of one number that represents the count as
+ * described above.
+ * @method count
+ * @owner Observable
+ */
+function count(predicate) {
+    return function (source) { return source.lift(new CountOperator(predicate, source)); };
+}
+exports.count = count;
+var CountOperator = (function () {
+    function CountOperator(predicate, source) {
+        this.predicate = predicate;
+        this.source = source;
+    }
+    CountOperator.prototype.call = function (subscriber, source) {
+        return source.subscribe(new CountSubscriber(subscriber, this.predicate, this.source));
+    };
+    return CountOperator;
+}());
+/**
+ * We need this JSDoc comment for affecting ESDoc.
+ * @ignore
+ * @extends {Ignored}
+ */
+var CountSubscriber = (function (_super) {
+    __extends(CountSubscriber, _super);
+    function CountSubscriber(destination, predicate, source) {
+        _super.call(this, destination);
+        this.predicate = predicate;
+        this.source = source;
+        this.count = 0;
+        this.index = 0;
+    }
+    CountSubscriber.prototype._next = function (value) {
+        if (this.predicate) {
+            this._tryPredicate(value);
+        }
+        else {
+            this.count++;
+        }
+    };
+    CountSubscriber.prototype._tryPredicate = function (value) {
+        var result;
+        try {
+            result = this.predicate(value, this.index++, this.source);
+        }
+        catch (err) {
+            this.destination.error(err);
+            return;
+        }
+        if (result) {
+            this.count++;
+        }
+    };
+    CountSubscriber.prototype._complete = function () {
+        this.destination.next(this.count);
+        this.destination.complete();
+    };
+    return CountSubscriber;
+}(Subscriber_1.Subscriber));
+
+},{"../Subscriber":36}],168:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -11338,7 +11758,85 @@ function dispatchNext(subscriber) {
     subscriber.debouncedNext();
 }
 
-},{"../Subscriber":36,"../scheduler/async":203}],161:[function(require,module,exports){
+},{"../Subscriber":36,"../scheduler/async":212}],169:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var Subscriber_1 = require('../Subscriber');
+/* tslint:enable:max-line-length */
+/**
+ * Emits a given value if the source Observable completes without emitting any
+ * `next` value, otherwise mirrors the source Observable.
+ *
+ * <span class="informal">If the source Observable turns out to be empty, then
+ * this operator will emit a default value.</span>
+ *
+ * <img src="./img/defaultIfEmpty.png" width="100%">
+ *
+ * `defaultIfEmpty` emits the values emitted by the source Observable or a
+ * specified default value if the source Observable is empty (completes without
+ * having emitted any `next` value).
+ *
+ * @example <caption>If no clicks happen in 5 seconds, then emit "no clicks"</caption>
+ * var clicks = Rx.Observable.fromEvent(document, 'click');
+ * var clicksBeforeFive = clicks.takeUntil(Rx.Observable.interval(5000));
+ * var result = clicksBeforeFive.defaultIfEmpty('no clicks');
+ * result.subscribe(x => console.log(x));
+ *
+ * @see {@link empty}
+ * @see {@link last}
+ *
+ * @param {any} [defaultValue=null] The default value used if the source
+ * Observable is empty.
+ * @return {Observable} An Observable that emits either the specified
+ * `defaultValue` if the source Observable emits no items, or the values emitted
+ * by the source Observable.
+ * @method defaultIfEmpty
+ * @owner Observable
+ */
+function defaultIfEmpty(defaultValue) {
+    if (defaultValue === void 0) { defaultValue = null; }
+    return function (source) { return source.lift(new DefaultIfEmptyOperator(defaultValue)); };
+}
+exports.defaultIfEmpty = defaultIfEmpty;
+var DefaultIfEmptyOperator = (function () {
+    function DefaultIfEmptyOperator(defaultValue) {
+        this.defaultValue = defaultValue;
+    }
+    DefaultIfEmptyOperator.prototype.call = function (subscriber, source) {
+        return source.subscribe(new DefaultIfEmptySubscriber(subscriber, this.defaultValue));
+    };
+    return DefaultIfEmptyOperator;
+}());
+/**
+ * We need this JSDoc comment for affecting ESDoc.
+ * @ignore
+ * @extends {Ignored}
+ */
+var DefaultIfEmptySubscriber = (function (_super) {
+    __extends(DefaultIfEmptySubscriber, _super);
+    function DefaultIfEmptySubscriber(destination, defaultValue) {
+        _super.call(this, destination);
+        this.defaultValue = defaultValue;
+        this.isEmpty = true;
+    }
+    DefaultIfEmptySubscriber.prototype._next = function (value) {
+        this.isEmpty = false;
+        this.destination.next(value);
+    };
+    DefaultIfEmptySubscriber.prototype._complete = function () {
+        if (this.isEmpty) {
+            this.destination.next(this.defaultValue);
+        }
+        this.destination.complete();
+    };
+    return DefaultIfEmptySubscriber;
+}(Subscriber_1.Subscriber));
+
+},{"../Subscriber":36}],170:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -11474,7 +11972,7 @@ var DelayMessage = (function () {
     return DelayMessage;
 }());
 
-},{"../Notification":28,"../Subscriber":36,"../scheduler/async":203,"../util/isDate":219}],162:[function(require,module,exports){
+},{"../Notification":28,"../Subscriber":36,"../scheduler/async":212,"../util/isDate":228}],171:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -11595,7 +12093,7 @@ var DistinctSubscriber = (function (_super) {
 }(OuterSubscriber_1.OuterSubscriber));
 exports.DistinctSubscriber = DistinctSubscriber;
 
-},{"../OuterSubscriber":31,"../util/Set":212,"../util/subscribeToResult":228}],163:[function(require,module,exports){
+},{"../OuterSubscriber":31,"../util/Set":221,"../util/subscribeToResult":237}],172:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -11704,7 +12202,7 @@ var DistinctUntilChangedSubscriber = (function (_super) {
     return DistinctUntilChangedSubscriber;
 }(Subscriber_1.Subscriber));
 
-},{"../Subscriber":36,"../util/errorObject":215,"../util/tryCatch":230}],164:[function(require,module,exports){
+},{"../Subscriber":36,"../util/errorObject":224,"../util/tryCatch":239}],173:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -11856,7 +12354,7 @@ var ExpandSubscriber = (function (_super) {
 }(OuterSubscriber_1.OuterSubscriber));
 exports.ExpandSubscriber = ExpandSubscriber;
 
-},{"../OuterSubscriber":31,"../util/errorObject":215,"../util/subscribeToResult":228,"../util/tryCatch":230}],165:[function(require,module,exports){
+},{"../OuterSubscriber":31,"../util/errorObject":224,"../util/subscribeToResult":237,"../util/tryCatch":239}],174:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -11951,7 +12449,7 @@ var FilterSubscriber = (function (_super) {
     return FilterSubscriber;
 }(Subscriber_1.Subscriber));
 
-},{"../Subscriber":36}],166:[function(require,module,exports){
+},{"../Subscriber":36}],175:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -11995,7 +12493,7 @@ var FinallySubscriber = (function (_super) {
     return FinallySubscriber;
 }(Subscriber_1.Subscriber));
 
-},{"../Subscriber":36,"../Subscription":37}],167:[function(require,module,exports){
+},{"../Subscriber":36,"../Subscription":37}],176:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -12148,7 +12646,7 @@ var FirstSubscriber = (function (_super) {
     return FirstSubscriber;
 }(Subscriber_1.Subscriber));
 
-},{"../Subscriber":36,"../util/EmptyError":210}],168:[function(require,module,exports){
+},{"../Subscriber":36,"../util/EmptyError":219}],177:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -12268,7 +12766,7 @@ var LastSubscriber = (function (_super) {
     return LastSubscriber;
 }(Subscriber_1.Subscriber));
 
-},{"../Subscriber":36,"../util/EmptyError":210}],169:[function(require,module,exports){
+},{"../Subscriber":36,"../util/EmptyError":219}],178:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -12358,7 +12856,7 @@ var MapSubscriber = (function (_super) {
     return MapSubscriber;
 }(Subscriber_1.Subscriber));
 
-},{"../Subscriber":36}],170:[function(require,module,exports){
+},{"../Subscriber":36}],179:[function(require,module,exports){
 "use strict";
 var Observable_1 = require('../Observable');
 var ArrayObservable_1 = require('../observable/ArrayObservable');
@@ -12458,7 +12956,7 @@ function mergeStatic() {
 }
 exports.mergeStatic = mergeStatic;
 
-},{"../Observable":29,"../observable/ArrayObservable":90,"../util/isScheduler":224,"./mergeAll":171}],171:[function(require,module,exports){
+},{"../Observable":29,"../observable/ArrayObservable":93,"../util/isScheduler":233,"./mergeAll":180}],180:[function(require,module,exports){
 "use strict";
 var mergeMap_1 = require('./mergeMap');
 var identity_1 = require('../util/identity');
@@ -12512,7 +13010,7 @@ function mergeAll(concurrent) {
 }
 exports.mergeAll = mergeAll;
 
-},{"../util/identity":216,"./mergeMap":172}],172:[function(require,module,exports){
+},{"../util/identity":225,"./mergeMap":181}],181:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -12686,7 +13184,7 @@ var MergeMapSubscriber = (function (_super) {
 }(OuterSubscriber_1.OuterSubscriber));
 exports.MergeMapSubscriber = MergeMapSubscriber;
 
-},{"../OuterSubscriber":31,"../util/subscribeToResult":228}],173:[function(require,module,exports){
+},{"../OuterSubscriber":31,"../util/subscribeToResult":237}],182:[function(require,module,exports){
 "use strict";
 var ConnectableObservable_1 = require('../observable/ConnectableObservable');
 /* tslint:enable:max-line-length */
@@ -12746,7 +13244,7 @@ var MulticastOperator = (function () {
 }());
 exports.MulticastOperator = MulticastOperator;
 
-},{"../observable/ConnectableObservable":91}],174:[function(require,module,exports){
+},{"../observable/ConnectableObservable":94}],183:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -12862,7 +13360,7 @@ var ObserveOnMessage = (function () {
 }());
 exports.ObserveOnMessage = ObserveOnMessage;
 
-},{"../Notification":28,"../Subscriber":36}],175:[function(require,module,exports){
+},{"../Notification":28,"../Subscriber":36}],184:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -12940,7 +13438,7 @@ var PairwiseSubscriber = (function (_super) {
     return PairwiseSubscriber;
 }(Subscriber_1.Subscriber));
 
-},{"../Subscriber":36}],176:[function(require,module,exports){
+},{"../Subscriber":36}],185:[function(require,module,exports){
 "use strict";
 var map_1 = require('./map');
 /**
@@ -12998,7 +13496,7 @@ function plucker(props, length) {
     return mapper;
 }
 
-},{"./map":169}],177:[function(require,module,exports){
+},{"./map":178}],186:[function(require,module,exports){
 "use strict";
 var Subject_1 = require('../Subject');
 var multicast_1 = require('./multicast');
@@ -13023,7 +13521,7 @@ function publish(selector) {
 }
 exports.publish = publish;
 
-},{"../Subject":34,"./multicast":173}],178:[function(require,module,exports){
+},{"../Subject":34,"./multicast":182}],187:[function(require,module,exports){
 "use strict";
 var ReplaySubject_1 = require('../ReplaySubject');
 var multicast_1 = require('./multicast');
@@ -13038,7 +13536,77 @@ function publishReplay(bufferSize, windowTime, selectorOrScheduler, scheduler) {
 }
 exports.publishReplay = publishReplay;
 
-},{"../ReplaySubject":32,"./multicast":173}],179:[function(require,module,exports){
+},{"../ReplaySubject":32,"./multicast":182}],188:[function(require,module,exports){
+"use strict";
+var scan_1 = require('./scan');
+var takeLast_1 = require('./takeLast');
+var defaultIfEmpty_1 = require('./defaultIfEmpty');
+var pipe_1 = require('../util/pipe');
+/* tslint:enable:max-line-length */
+/**
+ * Applies an accumulator function over the source Observable, and returns the
+ * accumulated result when the source completes, given an optional seed value.
+ *
+ * <span class="informal">Combines together all values emitted on the source,
+ * using an accumulator function that knows how to join a new source value into
+ * the accumulation from the past.</span>
+ *
+ * <img src="./img/reduce.png" width="100%">
+ *
+ * Like
+ * [Array.prototype.reduce()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce),
+ * `reduce` applies an `accumulator` function against an accumulation and each
+ * value of the source Observable (from the past) to reduce it to a single
+ * value, emitted on the output Observable. Note that `reduce` will only emit
+ * one value, only when the source Observable completes. It is equivalent to
+ * applying operator {@link scan} followed by operator {@link last}.
+ *
+ * Returns an Observable that applies a specified `accumulator` function to each
+ * item emitted by the source Observable. If a `seed` value is specified, then
+ * that value will be used as the initial value for the accumulator. If no seed
+ * value is specified, the first item of the source is used as the seed.
+ *
+ * @example <caption>Count the number of click events that happened in 5 seconds</caption>
+ * var clicksInFiveSeconds = Rx.Observable.fromEvent(document, 'click')
+ *   .takeUntil(Rx.Observable.interval(5000));
+ * var ones = clicksInFiveSeconds.mapTo(1);
+ * var seed = 0;
+ * var count = ones.reduce((acc, one) => acc + one, seed);
+ * count.subscribe(x => console.log(x));
+ *
+ * @see {@link count}
+ * @see {@link expand}
+ * @see {@link mergeScan}
+ * @see {@link scan}
+ *
+ * @param {function(acc: R, value: T, index: number): R} accumulator The accumulator function
+ * called on each source value.
+ * @param {R} [seed] The initial accumulation value.
+ * @return {Observable<R>} An Observable that emits a single value that is the
+ * result of accumulating the values emitted by the source Observable.
+ * @method reduce
+ * @owner Observable
+ */
+function reduce(accumulator, seed) {
+    // providing a seed of `undefined` *should* be valid and trigger
+    // hasSeed! so don't use `seed !== undefined` checks!
+    // For this reason, we have to check it here at the original call site
+    // otherwise inside Operator/Subscriber we won't know if `undefined`
+    // means they didn't provide anything or if they literally provided `undefined`
+    if (arguments.length >= 2) {
+        return function reduceOperatorFunctionWithSeed(source) {
+            return pipe_1.pipe(scan_1.scan(accumulator, seed), takeLast_1.takeLast(1), defaultIfEmpty_1.defaultIfEmpty(seed))(source);
+        };
+    }
+    return function reduceOperatorFunction(source) {
+        return pipe_1.pipe(scan_1.scan(function (acc, value, index) {
+            return accumulator(acc, value, index + 1);
+        }), takeLast_1.takeLast(1))(source);
+    };
+}
+exports.reduce = reduce;
+
+},{"../util/pipe":235,"./defaultIfEmpty":169,"./scan":192,"./takeLast":200}],189:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -13124,7 +13692,7 @@ var RefCountSubscriber = (function (_super) {
     return RefCountSubscriber;
 }(Subscriber_1.Subscriber));
 
-},{"../Subscriber":36}],180:[function(require,module,exports){
+},{"../Subscriber":36}],190:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -13190,7 +13758,7 @@ var RetrySubscriber = (function (_super) {
     return RetrySubscriber;
 }(Subscriber_1.Subscriber));
 
-},{"../Subscriber":36}],181:[function(require,module,exports){
+},{"../Subscriber":36}],191:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -13279,7 +13847,7 @@ var SampleSubscriber = (function (_super) {
     return SampleSubscriber;
 }(OuterSubscriber_1.OuterSubscriber));
 
-},{"../OuterSubscriber":31,"../util/subscribeToResult":228}],182:[function(require,module,exports){
+},{"../OuterSubscriber":31,"../util/subscribeToResult":237}],192:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -13401,7 +13969,7 @@ var ScanSubscriber = (function (_super) {
     return ScanSubscriber;
 }(Subscriber_1.Subscriber));
 
-},{"../Subscriber":36}],183:[function(require,module,exports){
+},{"../Subscriber":36}],193:[function(require,module,exports){
 "use strict";
 var multicast_1 = require('./multicast');
 var refCount_1 = require('./refCount');
@@ -13427,7 +13995,7 @@ function share() {
 exports.share = share;
 ;
 
-},{"../Subject":34,"./multicast":173,"./refCount":179}],184:[function(require,module,exports){
+},{"../Subject":34,"./multicast":182,"./refCount":189}],194:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -13479,7 +14047,7 @@ var SkipSubscriber = (function (_super) {
     return SkipSubscriber;
 }(Subscriber_1.Subscriber));
 
-},{"../Subscriber":36}],185:[function(require,module,exports){
+},{"../Subscriber":36}],195:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -13551,7 +14119,7 @@ var SkipUntilSubscriber = (function (_super) {
     return SkipUntilSubscriber;
 }(OuterSubscriber_1.OuterSubscriber));
 
-},{"../OuterSubscriber":31,"../util/subscribeToResult":228}],186:[function(require,module,exports){
+},{"../OuterSubscriber":31,"../util/subscribeToResult":237}],196:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -13618,7 +14186,7 @@ var SkipWhileSubscriber = (function (_super) {
     return SkipWhileSubscriber;
 }(Subscriber_1.Subscriber));
 
-},{"../Subscriber":36}],187:[function(require,module,exports){
+},{"../Subscriber":36}],197:[function(require,module,exports){
 "use strict";
 var ArrayObservable_1 = require('../observable/ArrayObservable');
 var ScalarObservable_1 = require('../observable/ScalarObservable');
@@ -13667,7 +14235,7 @@ function startWith() {
 }
 exports.startWith = startWith;
 
-},{"../observable/ArrayObservable":90,"../observable/EmptyObservable":93,"../observable/ScalarObservable":99,"../observable/concat":102,"../util/isScheduler":224}],188:[function(require,module,exports){
+},{"../observable/ArrayObservable":93,"../observable/EmptyObservable":96,"../observable/ScalarObservable":102,"../observable/concat":105,"../util/isScheduler":233}],198:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -13810,7 +14378,7 @@ var SwitchMapSubscriber = (function (_super) {
     return SwitchMapSubscriber;
 }(OuterSubscriber_1.OuterSubscriber));
 
-},{"../OuterSubscriber":31,"../util/subscribeToResult":228}],189:[function(require,module,exports){
+},{"../OuterSubscriber":31,"../util/subscribeToResult":237}],199:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -13902,7 +14470,117 @@ var TakeSubscriber = (function (_super) {
     return TakeSubscriber;
 }(Subscriber_1.Subscriber));
 
-},{"../Subscriber":36,"../observable/EmptyObservable":93,"../util/ArgumentOutOfRangeError":209}],190:[function(require,module,exports){
+},{"../Subscriber":36,"../observable/EmptyObservable":96,"../util/ArgumentOutOfRangeError":218}],200:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var Subscriber_1 = require('../Subscriber');
+var ArgumentOutOfRangeError_1 = require('../util/ArgumentOutOfRangeError');
+var EmptyObservable_1 = require('../observable/EmptyObservable');
+/**
+ * Emits only the last `count` values emitted by the source Observable.
+ *
+ * <span class="informal">Remembers the latest `count` values, then emits those
+ * only when the source completes.</span>
+ *
+ * <img src="./img/takeLast.png" width="100%">
+ *
+ * `takeLast` returns an Observable that emits at most the last `count` values
+ * emitted by the source Observable. If the source emits fewer than `count`
+ * values then all of its values are emitted. This operator must wait until the
+ * `complete` notification emission from the source in order to emit the `next`
+ * values on the output Observable, because otherwise it is impossible to know
+ * whether or not more values will be emitted on the source. For this reason,
+ * all values are emitted synchronously, followed by the complete notification.
+ *
+ * @example <caption>Take the last 3 values of an Observable with many values</caption>
+ * var many = Rx.Observable.range(1, 100);
+ * var lastThree = many.takeLast(3);
+ * lastThree.subscribe(x => console.log(x));
+ *
+ * @see {@link take}
+ * @see {@link takeUntil}
+ * @see {@link takeWhile}
+ * @see {@link skip}
+ *
+ * @throws {ArgumentOutOfRangeError} When using `takeLast(i)`, it delivers an
+ * ArgumentOutOrRangeError to the Observer's `error` callback if `i < 0`.
+ *
+ * @param {number} count The maximum number of values to emit from the end of
+ * the sequence of values emitted by the source Observable.
+ * @return {Observable<T>} An Observable that emits at most the last count
+ * values emitted by the source Observable.
+ * @method takeLast
+ * @owner Observable
+ */
+function takeLast(count) {
+    return function takeLastOperatorFunction(source) {
+        if (count === 0) {
+            return new EmptyObservable_1.EmptyObservable();
+        }
+        else {
+            return source.lift(new TakeLastOperator(count));
+        }
+    };
+}
+exports.takeLast = takeLast;
+var TakeLastOperator = (function () {
+    function TakeLastOperator(total) {
+        this.total = total;
+        if (this.total < 0) {
+            throw new ArgumentOutOfRangeError_1.ArgumentOutOfRangeError;
+        }
+    }
+    TakeLastOperator.prototype.call = function (subscriber, source) {
+        return source.subscribe(new TakeLastSubscriber(subscriber, this.total));
+    };
+    return TakeLastOperator;
+}());
+/**
+ * We need this JSDoc comment for affecting ESDoc.
+ * @ignore
+ * @extends {Ignored}
+ */
+var TakeLastSubscriber = (function (_super) {
+    __extends(TakeLastSubscriber, _super);
+    function TakeLastSubscriber(destination, total) {
+        _super.call(this, destination);
+        this.total = total;
+        this.ring = new Array();
+        this.count = 0;
+    }
+    TakeLastSubscriber.prototype._next = function (value) {
+        var ring = this.ring;
+        var total = this.total;
+        var count = this.count++;
+        if (ring.length < total) {
+            ring.push(value);
+        }
+        else {
+            var index = count % total;
+            ring[index] = value;
+        }
+    };
+    TakeLastSubscriber.prototype._complete = function () {
+        var destination = this.destination;
+        var count = this.count;
+        if (count > 0) {
+            var total = this.count >= this.total ? this.total : this.count;
+            var ring = this.ring;
+            for (var i = 0; i < total; i++) {
+                var idx = (count++) % total;
+                destination.next(ring[idx]);
+            }
+        }
+        destination.complete();
+    };
+    return TakeLastSubscriber;
+}(Subscriber_1.Subscriber));
+
+},{"../Subscriber":36,"../observable/EmptyObservable":96,"../util/ArgumentOutOfRangeError":218}],201:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -13978,7 +14656,7 @@ var TakeUntilSubscriber = (function (_super) {
     return TakeUntilSubscriber;
 }(OuterSubscriber_1.OuterSubscriber));
 
-},{"../OuterSubscriber":31,"../util/subscribeToResult":228}],191:[function(require,module,exports){
+},{"../OuterSubscriber":31,"../util/subscribeToResult":237}],202:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -14071,7 +14749,7 @@ var TakeWhileSubscriber = (function (_super) {
     return TakeWhileSubscriber;
 }(Subscriber_1.Subscriber));
 
-},{"../Subscriber":36}],192:[function(require,module,exports){
+},{"../Subscriber":36}],203:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -14185,267 +14863,7 @@ var DoSubscriber = (function (_super) {
     return DoSubscriber;
 }(Subscriber_1.Subscriber));
 
-},{"../Subscriber":36}],193:[function(require,module,exports){
-"use strict";
-var __extends = (this && this.__extends) || function (d, b) {
-    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
-    function __() { this.constructor = d; }
-    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-};
-var OuterSubscriber_1 = require('../OuterSubscriber');
-var subscribeToResult_1 = require('../util/subscribeToResult');
-exports.defaultThrottleConfig = {
-    leading: true,
-    trailing: false
-};
-/**
- * Emits a value from the source Observable, then ignores subsequent source
- * values for a duration determined by another Observable, then repeats this
- * process.
- *
- * <span class="informal">It's like {@link throttleTime}, but the silencing
- * duration is determined by a second Observable.</span>
- *
- * <img src="./img/throttle.png" width="100%">
- *
- * `throttle` emits the source Observable values on the output Observable
- * when its internal timer is disabled, and ignores source values when the timer
- * is enabled. Initially, the timer is disabled. As soon as the first source
- * value arrives, it is forwarded to the output Observable, and then the timer
- * is enabled by calling the `durationSelector` function with the source value,
- * which returns the "duration" Observable. When the duration Observable emits a
- * value or completes, the timer is disabled, and this process repeats for the
- * next source value.
- *
- * @example <caption>Emit clicks at a rate of at most one click per second</caption>
- * var clicks = Rx.Observable.fromEvent(document, 'click');
- * var result = clicks.throttle(ev => Rx.Observable.interval(1000));
- * result.subscribe(x => console.log(x));
- *
- * @see {@link audit}
- * @see {@link debounce}
- * @see {@link delayWhen}
- * @see {@link sample}
- * @see {@link throttleTime}
- *
- * @param {function(value: T): SubscribableOrPromise} durationSelector A function
- * that receives a value from the source Observable, for computing the silencing
- * duration for each source value, returned as an Observable or a Promise.
- * @param {Object} config a configuration object to define `leading` and `trailing` behavior. Defaults
- * to `{ leading: true, trailing: false }`.
- * @return {Observable<T>} An Observable that performs the throttle operation to
- * limit the rate of emissions from the source.
- * @method throttle
- * @owner Observable
- */
-function throttle(durationSelector, config) {
-    if (config === void 0) { config = exports.defaultThrottleConfig; }
-    return function (source) { return source.lift(new ThrottleOperator(durationSelector, config.leading, config.trailing)); };
-}
-exports.throttle = throttle;
-var ThrottleOperator = (function () {
-    function ThrottleOperator(durationSelector, leading, trailing) {
-        this.durationSelector = durationSelector;
-        this.leading = leading;
-        this.trailing = trailing;
-    }
-    ThrottleOperator.prototype.call = function (subscriber, source) {
-        return source.subscribe(new ThrottleSubscriber(subscriber, this.durationSelector, this.leading, this.trailing));
-    };
-    return ThrottleOperator;
-}());
-/**
- * We need this JSDoc comment for affecting ESDoc
- * @ignore
- * @extends {Ignored}
- */
-var ThrottleSubscriber = (function (_super) {
-    __extends(ThrottleSubscriber, _super);
-    function ThrottleSubscriber(destination, durationSelector, _leading, _trailing) {
-        _super.call(this, destination);
-        this.destination = destination;
-        this.durationSelector = durationSelector;
-        this._leading = _leading;
-        this._trailing = _trailing;
-        this._hasTrailingValue = false;
-    }
-    ThrottleSubscriber.prototype._next = function (value) {
-        if (this.throttled) {
-            if (this._trailing) {
-                this._hasTrailingValue = true;
-                this._trailingValue = value;
-            }
-        }
-        else {
-            var duration = this.tryDurationSelector(value);
-            if (duration) {
-                this.add(this.throttled = subscribeToResult_1.subscribeToResult(this, duration));
-            }
-            if (this._leading) {
-                this.destination.next(value);
-                if (this._trailing) {
-                    this._hasTrailingValue = true;
-                    this._trailingValue = value;
-                }
-            }
-        }
-    };
-    ThrottleSubscriber.prototype.tryDurationSelector = function (value) {
-        try {
-            return this.durationSelector(value);
-        }
-        catch (err) {
-            this.destination.error(err);
-            return null;
-        }
-    };
-    ThrottleSubscriber.prototype._unsubscribe = function () {
-        var _a = this, throttled = _a.throttled, _trailingValue = _a._trailingValue, _hasTrailingValue = _a._hasTrailingValue, _trailing = _a._trailing;
-        this._trailingValue = null;
-        this._hasTrailingValue = false;
-        if (throttled) {
-            this.remove(throttled);
-            this.throttled = null;
-            throttled.unsubscribe();
-        }
-    };
-    ThrottleSubscriber.prototype._sendTrailing = function () {
-        var _a = this, destination = _a.destination, throttled = _a.throttled, _trailing = _a._trailing, _trailingValue = _a._trailingValue, _hasTrailingValue = _a._hasTrailingValue;
-        if (throttled && _trailing && _hasTrailingValue) {
-            destination.next(_trailingValue);
-            this._trailingValue = null;
-            this._hasTrailingValue = false;
-        }
-    };
-    ThrottleSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) {
-        this._sendTrailing();
-        this._unsubscribe();
-    };
-    ThrottleSubscriber.prototype.notifyComplete = function () {
-        this._sendTrailing();
-        this._unsubscribe();
-    };
-    return ThrottleSubscriber;
-}(OuterSubscriber_1.OuterSubscriber));
-
-},{"../OuterSubscriber":31,"../util/subscribeToResult":228}],194:[function(require,module,exports){
-"use strict";
-var __extends = (this && this.__extends) || function (d, b) {
-    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
-    function __() { this.constructor = d; }
-    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-};
-var Subscriber_1 = require('../Subscriber');
-var async_1 = require('../scheduler/async');
-var throttle_1 = require('./throttle');
-/**
- * Emits a value from the source Observable, then ignores subsequent source
- * values for `duration` milliseconds, then repeats this process.
- *
- * <span class="informal">Lets a value pass, then ignores source values for the
- * next `duration` milliseconds.</span>
- *
- * <img src="./img/throttleTime.png" width="100%">
- *
- * `throttleTime` emits the source Observable values on the output Observable
- * when its internal timer is disabled, and ignores source values when the timer
- * is enabled. Initially, the timer is disabled. As soon as the first source
- * value arrives, it is forwarded to the output Observable, and then the timer
- * is enabled. After `duration` milliseconds (or the time unit determined
- * internally by the optional `scheduler`) has passed, the timer is disabled,
- * and this process repeats for the next source value. Optionally takes a
- * {@link IScheduler} for managing timers.
- *
- * @example <caption>Emit clicks at a rate of at most one click per second</caption>
- * var clicks = Rx.Observable.fromEvent(document, 'click');
- * var result = clicks.throttleTime(1000);
- * result.subscribe(x => console.log(x));
- *
- * @see {@link auditTime}
- * @see {@link debounceTime}
- * @see {@link delay}
- * @see {@link sampleTime}
- * @see {@link throttle}
- *
- * @param {number} duration Time to wait before emitting another value after
- * emitting the last value, measured in milliseconds or the time unit determined
- * internally by the optional `scheduler`.
- * @param {Scheduler} [scheduler=async] The {@link IScheduler} to use for
- * managing the timers that handle the throttling.
- * @return {Observable<T>} An Observable that performs the throttle operation to
- * limit the rate of emissions from the source.
- * @method throttleTime
- * @owner Observable
- */
-function throttleTime(duration, scheduler, config) {
-    if (scheduler === void 0) { scheduler = async_1.async; }
-    if (config === void 0) { config = throttle_1.defaultThrottleConfig; }
-    return function (source) { return source.lift(new ThrottleTimeOperator(duration, scheduler, config.leading, config.trailing)); };
-}
-exports.throttleTime = throttleTime;
-var ThrottleTimeOperator = (function () {
-    function ThrottleTimeOperator(duration, scheduler, leading, trailing) {
-        this.duration = duration;
-        this.scheduler = scheduler;
-        this.leading = leading;
-        this.trailing = trailing;
-    }
-    ThrottleTimeOperator.prototype.call = function (subscriber, source) {
-        return source.subscribe(new ThrottleTimeSubscriber(subscriber, this.duration, this.scheduler, this.leading, this.trailing));
-    };
-    return ThrottleTimeOperator;
-}());
-/**
- * We need this JSDoc comment for affecting ESDoc.
- * @ignore
- * @extends {Ignored}
- */
-var ThrottleTimeSubscriber = (function (_super) {
-    __extends(ThrottleTimeSubscriber, _super);
-    function ThrottleTimeSubscriber(destination, duration, scheduler, leading, trailing) {
-        _super.call(this, destination);
-        this.duration = duration;
-        this.scheduler = scheduler;
-        this.leading = leading;
-        this.trailing = trailing;
-        this._hasTrailingValue = false;
-        this._trailingValue = null;
-    }
-    ThrottleTimeSubscriber.prototype._next = function (value) {
-        if (this.throttled) {
-            if (this.trailing) {
-                this._trailingValue = value;
-                this._hasTrailingValue = true;
-            }
-        }
-        else {
-            this.add(this.throttled = this.scheduler.schedule(dispatchNext, this.duration, { subscriber: this }));
-            if (this.leading) {
-                this.destination.next(value);
-            }
-        }
-    };
-    ThrottleTimeSubscriber.prototype.clearThrottle = function () {
-        var throttled = this.throttled;
-        if (throttled) {
-            if (this.trailing && this._hasTrailingValue) {
-                this.destination.next(this._trailingValue);
-                this._trailingValue = null;
-                this._hasTrailingValue = false;
-            }
-            throttled.unsubscribe();
-            this.remove(throttled);
-            this.throttled = null;
-        }
-    };
-    return ThrottleTimeSubscriber;
-}(Subscriber_1.Subscriber));
-function dispatchNext(arg) {
-    var subscriber = arg.subscriber;
-    subscriber.clearThrottle();
-}
-
-},{"../Subscriber":36,"../scheduler/async":203,"./throttle":193}],195:[function(require,module,exports){
+},{"../Subscriber":36}],204:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -14587,7 +15005,7 @@ var TimeoutSubscriber = (function (_super) {
     return TimeoutSubscriber;
 }(Subscriber_1.Subscriber));
 
-},{"../Subscriber":36,"../scheduler/async":203,"../util/TimeoutError":213,"../util/isDate":219}],196:[function(require,module,exports){
+},{"../Subscriber":36,"../scheduler/async":212,"../util/TimeoutError":222,"../util/isDate":228}],205:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -14720,7 +15138,7 @@ var WithLatestFromSubscriber = (function (_super) {
     return WithLatestFromSubscriber;
 }(OuterSubscriber_1.OuterSubscriber));
 
-},{"../OuterSubscriber":31,"../util/subscribeToResult":228}],197:[function(require,module,exports){
+},{"../OuterSubscriber":31,"../util/subscribeToResult":237}],206:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -15002,7 +15420,7 @@ var ZipBufferIterator = (function (_super) {
     return ZipBufferIterator;
 }(OuterSubscriber_1.OuterSubscriber));
 
-},{"../OuterSubscriber":31,"../Subscriber":36,"../observable/ArrayObservable":90,"../symbol/iterator":205,"../util/isArray":217,"../util/subscribeToResult":228}],198:[function(require,module,exports){
+},{"../OuterSubscriber":31,"../Subscriber":36,"../observable/ArrayObservable":93,"../symbol/iterator":214,"../util/isArray":226,"../util/subscribeToResult":237}],207:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -15047,7 +15465,7 @@ var Action = (function (_super) {
 }(Subscription_1.Subscription));
 exports.Action = Action;
 
-},{"../Subscription":37}],199:[function(require,module,exports){
+},{"../Subscription":37}],208:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -15190,7 +15608,7 @@ var AsyncAction = (function (_super) {
 }(Action_1.Action));
 exports.AsyncAction = AsyncAction;
 
-},{"../util/root":227,"./Action":198}],200:[function(require,module,exports){
+},{"../util/root":236,"./Action":207}],209:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -15242,7 +15660,7 @@ var AsyncScheduler = (function (_super) {
 }(Scheduler_1.Scheduler));
 exports.AsyncScheduler = AsyncScheduler;
 
-},{"../Scheduler":33}],201:[function(require,module,exports){
+},{"../Scheduler":33}],210:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -15292,7 +15710,7 @@ var QueueAction = (function (_super) {
 }(AsyncAction_1.AsyncAction));
 exports.QueueAction = QueueAction;
 
-},{"./AsyncAction":199}],202:[function(require,module,exports){
+},{"./AsyncAction":208}],211:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -15309,7 +15727,7 @@ var QueueScheduler = (function (_super) {
 }(AsyncScheduler_1.AsyncScheduler));
 exports.QueueScheduler = QueueScheduler;
 
-},{"./AsyncScheduler":200}],203:[function(require,module,exports){
+},{"./AsyncScheduler":209}],212:[function(require,module,exports){
 "use strict";
 var AsyncAction_1 = require('./AsyncAction');
 var AsyncScheduler_1 = require('./AsyncScheduler');
@@ -15357,7 +15775,7 @@ var AsyncScheduler_1 = require('./AsyncScheduler');
  */
 exports.async = new AsyncScheduler_1.AsyncScheduler(AsyncAction_1.AsyncAction);
 
-},{"./AsyncAction":199,"./AsyncScheduler":200}],204:[function(require,module,exports){
+},{"./AsyncAction":208,"./AsyncScheduler":209}],213:[function(require,module,exports){
 "use strict";
 var QueueAction_1 = require('./QueueAction');
 var QueueScheduler_1 = require('./QueueScheduler');
@@ -15424,7 +15842,7 @@ var QueueScheduler_1 = require('./QueueScheduler');
  */
 exports.queue = new QueueScheduler_1.QueueScheduler(QueueAction_1.QueueAction);
 
-},{"./QueueAction":201,"./QueueScheduler":202}],205:[function(require,module,exports){
+},{"./QueueAction":210,"./QueueScheduler":211}],214:[function(require,module,exports){
 "use strict";
 var root_1 = require('../util/root');
 function symbolIteratorPonyfill(root) {
@@ -15463,7 +15881,7 @@ exports.iterator = symbolIteratorPonyfill(root_1.root);
  */
 exports.$$iterator = exports.iterator;
 
-},{"../util/root":227}],206:[function(require,module,exports){
+},{"../util/root":236}],215:[function(require,module,exports){
 "use strict";
 var root_1 = require('../util/root');
 function getSymbolObservable(context) {
@@ -15490,7 +15908,7 @@ exports.observable = getSymbolObservable(root_1.root);
  */
 exports.$$observable = exports.observable;
 
-},{"../util/root":227}],207:[function(require,module,exports){
+},{"../util/root":236}],216:[function(require,module,exports){
 "use strict";
 var root_1 = require('../util/root');
 var Symbol = root_1.root.Symbol;
@@ -15501,7 +15919,7 @@ exports.rxSubscriber = (typeof Symbol === 'function' && typeof Symbol.for === 'f
  */
 exports.$$rxSubscriber = exports.rxSubscriber;
 
-},{"../util/root":227}],208:[function(require,module,exports){
+},{"../util/root":236}],217:[function(require,module,exports){
 "use strict";
 var root_1 = require('./root');
 var RequestAnimationFrameDefinition = (function () {
@@ -15536,7 +15954,7 @@ var RequestAnimationFrameDefinition = (function () {
 exports.RequestAnimationFrameDefinition = RequestAnimationFrameDefinition;
 exports.AnimationFrame = new RequestAnimationFrameDefinition(root_1.root);
 
-},{"./root":227}],209:[function(require,module,exports){
+},{"./root":236}],218:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -15565,7 +15983,7 @@ var ArgumentOutOfRangeError = (function (_super) {
 }(Error));
 exports.ArgumentOutOfRangeError = ArgumentOutOfRangeError;
 
-},{}],210:[function(require,module,exports){
+},{}],219:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -15594,7 +16012,7 @@ var EmptyError = (function (_super) {
 }(Error));
 exports.EmptyError = EmptyError;
 
-},{}],211:[function(require,module,exports){
+},{}],220:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -15622,7 +16040,7 @@ var ObjectUnsubscribedError = (function (_super) {
 }(Error));
 exports.ObjectUnsubscribedError = ObjectUnsubscribedError;
 
-},{}],212:[function(require,module,exports){
+},{}],221:[function(require,module,exports){
 "use strict";
 var root_1 = require('./root');
 function minimalSetImpl() {
@@ -15656,7 +16074,7 @@ function minimalSetImpl() {
 exports.minimalSetImpl = minimalSetImpl;
 exports.Set = root_1.root.Set || minimalSetImpl();
 
-},{"./root":227}],213:[function(require,module,exports){
+},{"./root":236}],222:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -15682,7 +16100,7 @@ var TimeoutError = (function (_super) {
 }(Error));
 exports.TimeoutError = TimeoutError;
 
-},{}],214:[function(require,module,exports){
+},{}],223:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || function (d, b) {
     for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
@@ -15708,41 +16126,41 @@ var UnsubscriptionError = (function (_super) {
 }(Error));
 exports.UnsubscriptionError = UnsubscriptionError;
 
-},{}],215:[function(require,module,exports){
+},{}],224:[function(require,module,exports){
 "use strict";
 // typeof any so that it we don't have to cast when comparing a result to the error object
 exports.errorObject = { e: {} };
 
-},{}],216:[function(require,module,exports){
+},{}],225:[function(require,module,exports){
 "use strict";
 function identity(x) {
     return x;
 }
 exports.identity = identity;
 
-},{}],217:[function(require,module,exports){
+},{}],226:[function(require,module,exports){
 "use strict";
 exports.isArray = Array.isArray || (function (x) { return x && typeof x.length === 'number'; });
 
-},{}],218:[function(require,module,exports){
+},{}],227:[function(require,module,exports){
 "use strict";
 exports.isArrayLike = (function (x) { return x && typeof x.length === 'number'; });
 
-},{}],219:[function(require,module,exports){
+},{}],228:[function(require,module,exports){
 "use strict";
 function isDate(value) {
     return value instanceof Date && !isNaN(+value);
 }
 exports.isDate = isDate;
 
-},{}],220:[function(require,module,exports){
+},{}],229:[function(require,module,exports){
 "use strict";
 function isFunction(x) {
     return typeof x === 'function';
 }
 exports.isFunction = isFunction;
 
-},{}],221:[function(require,module,exports){
+},{}],230:[function(require,module,exports){
 "use strict";
 var isArray_1 = require('../util/isArray');
 function isNumeric(val) {
@@ -15755,34 +16173,34 @@ function isNumeric(val) {
 exports.isNumeric = isNumeric;
 ;
 
-},{"../util/isArray":217}],222:[function(require,module,exports){
+},{"../util/isArray":226}],231:[function(require,module,exports){
 "use strict";
 function isObject(x) {
     return x != null && typeof x === 'object';
 }
 exports.isObject = isObject;
 
-},{}],223:[function(require,module,exports){
+},{}],232:[function(require,module,exports){
 "use strict";
 function isPromise(value) {
     return value && typeof value.subscribe !== 'function' && typeof value.then === 'function';
 }
 exports.isPromise = isPromise;
 
-},{}],224:[function(require,module,exports){
+},{}],233:[function(require,module,exports){
 "use strict";
 function isScheduler(value) {
     return value && typeof value.schedule === 'function';
 }
 exports.isScheduler = isScheduler;
 
-},{}],225:[function(require,module,exports){
+},{}],234:[function(require,module,exports){
 "use strict";
 /* tslint:disable:no-empty */
 function noop() { }
 exports.noop = noop;
 
-},{}],226:[function(require,module,exports){
+},{}],235:[function(require,module,exports){
 "use strict";
 var noop_1 = require('./noop');
 /* tslint:enable:max-line-length */
@@ -15808,7 +16226,7 @@ function pipeFromArray(fns) {
 }
 exports.pipeFromArray = pipeFromArray;
 
-},{"./noop":225}],227:[function(require,module,exports){
+},{"./noop":234}],236:[function(require,module,exports){
 (function (global){
 "use strict";
 // CommonJS / Node have global context exposed as "global" variable.
@@ -15831,7 +16249,7 @@ exports.root = _root;
 
 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
 
-},{}],228:[function(require,module,exports){
+},{}],237:[function(require,module,exports){
 "use strict";
 var root_1 = require('./root');
 var isArrayLike_1 = require('./isArrayLike');
@@ -15911,7 +16329,7 @@ function subscribeToResult(outerSubscriber, result, outerValue, outerIndex) {
 }
 exports.subscribeToResult = subscribeToResult;
 
-},{"../InnerSubscriber":27,"../Observable":29,"../symbol/iterator":205,"../symbol/observable":206,"./isArrayLike":218,"./isObject":222,"./isPromise":223,"./root":227}],229:[function(require,module,exports){
+},{"../InnerSubscriber":27,"../Observable":29,"../symbol/iterator":214,"../symbol/observable":215,"./isArrayLike":227,"./isObject":231,"./isPromise":232,"./root":236}],238:[function(require,module,exports){
 "use strict";
 var Subscriber_1 = require('../Subscriber');
 var rxSubscriber_1 = require('../symbol/rxSubscriber');
@@ -15932,7 +16350,7 @@ function toSubscriber(nextOrObserver, error, complete) {
 }
 exports.toSubscriber = toSubscriber;
 
-},{"../Observer":30,"../Subscriber":36,"../symbol/rxSubscriber":207}],230:[function(require,module,exports){
+},{"../Observer":30,"../Subscriber":36,"../symbol/rxSubscriber":216}],239:[function(require,module,exports){
 "use strict";
 var errorObject_1 = require('./errorObject');
 var tryCatchTarget;
@@ -15952,7 +16370,7 @@ function tryCatch(fn) {
 exports.tryCatch = tryCatch;
 ;
 
-},{"./errorObject":215}],231:[function(require,module,exports){
+},{"./errorObject":224}],240:[function(require,module,exports){
 // threejs.org/license
 (function(m,ja){"object"===typeof exports&&"undefined"!==typeof module?ja(exports):"function"===typeof define&&define.amd?define(["exports"],ja):ja(m.THREE=m.THREE||{})})(this,function(m){function ja(){}function C(a,b){this.x=a||0;this.y=b||0}function K(){this.elements=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];0<arguments.length&&console.error("THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.")}function Z(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._w=void 0!==d?d:1}
 function p(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0}function ra(){this.elements=[1,0,0,0,1,0,0,0,1];0<arguments.length&&console.error("THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.")}function ea(a,b,c,d,e,f,g,h,k,l){Object.defineProperty(this,"id",{value:kf++});this.uuid=R.generateUUID();this.name="";this.image=void 0!==a?a:ea.DEFAULT_IMAGE;this.mipmaps=[];this.mapping=void 0!==b?b:ea.DEFAULT_MAPPING;this.wrapS=void 0!==c?c:1001;this.wrapT=void 0!==d?d:1001;this.magFilter=
@@ -16852,7 +17270,7 @@ var e=new $d;e.setCrossOrigin(this.crossOrigin);a=e.load(a,c,void 0,d);b&&(a.map
 function(a,b){console.warn("THREE.Projector: .projectVector() is now vector.project().");a.project(b)};this.unprojectVector=function(a,b){console.warn("THREE.Projector: .unprojectVector() is now vector.unproject().");a.unproject(b)};this.pickingRay=function(){console.error("THREE.Projector: .pickingRay() is now raycaster.setFromCamera().")}};m.CanvasRenderer=function(){console.error("THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js");this.domElement=document.createElementNS("http://www.w3.org/1999/xhtml",
 "canvas");this.clear=function(){};this.render=function(){};this.setClearColor=function(){};this.setSize=function(){}};Object.defineProperty(m,"__esModule",{value:!0})});
 
-},{}],232:[function(require,module,exports){
+},{}],241:[function(require,module,exports){
 'use strict';
 
 module.exports = TinyQueue;
@@ -16939,7 +17357,7 @@ TinyQueue.prototype = {
     }
 };
 
-},{}],233:[function(require,module,exports){
+},{}],242:[function(require,module,exports){
 //     Underscore.js 1.8.3
 //     http://underscorejs.org
 //     (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
@@ -18489,22 +18907,22 @@ TinyQueue.prototype = {
   }
 }.call(this));
 
-},{}],234:[function(require,module,exports){
+},{}],243:[function(require,module,exports){
 var createElement = require("./vdom/create-element.js")
 
 module.exports = createElement
 
-},{"./vdom/create-element.js":240}],235:[function(require,module,exports){
+},{"./vdom/create-element.js":249}],244:[function(require,module,exports){
 var diff = require("./vtree/diff.js")
 
 module.exports = diff
 
-},{"./vtree/diff.js":260}],236:[function(require,module,exports){
+},{"./vtree/diff.js":269}],245:[function(require,module,exports){
 var h = require("./virtual-hyperscript/index.js")
 
 module.exports = h
 
-},{"./virtual-hyperscript/index.js":247}],237:[function(require,module,exports){
+},{"./virtual-hyperscript/index.js":256}],246:[function(require,module,exports){
 var diff = require("./diff.js")
 var patch = require("./patch.js")
 var h = require("./h.js")
@@ -18521,12 +18939,12 @@ module.exports = {
     VText: VText
 }
 
-},{"./create-element.js":234,"./diff.js":235,"./h.js":236,"./patch.js":238,"./vnode/vnode.js":256,"./vnode/vtext.js":258}],238:[function(require,module,exports){
+},{"./create-element.js":243,"./diff.js":244,"./h.js":245,"./patch.js":247,"./vnode/vnode.js":265,"./vnode/vtext.js":267}],247:[function(require,module,exports){
 var patch = require("./vdom/patch.js")
 
 module.exports = patch
 
-},{"./vdom/patch.js":243}],239:[function(require,module,exports){
+},{"./vdom/patch.js":252}],248:[function(require,module,exports){
 var isObject = require("is-object")
 var isHook = require("../vnode/is-vhook.js")
 
@@ -18625,7 +19043,7 @@ function getPrototype(value) {
     }
 }
 
-},{"../vnode/is-vhook.js":251,"is-object":20}],240:[function(require,module,exports){
+},{"../vnode/is-vhook.js":260,"is-object":20}],249:[function(require,module,exports){
 var document = require("global/document")
 
 var applyProperties = require("./apply-properties")
@@ -18673,7 +19091,7 @@ function createElement(vnode, opts) {
     return node
 }
 
-},{"../vnode/handle-thunk.js":249,"../vnode/is-vnode.js":252,"../vnode/is-vtext.js":253,"../vnode/is-widget.js":254,"./apply-properties":239,"global/document":16}],241:[function(require,module,exports){
+},{"../vnode/handle-thunk.js":258,"../vnode/is-vnode.js":261,"../vnode/is-vtext.js":262,"../vnode/is-widget.js":263,"./apply-properties":248,"global/document":16}],250:[function(require,module,exports){
 // Maps a virtual DOM tree onto a real DOM tree in an efficient manner.
 // We don't want to read all of the DOM nodes in the tree so we use
 // the in-order tree indexing to eliminate recursion down certain branches.
@@ -18760,7 +19178,7 @@ function ascending(a, b) {
     return a > b ? 1 : -1
 }
 
-},{}],242:[function(require,module,exports){
+},{}],251:[function(require,module,exports){
 var applyProperties = require("./apply-properties")
 
 var isWidget = require("../vnode/is-widget.js")
@@ -18913,7 +19331,7 @@ function replaceRoot(oldRoot, newRoot) {
     return newRoot;
 }
 
-},{"../vnode/is-widget.js":254,"../vnode/vpatch.js":257,"./apply-properties":239,"./update-widget":244}],243:[function(require,module,exports){
+},{"../vnode/is-widget.js":263,"../vnode/vpatch.js":266,"./apply-properties":248,"./update-widget":253}],252:[function(require,module,exports){
 var document = require("global/document")
 var isArray = require("x-is-array")
 
@@ -18995,7 +19413,7 @@ function patchIndices(patches) {
     return indices
 }
 
-},{"./create-element":240,"./dom-index":241,"./patch-op":242,"global/document":16,"x-is-array":279}],244:[function(require,module,exports){
+},{"./create-element":249,"./dom-index":250,"./patch-op":251,"global/document":16,"x-is-array":288}],253:[function(require,module,exports){
 var isWidget = require("../vnode/is-widget.js")
 
 module.exports = updateWidget
@@ -19012,7 +19430,7 @@ function updateWidget(a, b) {
     return false
 }
 
-},{"../vnode/is-widget.js":254}],245:[function(require,module,exports){
+},{"../vnode/is-widget.js":263}],254:[function(require,module,exports){
 'use strict';
 
 var EvStore = require('ev-store');
@@ -19041,7 +19459,7 @@ EvHook.prototype.unhook = function(node, propertyName) {
     es[propName] = undefined;
 };
 
-},{"ev-store":9}],246:[function(require,module,exports){
+},{"ev-store":9}],255:[function(require,module,exports){
 'use strict';
 
 module.exports = SoftSetHook;
@@ -19060,7 +19478,7 @@ SoftSetHook.prototype.hook = function (node, propertyName) {
     }
 };
 
-},{}],247:[function(require,module,exports){
+},{}],256:[function(require,module,exports){
 'use strict';
 
 var isArray = require('x-is-array');
@@ -19199,7 +19617,7 @@ function errorString(obj) {
     }
 }
 
-},{"../vnode/is-thunk":250,"../vnode/is-vhook":251,"../vnode/is-vnode":252,"../vnode/is-vtext":253,"../vnode/is-widget":254,"../vnode/vnode.js":256,"../vnode/vtext.js":258,"./hooks/ev-hook.js":245,"./hooks/soft-set-hook.js":246,"./parse-tag.js":248,"x-is-array":279}],248:[function(require,module,exports){
+},{"../vnode/is-thunk":259,"../vnode/is-vhook":260,"../vnode/is-vnode":261,"../vnode/is-vtext":262,"../vnode/is-widget":263,"../vnode/vnode.js":265,"../vnode/vtext.js":267,"./hooks/ev-hook.js":254,"./hooks/soft-set-hook.js":255,"./parse-tag.js":257,"x-is-array":288}],257:[function(require,module,exports){
 'use strict';
 
 var split = require('browser-split');
@@ -19255,7 +19673,7 @@ function parseTag(tag, props) {
     return props.namespace ? tagName : tagName.toUpperCase();
 }
 
-},{"browser-split":5}],249:[function(require,module,exports){
+},{"browser-split":5}],258:[function(require,module,exports){
 var isVNode = require("./is-vnode")
 var isVText = require("./is-vtext")
 var isWidget = require("./is-widget")
@@ -19297,14 +19715,14 @@ function renderThunk(thunk, previous) {
     return renderedThunk
 }
 
-},{"./is-thunk":250,"./is-vnode":252,"./is-vtext":253,"./is-widget":254}],250:[function(require,module,exports){
+},{"./is-thunk":259,"./is-vnode":261,"./is-vtext":262,"./is-widget":263}],259:[function(require,module,exports){
 module.exports = isThunk
 
 function isThunk(t) {
     return t && t.type === "Thunk"
 }
 
-},{}],251:[function(require,module,exports){
+},{}],260:[function(require,module,exports){
 module.exports = isHook
 
 function isHook(hook) {
@@ -19313,7 +19731,7 @@ function isHook(hook) {
        typeof hook.unhook === "function" && !hook.hasOwnProperty("unhook"))
 }
 
-},{}],252:[function(require,module,exports){
+},{}],261:[function(require,module,exports){
 var version = require("./version")
 
 module.exports = isVirtualNode
@@ -19322,7 +19740,7 @@ function isVirtualNode(x) {
     return x && x.type === "VirtualNode" && x.version === version
 }
 
-},{"./version":255}],253:[function(require,module,exports){
+},{"./version":264}],262:[function(require,module,exports){
 var version = require("./version")
 
 module.exports = isVirtualText
@@ -19331,17 +19749,17 @@ function isVirtualText(x) {
     return x && x.type === "VirtualText" && x.version === version
 }
 
-},{"./version":255}],254:[function(require,module,exports){
+},{"./version":264}],263:[function(require,module,exports){
 module.exports = isWidget
 
 function isWidget(w) {
     return w && w.type === "Widget"
 }
 
-},{}],255:[function(require,module,exports){
+},{}],264:[function(require,module,exports){
 module.exports = "2"
 
-},{}],256:[function(require,module,exports){
+},{}],265:[function(require,module,exports){
 var version = require("./version")
 var isVNode = require("./is-vnode")
 var isWidget = require("./is-widget")
@@ -19415,7 +19833,7 @@ function VirtualNode(tagName, properties, children, key, namespace) {
 VirtualNode.prototype.version = version
 VirtualNode.prototype.type = "VirtualNode"
 
-},{"./is-thunk":250,"./is-vhook":251,"./is-vnode":252,"./is-widget":254,"./version":255}],257:[function(require,module,exports){
+},{"./is-thunk":259,"./is-vhook":260,"./is-vnode":261,"./is-widget":263,"./version":264}],266:[function(require,module,exports){
 var version = require("./version")
 
 VirtualPatch.NONE = 0
@@ -19439,7 +19857,7 @@ function VirtualPatch(type, vNode, patch) {
 VirtualPatch.prototype.version = version
 VirtualPatch.prototype.type = "VirtualPatch"
 
-},{"./version":255}],258:[function(require,module,exports){
+},{"./version":264}],267:[function(require,module,exports){
 var version = require("./version")
 
 module.exports = VirtualText
@@ -19451,7 +19869,7 @@ function VirtualText(text) {
 VirtualText.prototype.version = version
 VirtualText.prototype.type = "VirtualText"
 
-},{"./version":255}],259:[function(require,module,exports){
+},{"./version":264}],268:[function(require,module,exports){
 var isObject = require("is-object")
 var isHook = require("../vnode/is-vhook")
 
@@ -19511,7 +19929,7 @@ function getPrototype(value) {
   }
 }
 
-},{"../vnode/is-vhook":251,"is-object":20}],260:[function(require,module,exports){
+},{"../vnode/is-vhook":260,"is-object":20}],269:[function(require,module,exports){
 var isArray = require("x-is-array")
 
 var VPatch = require("../vnode/vpatch")
@@ -19940,7 +20358,7 @@ function appendPatch(apply, patch) {
     }
 }
 
-},{"../vnode/handle-thunk":249,"../vnode/is-thunk":250,"../vnode/is-vnode":252,"../vnode/is-vtext":253,"../vnode/is-widget":254,"../vnode/vpatch":257,"./diff-props":259,"x-is-array":279}],261:[function(require,module,exports){
+},{"../vnode/handle-thunk":258,"../vnode/is-thunk":259,"../vnode/is-vnode":261,"../vnode/is-vtext":262,"../vnode/is-widget":263,"../vnode/vpatch":266,"./diff-props":268,"x-is-array":288}],270:[function(require,module,exports){
 /** @license MIT License (c) copyright 2010-2014 original author or authors */
 /** @author Brian Cavalier */
 /** @author John Hann */
@@ -19959,7 +20377,7 @@ define(function (require) {
 });
 })(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
 
-},{"./Scheduler":262,"./env":274,"./makePromise":276}],262:[function(require,module,exports){
+},{"./Scheduler":271,"./env":283,"./makePromise":285}],271:[function(require,module,exports){
 /** @license MIT License (c) copyright 2010-2014 original author or authors */
 /** @author Brian Cavalier */
 /** @author John Hann */
@@ -20041,7 +20459,7 @@ define(function() {
 });
 }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
 
-},{}],263:[function(require,module,exports){
+},{}],272:[function(require,module,exports){
 /** @license MIT License (c) copyright 2010-2014 original author or authors */
 /** @author Brian Cavalier */
 /** @author John Hann */
@@ -20069,7 +20487,7 @@ define(function() {
        return TimeoutError;
 });
 }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
-},{}],264:[function(require,module,exports){
+},{}],273:[function(require,module,exports){
 /** @license MIT License (c) copyright 2010-2014 original author or authors */
 /** @author Brian Cavalier */
 /** @author John Hann */
@@ -20126,7 +20544,7 @@ define(function() {
 
 
 
-},{}],265:[function(require,module,exports){
+},{}],274:[function(require,module,exports){
 /** @license MIT License (c) copyright 2010-2014 original author or authors */
 /** @author Brian Cavalier */
 /** @author John Hann */
@@ -20427,7 +20845,7 @@ define(function(require) {
 });
 }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
 
-},{"../apply":264,"../state":277}],266:[function(require,module,exports){
+},{"../apply":273,"../state":286}],275:[function(require,module,exports){
 /** @license MIT License (c) copyright 2010-2014 original author or authors */
 /** @author Brian Cavalier */
 /** @author John Hann */
@@ -20589,7 +21007,7 @@ define(function() {
 });
 }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
 
-},{}],267:[function(require,module,exports){
+},{}],276:[function(require,module,exports){
 /** @license MIT License (c) copyright 2010-2014 original author or authors */
 /** @author Brian Cavalier */
 /** @author John Hann */
@@ -20618,7 +21036,7 @@ define(function() {
 });
 }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
 
-},{}],268:[function(require,module,exports){
+},{}],277:[function(require,module,exports){
 /** @license MIT License (c) copyright 2010-2014 original author or authors */
 /** @author Brian Cavalier */
 /** @author John Hann */
@@ -20640,7 +21058,7 @@ define(function(require) {
 });
 }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
 
-},{"../state":277}],269:[function(require,module,exports){
+},{"../state":286}],278:[function(require,module,exports){
 /** @license MIT License (c) copyright 2010-2014 original author or authors */
 /** @author Brian Cavalier */
 /** @author John Hann */
@@ -20707,7 +21125,7 @@ define(function() {
 });
 }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
 
-},{}],270:[function(require,module,exports){
+},{}],279:[function(require,module,exports){
 /** @license MIT License (c) copyright 2010-2014 original author or authors */
 /** @author Brian Cavalier */
 /** @author John Hann */
@@ -20733,7 +21151,7 @@ define(function() {
 });
 }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
 
-},{}],271:[function(require,module,exports){
+},{}],280:[function(require,module,exports){
 /** @license MIT License (c) copyright 2010-2014 original author or authors */
 /** @author Brian Cavalier */
 /** @author John Hann */
@@ -20813,7 +21231,7 @@ define(function(require) {
 });
 }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
 
-},{"../TimeoutError":263,"../env":274}],272:[function(require,module,exports){
+},{"../TimeoutError":272,"../env":283}],281:[function(require,module,exports){
 /** @license MIT License (c) copyright 2010-2014 original author or authors */
 /** @author Brian Cavalier */
 /** @author John Hann */
@@ -20901,7 +21319,7 @@ define(function(require) {
 });
 }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
 
-},{"../env":274,"../format":275}],273:[function(require,module,exports){
+},{"../env":283,"../format":284}],282:[function(require,module,exports){
 /** @license MIT License (c) copyright 2010-2014 original author or authors */
 /** @author Brian Cavalier */
 /** @author John Hann */
@@ -20941,7 +21359,7 @@ define(function() {
 }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
 
 
-},{}],274:[function(require,module,exports){
+},{}],283:[function(require,module,exports){
 (function (process){
 /** @license MIT License (c) copyright 2010-2014 original author or authors */
 /** @author Brian Cavalier */
@@ -21019,7 +21437,7 @@ define(function(require) {
 
 }).call(this,require('_process'))
 
-},{"_process":6}],275:[function(require,module,exports){
+},{"_process":6}],284:[function(require,module,exports){
 /** @license MIT License (c) copyright 2010-2014 original author or authors */
 /** @author Brian Cavalier */
 /** @author John Hann */
@@ -21077,7 +21495,7 @@ define(function() {
 });
 }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
 
-},{}],276:[function(require,module,exports){
+},{}],285:[function(require,module,exports){
 (function (process){
 /** @license MIT License (c) copyright 2010-2014 original author or authors */
 /** @author Brian Cavalier */
@@ -22037,7 +22455,7 @@ define(function() {
 
 }).call(this,require('_process'))
 
-},{"_process":6}],277:[function(require,module,exports){
+},{"_process":6}],286:[function(require,module,exports){
 /** @license MIT License (c) copyright 2010-2014 original author or authors */
 /** @author Brian Cavalier */
 /** @author John Hann */
@@ -22074,7 +22492,7 @@ define(function() {
 });
 }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }));
 
-},{}],278:[function(require,module,exports){
+},{}],287:[function(require,module,exports){
 /** @license MIT License (c) copyright 2010-2014 original author or authors */
 
 /**
@@ -22304,7 +22722,7 @@ define(function (require) {
 });
 })(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });
 
-},{"./lib/Promise":261,"./lib/TimeoutError":263,"./lib/apply":264,"./lib/decorators/array":265,"./lib/decorators/flow":266,"./lib/decorators/fold":267,"./lib/decorators/inspect":268,"./lib/decorators/iterate":269,"./lib/decorators/progress":270,"./lib/decorators/timed":271,"./lib/decorators/unhandledRejection":272,"./lib/decorators/with":273}],279:[function(require,module,exports){
+},{"./lib/Promise":270,"./lib/TimeoutError":272,"./lib/apply":273,"./lib/decorators/array":274,"./lib/decorators/flow":275,"./lib/decorators/fold":276,"./lib/decorators/inspect":277,"./lib/decorators/iterate":278,"./lib/decorators/progress":279,"./lib/decorators/timed":280,"./lib/decorators/unhandledRejection":281,"./lib/decorators/with":282}],288:[function(require,module,exports){
 var nativeIsArray = Array.isArray
 var toString = Object.prototype.toString
 
@@ -22314,7 +22732,7 @@ function isArray(obj) {
     return toString.call(obj) === "[object Array]"
 }
 
-},{}],280:[function(require,module,exports){
+},{}],289:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var APIv3_1 = require("./api/APIv3");
@@ -22322,7 +22740,7 @@ exports.APIv3 = APIv3_1.APIv3;
 var ModelCreator_1 = require("./api/ModelCreator");
 exports.ModelCreator = ModelCreator_1.ModelCreator;
 
-},{"./api/APIv3":293,"./api/ModelCreator":294}],281:[function(require,module,exports){
+},{"./api/APIv3":302,"./api/ModelCreator":303}],290:[function(require,module,exports){
 "use strict";
 function __export(m) {
     for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
@@ -22334,6 +22752,10 @@ var ComponentService_1 = require("./component/ComponentService");
 exports.ComponentService = ComponentService_1.ComponentService;
 var HandlerBase_1 = require("./component/utils/HandlerBase");
 exports.HandlerBase = HandlerBase_1.HandlerBase;
+var MeshFactory_1 = require("./component/utils/MeshFactory");
+exports.MeshFactory = MeshFactory_1.MeshFactory;
+var MeshScene_1 = require("./component/utils/MeshScene");
+exports.MeshScene = MeshScene_1.MeshScene;
 var AttributionComponent_1 = require("./component/AttributionComponent");
 exports.AttributionComponent = AttributionComponent_1.AttributionComponent;
 var BackgroundComponent_1 = require("./component/BackgroundComponent");
@@ -22398,26 +22820,24 @@ var SequenceComponent_1 = require("./component/sequence/SequenceComponent");
 exports.SequenceComponent = SequenceComponent_1.SequenceComponent;
 var SequenceDOMRenderer_1 = require("./component/sequence/SequenceDOMRenderer");
 exports.SequenceDOMRenderer = SequenceDOMRenderer_1.SequenceDOMRenderer;
-var SequenceDOMInteraction_1 = require("./component/sequence/SequenceDOMInteraction");
-exports.SequenceDOMInteraction = SequenceDOMInteraction_1.SequenceDOMInteraction;
-var ControlMode_1 = require("./component/sequence/ControlMode");
-exports.ControlMode = ControlMode_1.ControlMode;
+var SequenceMode_1 = require("./component/sequence/SequenceMode");
+exports.SequenceMode = SequenceMode_1.SequenceMode;
 var ImagePlaneComponent_1 = require("./component/imageplane/ImagePlaneComponent");
 exports.ImagePlaneComponent = ImagePlaneComponent_1.ImagePlaneComponent;
-var ImagePlaneFactory_1 = require("./component/imageplane/ImagePlaneFactory");
-exports.ImagePlaneFactory = ImagePlaneFactory_1.ImagePlaneFactory;
 var ImagePlaneGLRenderer_1 = require("./component/imageplane/ImagePlaneGLRenderer");
 exports.ImagePlaneGLRenderer = ImagePlaneGLRenderer_1.ImagePlaneGLRenderer;
-var ImagePlaneScene_1 = require("./component/imageplane/ImagePlaneScene");
-exports.ImagePlaneScene = ImagePlaneScene_1.ImagePlaneScene;
-var ImagePlaneShaders_1 = require("./component/imageplane/ImagePlaneShaders");
-exports.ImagePlaneShaders = ImagePlaneShaders_1.ImagePlaneShaders;
+var Shaders_1 = require("./component/shaders/Shaders");
+exports.Shaders = Shaders_1.Shaders;
 var SimpleMarker_1 = require("./component/marker/marker/SimpleMarker");
 exports.SimpleMarker = SimpleMarker_1.SimpleMarker;
 var CircleMarker_1 = require("./component/marker/marker/CircleMarker");
 exports.CircleMarker = CircleMarker_1.CircleMarker;
-var SliderComponent_1 = require("./component/imageplane/SliderComponent");
+var SliderComponent_1 = require("./component/slider/SliderComponent");
 exports.SliderComponent = SliderComponent_1.SliderComponent;
+var SliderDOMRenderer_1 = require("./component/slider/SliderDOMRenderer");
+exports.SliderDOMRenderer = SliderDOMRenderer_1.SliderDOMRenderer;
+var SliderGLRenderer_1 = require("./component/slider/SliderGLRenderer");
+exports.SliderGLRenderer = SliderGLRenderer_1.SliderGLRenderer;
 var StatsComponent_1 = require("./component/StatsComponent");
 exports.StatsComponent = StatsComponent_1.StatsComponent;
 var TagHandlerBase_1 = require("./component/tag/handlers/TagHandlerBase");
@@ -22476,9 +22896,11 @@ var PolygonGeometry_1 = require("./component/tag/geometry/PolygonGeometry");
 exports.PolygonGeometry = PolygonGeometry_1.PolygonGeometry;
 var GeometryTagError_1 = require("./component/tag/error/GeometryTagError");
 exports.GeometryTagError = GeometryTagError_1.GeometryTagError;
+var ZoomComponent_1 = require("./component/zoom/ZoomComponent");
+exports.ZoomComponent = ZoomComponent_1.ZoomComponent;
 __export(require("./component/interfaces/interfaces"));
 
-},{"./component/AttributionComponent":295,"./component/BackgroundComponent":296,"./component/BearingComponent":297,"./component/CacheComponent":298,"./component/Component":299,"./component/ComponentService":300,"./component/CoverComponent":301,"./component/DebugComponent":302,"./component/ImageComponent":303,"./component/LoadingComponent":304,"./component/NavigationComponent":305,"./component/RouteComponent":306,"./component/StatsComponent":307,"./component/direction/DirectionComponent":308,"./component/direction/DirectionDOMCalculator":309,"./component/direction/DirectionDOMRenderer":310,"./component/imageplane/ImagePlaneComponent":311,"./component/imageplane/ImagePlaneFactory":312,"./component/imageplane/ImagePlaneGLRenderer":313,"./component/imageplane/ImagePlaneScene":314,"./component/imageplane/ImagePlaneShaders":315,"./component/imageplane/SliderComponent":316,"./component/interfaces/interfaces":318,"./component/keyboard/KeyPlayHandler":319,"./component/keyboard/KeySequenceNavigationHandler":320,"./component/keyboard/KeySpatialNavigationHandler":321,"./component/keyboard/KeyZoomHandler":322,"./component/keyboard/KeyboardComponent":323,"./component/marker/MarkerComponent":325,"./component/marker/MarkerScene":326,"./component/marker/MarkerSet":327,"./component/marker/marker/CircleMarker":328,"./component/marker/marker/Marker":329,"./component/marker/marker/SimpleMarker":330,"./component/mouse/BounceHandler":331,"./component/mouse/DoubleClickZoomHandler":332,"./component/mouse/DragPanHandler":333,"./component/mouse/MouseComponent":334,"./component/mouse/ScrollZoomHandler":335,"./component/mouse/TouchZoomHandler":336,"./component/popup/PopupComponent":338,"./component/popup/popup/Popup":339,"./component/sequence/ControlMode":340,"./component/sequence/SequenceComponent":341,"./component/sequence/SequenceDOMInteraction":342,"./component/sequence/SequenceDOMRenderer":343,"./component/tag/TagComponent":345,"./component/tag/TagCreator":346,"./component/tag/TagDOMRenderer":347,"./component/tag/TagMode":348,"./component/tag/TagOperation":349,"./component/tag/TagScene":350,"./component/tag/TagSet":351,"./component/tag/error/GeometryTagError":352,"./component/tag/geometry/Geometry":353,"./component/tag/geometry/PointGeometry":354,"./component/tag/geometry/PolygonGeometry":355,"./component/tag/geometry/RectGeometry":356,"./component/tag/geometry/VertexGeometry":357,"./component/tag/handlers/CreateHandlerBase":358,"./component/tag/handlers/CreatePointHandler":359,"./component/tag/handlers/CreatePolygonHandler":360,"./component/tag/handlers/CreateRectDragHandler":361,"./component/tag/handlers/CreateRectHandler":362,"./component/tag/handlers/CreateVertexHandler":363,"./component/tag/handlers/EditVertexHandler":364,"./component/tag/handlers/TagHandlerBase":365,"./component/tag/tag/OutlineCreateTag":366,"./component/tag/tag/OutlineRenderTag":367,"./component/tag/tag/OutlineTag":368,"./component/tag/tag/RenderTag":369,"./component/tag/tag/SpotRenderTag":370,"./component/tag/tag/SpotTag":371,"./component/tag/tag/Tag":372,"./component/utils/HandlerBase":373}],282:[function(require,module,exports){
+},{"./component/AttributionComponent":304,"./component/BackgroundComponent":305,"./component/BearingComponent":306,"./component/CacheComponent":307,"./component/Component":308,"./component/ComponentService":309,"./component/CoverComponent":310,"./component/DebugComponent":311,"./component/ImageComponent":312,"./component/LoadingComponent":313,"./component/NavigationComponent":314,"./component/RouteComponent":315,"./component/StatsComponent":316,"./component/direction/DirectionComponent":317,"./component/direction/DirectionDOMCalculator":318,"./component/direction/DirectionDOMRenderer":319,"./component/imageplane/ImagePlaneComponent":320,"./component/imageplane/ImagePlaneGLRenderer":321,"./component/interfaces/interfaces":324,"./component/keyboard/KeyPlayHandler":325,"./component/keyboard/KeySequenceNavigationHandler":326,"./component/keyboard/KeySpatialNavigationHandler":327,"./component/keyboard/KeyZoomHandler":328,"./component/keyboard/KeyboardComponent":329,"./component/marker/MarkerComponent":331,"./component/marker/MarkerScene":332,"./component/marker/MarkerSet":333,"./component/marker/marker/CircleMarker":334,"./component/marker/marker/Marker":335,"./component/marker/marker/SimpleMarker":336,"./component/mouse/BounceHandler":337,"./component/mouse/DoubleClickZoomHandler":338,"./component/mouse/DragPanHandler":339,"./component/mouse/MouseComponent":340,"./component/mouse/ScrollZoomHandler":341,"./component/mouse/TouchZoomHandler":342,"./component/popup/PopupComponent":344,"./component/popup/popup/Popup":345,"./component/sequence/SequenceComponent":346,"./component/sequence/SequenceDOMRenderer":347,"./component/sequence/SequenceMode":348,"./component/shaders/Shaders":349,"./component/slider/SliderComponent":350,"./component/slider/SliderDOMRenderer":351,"./component/slider/SliderGLRenderer":352,"./component/tag/TagComponent":354,"./component/tag/TagCreator":355,"./component/tag/TagDOMRenderer":356,"./component/tag/TagMode":357,"./component/tag/TagOperation":358,"./component/tag/TagScene":359,"./component/tag/TagSet":360,"./component/tag/error/GeometryTagError":361,"./component/tag/geometry/Geometry":362,"./component/tag/geometry/PointGeometry":363,"./component/tag/geometry/PolygonGeometry":364,"./component/tag/geometry/RectGeometry":365,"./component/tag/geometry/VertexGeometry":366,"./component/tag/handlers/CreateHandlerBase":367,"./component/tag/handlers/CreatePointHandler":368,"./component/tag/handlers/CreatePolygonHandler":369,"./component/tag/handlers/CreateRectDragHandler":370,"./component/tag/handlers/CreateRectHandler":371,"./component/tag/handlers/CreateVertexHandler":372,"./component/tag/handlers/EditVertexHandler":373,"./component/tag/handlers/TagHandlerBase":374,"./component/tag/tag/OutlineCreateTag":375,"./component/tag/tag/OutlineRenderTag":376,"./component/tag/tag/OutlineTag":377,"./component/tag/tag/RenderTag":378,"./component/tag/tag/SpotRenderTag":379,"./component/tag/tag/SpotTag":380,"./component/tag/tag/Tag":381,"./component/utils/HandlerBase":382,"./component/utils/MeshFactory":383,"./component/utils/MeshScene":384,"./component/zoom/ZoomComponent":385}],291:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var EdgeDirection_1 = require("./graph/edge/EdgeDirection");
@@ -22492,9 +22914,11 @@ exports.EdgeCalculatorCoefficients = EdgeCalculatorCoefficients_1.EdgeCalculator
 var EdgeCalculator_1 = require("./graph/edge/EdgeCalculator");
 exports.EdgeCalculator = EdgeCalculator_1.EdgeCalculator;
 
-},{"./graph/edge/EdgeCalculator":392,"./graph/edge/EdgeCalculatorCoefficients":393,"./graph/edge/EdgeCalculatorDirections":394,"./graph/edge/EdgeCalculatorSettings":395,"./graph/edge/EdgeDirection":396}],283:[function(require,module,exports){
+},{"./graph/edge/EdgeCalculator":405,"./graph/edge/EdgeCalculatorCoefficients":406,"./graph/edge/EdgeCalculatorDirections":407,"./graph/edge/EdgeCalculatorSettings":408,"./graph/edge/EdgeDirection":409}],292:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
+var AbortMapillaryError_1 = require("./error/AbortMapillaryError");
+exports.AbortMapillaryError = AbortMapillaryError_1.AbortMapillaryError;
 var ArgumentMapillaryError_1 = require("./error/ArgumentMapillaryError");
 exports.ArgumentMapillaryError = ArgumentMapillaryError_1.ArgumentMapillaryError;
 var GraphMapillaryError_1 = require("./error/GraphMapillaryError");
@@ -22502,7 +22926,7 @@ exports.GraphMapillaryError = GraphMapillaryError_1.GraphMapillaryError;
 var MapillaryError_1 = require("./error/MapillaryError");
 exports.MapillaryError = MapillaryError_1.MapillaryError;
 
-},{"./error/ArgumentMapillaryError":374,"./error/GraphMapillaryError":375,"./error/MapillaryError":376}],284:[function(require,module,exports){
+},{"./error/AbortMapillaryError":386,"./error/ArgumentMapillaryError":387,"./error/GraphMapillaryError":388,"./error/MapillaryError":389}],293:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Camera_1 = require("./geo/Camera");
@@ -22516,7 +22940,7 @@ exports.Spatial = Spatial_1.Spatial;
 var Transform_1 = require("./geo/Transform");
 exports.Transform = Transform_1.Transform;
 
-},{"./geo/Camera":377,"./geo/GeoCoords":378,"./geo/Spatial":379,"./geo/Transform":380,"./geo/ViewportCoords":381}],285:[function(require,module,exports){
+},{"./geo/Camera":390,"./geo/GeoCoords":391,"./geo/Spatial":392,"./geo/Transform":393,"./geo/ViewportCoords":394}],294:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var FilterCreator_1 = require("./graph/FilterCreator");
@@ -22540,7 +22964,7 @@ exports.NodeCache = NodeCache_1.NodeCache;
 var Sequence_1 = require("./graph/Sequence");
 exports.Sequence = Sequence_1.Sequence;
 
-},{"./graph/FilterCreator":382,"./graph/Graph":383,"./graph/GraphCalculator":384,"./graph/GraphMode":385,"./graph/GraphService":386,"./graph/ImageLoadingService":387,"./graph/MeshReader":388,"./graph/Node":389,"./graph/NodeCache":390,"./graph/Sequence":391}],286:[function(require,module,exports){
+},{"./graph/FilterCreator":395,"./graph/Graph":396,"./graph/GraphCalculator":397,"./graph/GraphMode":398,"./graph/GraphService":399,"./graph/ImageLoadingService":400,"./graph/MeshReader":401,"./graph/Node":402,"./graph/NodeCache":403,"./graph/Sequence":404}],295:[function(require,module,exports){
 "use strict";
 /**
  * MapillaryJS is a WebGL JavaScript library for exploring street level imagery
@@ -22553,12 +22977,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
 __export(require("./Support"));
 var Edge_1 = require("./Edge");
 exports.EdgeDirection = Edge_1.EdgeDirection;
+var Error_1 = require("./Error");
+exports.AbortMapillaryError = Error_1.AbortMapillaryError;
 var Render_1 = require("./Render");
 exports.RenderMode = Render_1.RenderMode;
+var State_1 = require("./State");
+exports.TransitionMode = State_1.TransitionMode;
 var Viewer_1 = require("./Viewer");
 exports.Alignment = Viewer_1.Alignment;
 exports.ImageSize = Viewer_1.ImageSize;
 exports.Viewer = Viewer_1.Viewer;
+var Component_1 = require("./Component");
+exports.SliderMode = Component_1.SliderMode;
 var TagComponent = require("./component/tag/Tag");
 exports.TagComponent = TagComponent;
 var MarkerComponent = require("./component/marker/Marker");
@@ -22566,7 +22996,7 @@ exports.MarkerComponent = MarkerComponent;
 var PopupComponent = require("./component/popup/Popup");
 exports.PopupComponent = PopupComponent;
 
-},{"./Edge":282,"./Render":287,"./Support":289,"./Viewer":292,"./component/marker/Marker":324,"./component/popup/Popup":337,"./component/tag/Tag":344}],287:[function(require,module,exports){
+},{"./Component":290,"./Edge":291,"./Error":292,"./Render":296,"./State":297,"./Support":298,"./Viewer":301,"./component/marker/Marker":330,"./component/popup/Popup":343,"./component/tag/Tag":353}],296:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var DOMRenderer_1 = require("./render/DOMRenderer");
@@ -22582,9 +23012,11 @@ exports.RenderMode = RenderMode_1.RenderMode;
 var RenderService_1 = require("./render/RenderService");
 exports.RenderService = RenderService_1.RenderService;
 
-},{"./render/DOMRenderer":397,"./render/GLRenderStage":398,"./render/GLRenderer":399,"./render/RenderCamera":400,"./render/RenderMode":401,"./render/RenderService":402}],288:[function(require,module,exports){
+},{"./render/DOMRenderer":410,"./render/GLRenderStage":411,"./render/GLRenderer":412,"./render/RenderCamera":413,"./render/RenderMode":414,"./render/RenderService":415}],297:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
+var RotationDelta_1 = require("./state/RotationDelta");
+exports.RotationDelta = RotationDelta_1.RotationDelta;
 var State_1 = require("./state/State");
 exports.State = State_1.State;
 var StateBase_1 = require("./state/states/StateBase");
@@ -22593,12 +23025,18 @@ var StateContext_1 = require("./state/StateContext");
 exports.StateContext = StateContext_1.StateContext;
 var StateService_1 = require("./state/StateService");
 exports.StateService = StateService_1.StateService;
+var TransitionMode_1 = require("./state/TransitionMode");
+exports.TransitionMode = TransitionMode_1.TransitionMode;
+var InteractiveStateBase_1 = require("./state/states/InteractiveStateBase");
+exports.InteractiveStateBase = InteractiveStateBase_1.InteractiveStateBase;
+var InteractiveWaitingState_1 = require("./state/states/InteractiveWaitingState");
+exports.InteractiveWaitingState = InteractiveWaitingState_1.InteractiveWaitingState;
 var TraversingState_1 = require("./state/states/TraversingState");
 exports.TraversingState = TraversingState_1.TraversingState;
 var WaitingState_1 = require("./state/states/WaitingState");
 exports.WaitingState = WaitingState_1.WaitingState;
 
-},{"./state/State":403,"./state/StateContext":404,"./state/StateService":405,"./state/states/StateBase":406,"./state/states/TraversingState":407,"./state/states/WaitingState":408}],289:[function(require,module,exports){
+},{"./state/RotationDelta":416,"./state/State":417,"./state/StateContext":418,"./state/StateService":419,"./state/TransitionMode":420,"./state/states/InteractiveStateBase":421,"./state/states/InteractiveWaitingState":422,"./state/states/StateBase":423,"./state/states/TraversingState":424,"./state/states/WaitingState":425}],298:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var support = require("./utils/Support");
@@ -22630,6 +23068,7 @@ exports.isSupported = isSupported;
  */
 function isFallbackSupported() {
     return support.isBrowser() &&
+        support.isBlobSupported() &&
         support.isArraySupported() &&
         support.isFunctionSupported() &&
         support.isJSONSupported() &&
@@ -22637,7 +23076,7 @@ function isFallbackSupported() {
 }
 exports.isFallbackSupported = isFallbackSupported;
 
-},{"./utils/Support":416}],290:[function(require,module,exports){
+},{"./utils/Support":433}],299:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var ImageTileLoader_1 = require("./tiles/ImageTileLoader");
@@ -22649,7 +23088,7 @@ exports.TextureProvider = TextureProvider_1.TextureProvider;
 var RegionOfInterestCalculator_1 = require("./tiles/RegionOfInterestCalculator");
 exports.RegionOfInterestCalculator = RegionOfInterestCalculator_1.RegionOfInterestCalculator;
 
-},{"./tiles/ImageTileLoader":409,"./tiles/ImageTileStore":410,"./tiles/RegionOfInterestCalculator":411,"./tiles/TextureProvider":412}],291:[function(require,module,exports){
+},{"./tiles/ImageTileLoader":426,"./tiles/ImageTileStore":427,"./tiles/RegionOfInterestCalculator":428,"./tiles/TextureProvider":429}],300:[function(require,module,exports){
 "use strict";
 function __export(m) {
     for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
@@ -22665,7 +23104,7 @@ __export(require("./utils/Support"));
 var Urls_1 = require("./utils/Urls");
 exports.Urls = Urls_1.Urls;
 
-},{"./utils/DOM":413,"./utils/EventEmitter":414,"./utils/Settings":415,"./utils/Support":416,"./utils/Urls":417}],292:[function(require,module,exports){
+},{"./utils/DOM":430,"./utils/EventEmitter":431,"./utils/Settings":432,"./utils/Support":433,"./utils/Urls":434}],301:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Alignment_1 = require("./viewer/Alignment");
@@ -22699,15 +23138,11 @@ exports.TouchService = TouchService_1.TouchService;
 var Viewer_1 = require("./viewer/Viewer");
 exports.Viewer = Viewer_1.Viewer;
 
-},{"./viewer/Alignment":418,"./viewer/CacheService":419,"./viewer/ComponentController":420,"./viewer/Container":421,"./viewer/ImageSize":422,"./viewer/KeyboardService":423,"./viewer/LoadingService":424,"./viewer/MouseService":425,"./viewer/Navigator":426,"./viewer/Observer":427,"./viewer/PlayService":428,"./viewer/Projection":429,"./viewer/SpriteService":430,"./viewer/TouchService":431,"./viewer/Viewer":432}],293:[function(require,module,exports){
+},{"./viewer/Alignment":435,"./viewer/CacheService":436,"./viewer/ComponentController":437,"./viewer/Container":438,"./viewer/ImageSize":439,"./viewer/KeyboardService":440,"./viewer/LoadingService":441,"./viewer/MouseService":442,"./viewer/Navigator":443,"./viewer/Observer":444,"./viewer/PlayService":445,"./viewer/Projection":446,"./viewer/SpriteService":447,"./viewer/TouchService":448,"./viewer/Viewer":449}],302:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
 var Observable_1 = require("rxjs/Observable");
-require("rxjs/add/observable/defer");
-require("rxjs/add/observable/fromPromise");
-require("rxjs/add/operator/catch");
-require("rxjs/add/operator/map");
 var API_1 = require("../API");
 /**
  * @class APIv3
@@ -22737,11 +23172,14 @@ var APIv3 = /** @class */ (function () {
         this._propertiesCore = [
             "cl",
             "l",
-            "sequence",
+            "sequence_key",
         ];
         this._propertiesFill = [
             "captured_at",
+            "captured_with_camera_uuid",
             "user",
+            "organization_key",
+            "private",
             "project",
         ];
         this._propertiesKey = [
@@ -22826,11 +23264,10 @@ var APIv3 = /** @class */ (function () {
             hs,
             { from: 0, to: this._pageCount },
             this._propertiesKey
-                .concat(this._propertiesCore),
-            this._propertiesKey
+                .concat(this._propertiesCore)
         ]))
             .map(function (value) {
-            if (value == null) {
+            if (!value) {
                 value = { json: { imagesByH: {} } };
                 for (var _i = 0, hs_1 = hs; _i < hs_1.length; _i++) {
                     var h = hs_1[_i];
@@ -22868,6 +23305,16 @@ var APIv3 = /** @class */ (function () {
                 .concat(this._propertiesSequence)
         ]))
             .map(function (value) {
+            if (!value) {
+                value = { json: { sequenceByKey: {} } };
+            }
+            for (var _i = 0, sequenceKeys_1 = sequenceKeys; _i < sequenceKeys_1.length; _i++) {
+                var sequenceKey = sequenceKeys_1[_i];
+                if (!(sequenceKey in value.json.sequenceByKey)) {
+                    console.warn("Sequence data missing (" + sequenceKey + ")");
+                    value.json.sequenceByKey[sequenceKey] = { key: sequenceKey, keys: [] };
+                }
+            }
             return value.json.sequenceByKey;
         }), this._pathSequenceByKey, sequenceKeys);
     };
@@ -22911,7 +23358,7 @@ var APIv3 = /** @class */ (function () {
 exports.APIv3 = APIv3;
 exports.default = APIv3;
 
-},{"../API":280,"rxjs/Observable":29,"rxjs/add/observable/defer":39,"rxjs/add/observable/fromPromise":43,"rxjs/add/operator/catch":52,"rxjs/add/operator/map":65}],294:[function(require,module,exports){
+},{"../API":289,"rxjs/Observable":29}],303:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -22955,7 +23402,7 @@ var ModelCreator = /** @class */ (function () {
 exports.ModelCreator = ModelCreator;
 exports.default = ModelCreator;
 
-},{"../Utils":291,"falcor":15,"falcor-http-datasource":10}],295:[function(require,module,exports){
+},{"../Utils":300,"falcor":15,"falcor-http-datasource":10}],304:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -22970,7 +23417,9 @@ var __extends = (this && this.__extends) || (function () {
 })();
 Object.defineProperty(exports, "__esModule", { value: true });
 var vd = require("virtual-dom");
+var Observable_1 = require("rxjs/Observable");
 var Component_1 = require("../Component");
+var Utils_1 = require("../Utils");
 var AttributionComponent = /** @class */ (function (_super) {
     __extends(AttributionComponent, _super);
     function AttributionComponent(name, container, navigator) {
@@ -22978,9 +23427,14 @@ var AttributionComponent = /** @class */ (function (_super) {
     }
     AttributionComponent.prototype._activate = function () {
         var _this = this;
-        this._disposable = this._navigator.stateService.currentNode$
-            .map(function (node) {
-            return { name: _this._name, vnode: _this._getAttributionNode(node.username, node.key) };
+        this._disposable = Observable_1.Observable
+            .combineLatest(this._navigator.stateService.currentNode$, this._container.renderService.size$)
+            .map(function (_a) {
+            var node = _a[0], size = _a[1];
+            return {
+                name: _this._name,
+                vnode: _this._getAttributionNode(node.username, node.key, node.capturedAt, size.width),
+            };
         })
             .subscribe(this._container.domRenderer.render$);
     };
@@ -22990,18 +23444,22 @@ var AttributionComponent = /** @class */ (function (_super) {
     AttributionComponent.prototype._getDefaultConfiguration = function () {
         return {};
     };
-    AttributionComponent.prototype._getAttributionNode = function (username, key) {
-        return vd.h("div.Attribution", {}, [
-            vd.h("a", { href: "https://www.mapillary.com/app/user/" + username,
-                target: "_blank",
-                textContent: "@" + username,
-            }, []),
-            vd.h("span", { textContent: "|" }, []),
-            vd.h("a", { href: "https://www.mapillary.com/app/?pKey=" + key + "&focus=photo",
-                target: "_blank",
-                textContent: "mapillary.com",
-            }, []),
-        ]);
+    AttributionComponent.prototype._getAttributionNode = function (username, key, capturedAt, width) {
+        var compact = width <= 640;
+        var mapillaryIcon = vd.h("div.AttributionMapillaryLogo", []);
+        var mapillaryLink = vd.h("a.AttributionIconContainer", { href: Utils_1.Urls.explore, target: "_blank" }, [mapillaryIcon]);
+        var imageBy = compact ? "" + username : "image by " + username;
+        var imageByContent = vd.h("div.AttributionUsername", { textContent: imageBy }, []);
+        var date = new Date(capturedAt).toDateString().split(" ");
+        var formatted = (date.length > 3 ?
+            compact ?
+                [date[3]] :
+                [date[1], date[2] + ",", date[3]] :
+            date).join(" ");
+        var dateContent = vd.h("div.AttributionDate", { textContent: formatted }, []);
+        var imageLink = vd.h("a.AttributionImageContainer", { href: Utils_1.Urls.exporeImage(key), target: "_blank" }, [imageByContent, dateContent]);
+        var compactClass = compact ? ".AttributionCompact" : "";
+        return vd.h("div.AttributionContainer" + compactClass, {}, [mapillaryLink, imageLink]);
     };
     AttributionComponent.componentName = "attribution";
     return AttributionComponent;
@@ -23010,7 +23468,7 @@ exports.AttributionComponent = AttributionComponent;
 Component_1.ComponentService.register(AttributionComponent);
 exports.default = AttributionComponent;
 
-},{"../Component":281,"virtual-dom":237}],296:[function(require,module,exports){
+},{"../Component":290,"../Utils":300,"rxjs/Observable":29,"virtual-dom":246}],305:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -23054,7 +23512,7 @@ exports.BackgroundComponent = BackgroundComponent;
 Component_1.ComponentService.register(BackgroundComponent);
 exports.default = BackgroundComponent;
 
-},{"../Component":281,"virtual-dom":237}],297:[function(require,module,exports){
+},{"../Component":290,"virtual-dom":246}],306:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -23069,7 +23527,6 @@ var __extends = (this && this.__extends) || (function () {
 })();
 Object.defineProperty(exports, "__esModule", { value: true });
 var vd = require("virtual-dom");
-var Observable_1 = require("rxjs/Observable");
 var Component_1 = require("../Component");
 var Geo_1 = require("../Geo");
 var BearingComponent = /** @class */ (function (_super) {
@@ -23078,36 +23535,11 @@ var BearingComponent = /** @class */ (function (_super) {
         var _this = _super.call(this, name, container, navigator) || this;
         _this._spatial = new Geo_1.Spatial();
         _this._svgNamespace = "http://www.w3.org/2000/svg";
-        _this._distinctThreshold = Math.PI / 90;
+        _this._distinctThreshold = Math.PI / 360;
         return _this;
     }
     BearingComponent.prototype._activate = function () {
         var _this = this;
-        var nodeBearingFov$ = this._navigator.stateService.currentState$
-            .distinctUntilChanged(undefined, function (frame) {
-            return frame.state.currentNode.key;
-        })
-            .map(function (frame) {
-            var node = frame.state.currentNode;
-            var transform = frame.state.currentTransform;
-            if (node.pano) {
-                var panoHFov = 2 * Math.PI * node.gpano.CroppedAreaImageWidthPixels / node.gpano.FullPanoWidthPixels;
-                return [_this._spatial.degToRad(node.ca), panoHFov];
-            }
-            var size = Math.max(transform.basicWidth, transform.basicHeight);
-            if (size <= 0) {
-                console.warn("Original image size (" + transform.basicWidth + ", " + transform.basicHeight + ") is invalid (" + node.key + ". " +
-                    "Not showing available fov.");
-            }
-            var hFov = size > 0 ?
-                2 * Math.atan(0.5 * transform.basicWidth / (size * transform.focal)) :
-                0;
-            return [_this._spatial.degToRad(node.ca), hFov];
-        })
-            .distinctUntilChanged(function (a1, a2) {
-            return Math.abs(a2[0] - a1[0]) < _this._distinctThreshold &&
-                Math.abs(a2[1] - a1[1]) < _this._distinctThreshold;
-        });
         var cameraBearingFov$ = this._container.renderService.renderCamera$
             .map(function (rc) {
             var vFov = _this._spatial.degToRad(rc.perspective.fov);
@@ -23120,23 +23552,20 @@ var BearingComponent = /** @class */ (function (_super) {
             return Math.abs(a2[0] - a1[0]) < _this._distinctThreshold &&
                 Math.abs(a2[1] - a1[1]) < _this._distinctThreshold;
         });
-        this._renderSubscription = Observable_1.Observable
-            .combineLatest(nodeBearingFov$, cameraBearingFov$)
-            .map(function (args) {
-            var background = vd.h("div.BearingIndicatorBackground", { oncontextmenu: function (event) { event.preventDefault(); } }, [
-                vd.h("div.BearingIndicatorBackgroundRectangle", {}, []),
-                vd.h("div.BearingIndicatorBackgroundCircle", {}, []),
-            ]);
-            var north = vd.h("div.BearingIndicatorNorth", {}, []);
-            var nodeSector = _this._createCircleSector(args[0][0], args[0][1], "#000");
-            var cameraSector = _this._createCircleSector(args[1][0], args[1][1], "#fff");
-            var compass = _this._createCircleSectorCompass(nodeSector, cameraSector);
+        this._renderSubscription = cameraBearingFov$
+            .map(function (_a) {
+            var bearing = _a[0], fov = _a[1];
+            var background = vd.h("div.BearingIndicatorBackground", {}, []);
+            var backgroundCircle = vd.h("div.BearingIndicatorBackgroundCircle", {}, []);
+            var north = _this._createNorth(bearing);
+            var cameraSector = _this._createCircleSectorCompass(_this._createCircleSector(Math.max(Math.PI / 20, fov), "#FFF"));
             return {
                 name: _this._name,
-                vnode: vd.h("div.BearingIndicator", {}, [
+                vnode: vd.h("div.BearingIndicatorContainer", { oncontextmenu: function (event) { event.preventDefault(); } }, [
                     background,
+                    backgroundCircle,
                     north,
-                    compass,
+                    cameraSector,
                 ]),
             };
         })
@@ -23148,43 +23577,32 @@ var BearingComponent = /** @class */ (function (_super) {
     BearingComponent.prototype._getDefaultConfiguration = function () {
         return {};
     };
-    BearingComponent.prototype._createCircleSectorCompass = function (nodeSector, cameraSector) {
+    BearingComponent.prototype._createCircleSectorCompass = function (cameraSector) {
         var group = vd.h("g", {
             attributes: { transform: "translate(1,1)" },
             namespace: this._svgNamespace,
-        }, [nodeSector, cameraSector]);
-        var centerCircle = vd.h("circle", {
-            attributes: {
-                cx: "1",
-                cy: "1",
-                fill: "#abb1b9",
-                r: "0.291667",
-                stroke: "#000",
-                "stroke-width": "0.0833333",
-            },
-            namespace: this._svgNamespace,
-        }, []);
+        }, [cameraSector]);
         var svg = vd.h("svg", {
             attributes: { viewBox: "0 0 2 2" },
             namespace: this._svgNamespace,
             style: {
-                bottom: "4px",
-                height: "48px",
+                height: "30px",
                 left: "4px",
                 position: "absolute",
-                width: "48px",
+                top: "4px",
+                width: "30px",
             },
-        }, [group, centerCircle]);
+        }, [group]);
         return svg;
     };
-    BearingComponent.prototype._createCircleSector = function (bearing, fov, fill) {
+    BearingComponent.prototype._createCircleSector = function (fov, fill) {
         if (fov > 2 * Math.PI - Math.PI / 90) {
             return vd.h("circle", {
                 attributes: { cx: "0", cy: "0", fill: fill, r: "1" },
                 namespace: this._svgNamespace,
             }, []);
         }
-        var arcStart = bearing - fov / 2 - Math.PI / 2;
+        var arcStart = -Math.PI / 2 - fov / 2;
         var arcEnd = arcStart + fov;
         var startX = Math.cos(arcStart);
         var startY = Math.sin(arcStart);
@@ -23197,6 +23615,11 @@ var BearingComponent = /** @class */ (function (_super) {
             namespace: this._svgNamespace,
         }, []);
     };
+    BearingComponent.prototype._createNorth = function (bearing) {
+        var north = vd.h("div.BearingNorth", []);
+        var container = vd.h("div.BearingNorthContainer", { style: { transform: "rotateZ(" + -bearing * 180 / Math.PI + "deg)" } }, [north]);
+        return container;
+    };
     BearingComponent.componentName = "bearing";
     return BearingComponent;
 }(Component_1.Component));
@@ -23204,7 +23627,7 @@ exports.BearingComponent = BearingComponent;
 Component_1.ComponentService.register(BearingComponent);
 exports.default = BearingComponent;
 
-},{"../Component":281,"../Geo":284,"rxjs/Observable":29,"virtual-dom":237}],298:[function(require,module,exports){
+},{"../Component":290,"../Geo":293,"virtual-dom":246}],307:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -23218,22 +23641,6 @@ var __extends = (this && this.__extends) || (function () {
 })();
 Object.defineProperty(exports, "__esModule", { value: true });
 var Observable_1 = require("rxjs/Observable");
-require("rxjs/add/observable/combineLatest");
-require("rxjs/add/observable/from");
-require("rxjs/add/observable/merge");
-require("rxjs/add/observable/of");
-require("rxjs/add/observable/zip");
-require("rxjs/add/operator/catch");
-require("rxjs/add/operator/combineLatest");
-require("rxjs/add/operator/distinct");
-require("rxjs/add/operator/expand");
-require("rxjs/add/operator/filter");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/merge");
-require("rxjs/add/operator/mergeMap");
-require("rxjs/add/operator/mergeAll");
-require("rxjs/add/operator/skip");
-require("rxjs/add/operator/switchMap");
 var Edge_1 = require("../Edge");
 var Component_1 = require("../Component");
 var CacheComponent = /** @class */ (function (_super) {
@@ -23362,7 +23769,7 @@ exports.CacheComponent = CacheComponent;
 Component_1.ComponentService.register(CacheComponent);
 exports.default = CacheComponent;
 
-},{"../Component":281,"../Edge":282,"rxjs/Observable":29,"rxjs/add/observable/combineLatest":38,"rxjs/add/observable/from":41,"rxjs/add/observable/merge":44,"rxjs/add/observable/of":45,"rxjs/add/observable/zip":48,"rxjs/add/operator/catch":52,"rxjs/add/operator/combineLatest":53,"rxjs/add/operator/distinct":57,"rxjs/add/operator/expand":60,"rxjs/add/operator/filter":61,"rxjs/add/operator/map":65,"rxjs/add/operator/merge":66,"rxjs/add/operator/mergeAll":67,"rxjs/add/operator/mergeMap":68,"rxjs/add/operator/skip":77,"rxjs/add/operator/switchMap":81}],299:[function(require,module,exports){
+},{"../Component":290,"../Edge":291,"rxjs/Observable":29}],308:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -23377,9 +23784,6 @@ var __extends = (this && this.__extends) || (function () {
 Object.defineProperty(exports, "__esModule", { value: true });
 var BehaviorSubject_1 = require("rxjs/BehaviorSubject");
 var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/operator/publishReplay");
-require("rxjs/add/operator/scan");
-require("rxjs/add/operator/startWith");
 var Utils_1 = require("../Utils");
 var Component = /** @class */ (function (_super) {
     __extends(Component, _super);
@@ -23485,7 +23889,7 @@ var Component = /** @class */ (function (_super) {
 exports.Component = Component;
 exports.default = Component;
 
-},{"../Utils":291,"rxjs/BehaviorSubject":26,"rxjs/Subject":34,"rxjs/add/operator/publishReplay":72,"rxjs/add/operator/scan":75,"rxjs/add/operator/startWith":80}],300:[function(require,module,exports){
+},{"../Utils":300,"rxjs/BehaviorSubject":26,"rxjs/Subject":34}],309:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -23587,7 +23991,7 @@ var ComponentService = /** @class */ (function () {
 exports.ComponentService = ComponentService;
 exports.default = ComponentService;
 
-},{"../Error":283,"underscore":233}],301:[function(require,module,exports){
+},{"../Error":292,"underscore":242}],310:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -23602,10 +24006,10 @@ var __extends = (this && this.__extends) || (function () {
 })();
 Object.defineProperty(exports, "__esModule", { value: true });
 var vd = require("virtual-dom");
-require("rxjs/add/operator/filter");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/withLatestFrom");
+var Observable_1 = require("rxjs/Observable");
 var Component_1 = require("../Component");
+var Utils_1 = require("../Utils");
+var Viewer_1 = require("../Viewer");
 var CoverComponent = /** @class */ (function (_super) {
     __extends(CoverComponent, _super);
     function CoverComponent(name, container, navigator) {
@@ -23613,60 +24017,72 @@ var CoverComponent = /** @class */ (function (_super) {
     }
     CoverComponent.prototype._activate = function () {
         var _this = this;
-        this._keyDisposable = this._navigator.stateService.currentNode$
-            .withLatestFrom(this._configuration$, function (node, configuration) {
-            return [node, configuration];
+        this._configuration$
+            .distinctUntilChanged(undefined, function (configuration) {
+            return configuration.state;
         })
-            .filter(function (_a) {
-            var node = _a[0], configuration = _a[1];
-            return node.key !== configuration.key;
+            .switchMap(function (configuration) {
+            return Observable_1.Observable
+                .combineLatest(Observable_1.Observable.of(configuration.state), _this._navigator.stateService.currentNode$);
         })
-            .map(function (_a) {
-            var node = _a[0], configuration = _a[1];
-            return node;
+            .switchMap(function (_a) {
+            var state = _a[0], node = _a[1];
+            var keySrc$ = Observable_1.Observable
+                .combineLatest(Observable_1.Observable.of(node.key), node.image$
+                .map(function (image) {
+                return image.src;
+            }));
+            return state === Component_1.CoverState.Visible ? keySrc$.first() : keySrc$;
         })
-            .map(function (node) {
-            return { key: node.key, src: node.image.src };
+            .distinctUntilChanged(function (_a, _b) {
+            var k1 = _a[0], s1 = _a[1];
+            var k2 = _b[0], s2 = _b[1];
+            return k1 === k2 && s1 === s2;
+        })
+            .map(function (_a) {
+            var key = _a[0], src = _a[1];
+            return { key: key, src: src };
         })
             .subscribe(this._configurationSubject$);
-        this._disposable = this._configuration$
-            .map(function (conf) {
-            if (!conf.key) {
+        this._renderSubscription = Observable_1.Observable
+            .combineLatest(this._configuration$, this._container.renderService.size$)
+            .map(function (_a) {
+            var configuration = _a[0], size = _a[1];
+            if (!configuration.key) {
                 return { name: _this._name, vnode: vd.h("div", []) };
             }
-            if (conf.state === Component_1.CoverState.Hidden) {
-                return { name: _this._name, vnode: vd.h("div.Cover.CoverDone", [_this._getCoverBackgroundVNode(conf)]) };
+            var compactClass = size.width <= 640 || size.height <= 480 ? ".CoverCompact" : "";
+            if (configuration.state === Component_1.CoverState.Hidden) {
+                var doneContainer = vd.h("div.CoverContainer.CoverDone" + compactClass, [_this._getCoverBackgroundVNode(configuration)]);
+                return { name: _this._name, vnode: doneContainer };
             }
-            return { name: _this._name, vnode: _this._getCoverButtonVNode(conf) };
+            var container = vd.h("div.CoverContainer" + compactClass, [_this._getCoverButtonVNode(configuration)]);
+            return { name: _this._name, vnode: container };
         })
             .subscribe(this._container.domRenderer.render$);
     };
     CoverComponent.prototype._deactivate = function () {
-        this._disposable.unsubscribe();
-        this._keyDisposable.unsubscribe();
+        this._renderSubscription.unsubscribe();
+        this._keySubscription.unsubscribe();
     };
     CoverComponent.prototype._getDefaultConfiguration = function () {
         return { state: Component_1.CoverState.Visible };
     };
-    CoverComponent.prototype._getCoverButtonVNode = function (conf) {
+    CoverComponent.prototype._getCoverButtonVNode = function (configuration) {
         var _this = this;
-        var cover = conf.state === Component_1.CoverState.Loading ? "div.Cover.CoverLoading" : "div.Cover";
-        return vd.h(cover, [
-            this._getCoverBackgroundVNode(conf),
-            vd.h("button.CoverButton", { onclick: function () { _this.configure({ state: Component_1.CoverState.Loading }); } }, ["Explore"]),
-            vd.h("a.CoverLogo", { href: "https://www.mapillary.com", target: "_blank" }, []),
-        ]);
+        var cover = configuration.state === Component_1.CoverState.Loading ? "div.Cover.CoverLoading" : "div.Cover";
+        var coverButton = vd.h("div.CoverButton", { onclick: function () { _this.configure({ state: Component_1.CoverState.Loading }); } }, [vd.h("div.CoverButtonIcon", [])]);
+        var coverLogo = vd.h("a.CoverLogo", { href: Utils_1.Urls.explore, target: "_blank" }, []);
+        return vd.h(cover, [this._getCoverBackgroundVNode(configuration), coverButton, coverLogo]);
     };
     CoverComponent.prototype._getCoverBackgroundVNode = function (conf) {
         var url = conf.src != null ?
-            "url(" + conf.src + ")" :
-            "url(https://d1cuyjsrcm0gby.cloudfront.net/" + conf.key + "/thumb-640.jpg)";
-        var properties = { style: { backgroundImage: url } };
+            conf.src : Utils_1.Urls.thumbnail(conf.key, Viewer_1.ImageSize.Size640);
+        var properties = { style: { backgroundImage: "url(" + url + ")" } };
         var children = [];
         if (conf.state === Component_1.CoverState.Loading) {
             children.push(vd.h("div.Spinner", {}, []));
         }
-        children.push(vd.h("div.CoverBackgroundGradient", {}, []));
         return vd.h("div.CoverBackground", properties, children);
     };
     CoverComponent.componentName = "cover";
@@ -23676,7 +24092,7 @@ exports.CoverComponent = CoverComponent;
 Component_1.ComponentService.registerCover(CoverComponent);
 exports.default = CoverComponent;
 
-},{"../Component":281,"rxjs/add/operator/filter":61,"rxjs/add/operator/map":65,"rxjs/add/operator/withLatestFrom":87,"virtual-dom":237}],302:[function(require,module,exports){
+},{"../Component":290,"../Utils":300,"../Viewer":301,"rxjs/Observable":29,"virtual-dom":246}],311:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -23693,7 +24109,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
 var _ = require("underscore");
 var vd = require("virtual-dom");
 var BehaviorSubject_1 = require("rxjs/BehaviorSubject");
-require("rxjs/add/operator/combineLatest");
 var Component_1 = require("../Component");
 var DebugComponent = /** @class */ (function (_super) {
     __extends(DebugComponent, _super);
@@ -23789,7 +24204,7 @@ exports.DebugComponent = DebugComponent;
 Component_1.ComponentService.register(DebugComponent);
 exports.default = DebugComponent;
 
-},{"../Component":281,"rxjs/BehaviorSubject":26,"rxjs/add/operator/combineLatest":53,"underscore":233,"virtual-dom":237}],303:[function(require,module,exports){
+},{"../Component":290,"rxjs/BehaviorSubject":26,"underscore":242,"virtual-dom":246}],312:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -23805,7 +24220,6 @@ var __extends = (this && this.__extends) || (function () {
 Object.defineProperty(exports, "__esModule", { value: true });
 var vd = require("virtual-dom");
 var Observable_1 = require("rxjs/Observable");
-require("rxjs/add/operator/combineLatest");
 var Component_1 = require("../Component");
 var Utils_1 = require("../Utils");
 var ImageComponent = /** @class */ (function (_super) {
@@ -23862,7 +24276,7 @@ exports.ImageComponent = ImageComponent;
 Component_1.ComponentService.register(ImageComponent);
 exports.default = ImageComponent;
 
-},{"../Component":281,"../Utils":291,"rxjs/Observable":29,"rxjs/add/operator/combineLatest":53,"virtual-dom":237}],304:[function(require,module,exports){
+},{"../Component":290,"../Utils":300,"rxjs/Observable":29,"virtual-dom":246}],313:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -23879,7 +24293,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
 var _ = require("underscore");
 var vd = require("virtual-dom");
 var Observable_1 = require("rxjs/Observable");
-require("rxjs/add/operator/combineLatest");
 var Component_1 = require("../Component");
 var LoadingComponent = /** @class */ (function (_super) {
     __extends(LoadingComponent, _super);
@@ -23938,7 +24351,7 @@ exports.LoadingComponent = LoadingComponent;
 Component_1.ComponentService.register(LoadingComponent);
 exports.default = LoadingComponent;
 
-},{"../Component":281,"rxjs/Observable":29,"rxjs/add/operator/combineLatest":53,"underscore":233,"virtual-dom":237}],305:[function(require,module,exports){
+},{"../Component":290,"rxjs/Observable":29,"underscore":242,"virtual-dom":246}],314:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -23954,9 +24367,8 @@ var __extends = (this && this.__extends) || (function () {
 Object.defineProperty(exports, "__esModule", { value: true });
 var vd = require("virtual-dom");
 var Observable_1 = require("rxjs/Observable");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/first");
 var Edge_1 = require("../Edge");
+var Error_1 = require("../Error");
 var Component_1 = require("../Component");
 /**
  * @class NavigationComponent
@@ -24053,7 +24465,11 @@ var NavigationComponent = /** @class */ (function (_super) {
         return vd.h("span.Direction.Direction" + name, {
             onclick: function (ev) {
                 _this._navigator.moveDir$(direction)
-                    .subscribe(function (node) { return; }, function (error) { console.error(error); });
+                    .subscribe(undefined, function (error) {
+                    if (!(error instanceof Error_1.AbortMapillaryError)) {
+                        console.error(error);
+                    }
+                });
             },
             style: {
                 visibility: visibility,
@@ -24067,7 +24483,7 @@ exports.NavigationComponent = NavigationComponent;
 Component_1.ComponentService.register(NavigationComponent);
 exports.default = NavigationComponent;
 
-},{"../Component":281,"../Edge":282,"rxjs/Observable":29,"rxjs/add/operator/first":63,"rxjs/add/operator/map":65,"virtual-dom":237}],306:[function(require,module,exports){
+},{"../Component":290,"../Edge":291,"../Error":292,"rxjs/Observable":29,"virtual-dom":246}],315:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -24084,16 +24500,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
 var _ = require("underscore");
 var vd = require("virtual-dom");
 var Observable_1 = require("rxjs/Observable");
-require("rxjs/add/observable/fromPromise");
-require("rxjs/add/observable/of");
-require("rxjs/add/operator/combineLatest");
-require("rxjs/add/operator/distinct");
-require("rxjs/add/operator/distinctUntilChanged");
-require("rxjs/add/operator/filter");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/mergeMap");
-require("rxjs/add/operator/pluck");
-require("rxjs/add/operator/scan");
 var Component_1 = require("../Component");
 var DescriptionState = /** @class */ (function () {
     function DescriptionState() {
@@ -24287,7 +24693,7 @@ exports.RouteComponent = RouteComponent;
 Component_1.ComponentService.register(RouteComponent);
 exports.default = RouteComponent;
 
-},{"../Component":281,"rxjs/Observable":29,"rxjs/add/observable/fromPromise":43,"rxjs/add/observable/of":45,"rxjs/add/operator/combineLatest":53,"rxjs/add/operator/distinct":57,"rxjs/add/operator/distinctUntilChanged":58,"rxjs/add/operator/filter":61,"rxjs/add/operator/map":65,"rxjs/add/operator/mergeMap":68,"rxjs/add/operator/pluck":70,"rxjs/add/operator/scan":75,"underscore":233,"virtual-dom":237}],307:[function(require,module,exports){
+},{"../Component":290,"rxjs/Observable":29,"underscore":242,"virtual-dom":246}],316:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -24301,11 +24707,6 @@ var __extends = (this && this.__extends) || (function () {
 })();
 Object.defineProperty(exports, "__esModule", { value: true });
 var Observable_1 = require("rxjs/Observable");
-require("rxjs/add/operator/buffer");
-require("rxjs/add/operator/debounceTime");
-require("rxjs/add/operator/filter");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/scan");
 var Component_1 = require("../Component");
 var StatsComponent = /** @class */ (function (_super) {
     __extends(StatsComponent, _super);
@@ -24377,7 +24778,7 @@ exports.StatsComponent = StatsComponent;
 Component_1.ComponentService.register(StatsComponent);
 exports.default = StatsComponent;
 
-},{"../Component":281,"rxjs/Observable":29,"rxjs/add/operator/buffer":49,"rxjs/add/operator/debounceTime":55,"rxjs/add/operator/filter":61,"rxjs/add/operator/map":65,"rxjs/add/operator/scan":75}],308:[function(require,module,exports){
+},{"../Component":290,"rxjs/Observable":29}],317:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -24394,12 +24795,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
 var vd = require("virtual-dom");
 var Observable_1 = require("rxjs/Observable");
 var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/observable/combineLatest");
-require("rxjs/add/operator/do");
-require("rxjs/add/operator/distinctUntilChanged");
-require("rxjs/add/operator/filter");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/share");
 var Component_1 = require("../../Component");
 /**
  * @class DirectionComponent
@@ -24563,7 +24958,7 @@ exports.DirectionComponent = DirectionComponent;
 Component_1.ComponentService.register(DirectionComponent);
 exports.default = DirectionComponent;
 
-},{"../../Component":281,"rxjs/Observable":29,"rxjs/Subject":34,"rxjs/add/observable/combineLatest":38,"rxjs/add/operator/distinctUntilChanged":58,"rxjs/add/operator/do":59,"rxjs/add/operator/filter":61,"rxjs/add/operator/map":65,"rxjs/add/operator/share":76,"virtual-dom":237}],309:[function(require,module,exports){
+},{"../../Component":290,"rxjs/Observable":29,"rxjs/Subject":34,"virtual-dom":246}],318:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Geo_1 = require("../../Geo");
@@ -24802,13 +25197,14 @@ var DirectionDOMCalculator = /** @class */ (function () {
 exports.DirectionDOMCalculator = DirectionDOMCalculator;
 exports.default = DirectionDOMCalculator;
 
-},{"../../Geo":284}],310:[function(require,module,exports){
+},{"../../Geo":293}],319:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
 var vd = require("virtual-dom");
 var Component_1 = require("../../Component");
 var Edge_1 = require("../../Edge");
+var Error_1 = require("../../Error");
 var Geo_1 = require("../../Geo");
 /**
  * @class DirectionDOMRenderer
@@ -25049,21 +25445,33 @@ var DirectionDOMRenderer = /** @class */ (function () {
     DirectionDOMRenderer.prototype._createVNodeByKey = function (navigator, key, azimuth, rotation, offset, className, shiftVertically) {
         var onClick = function (e) {
             navigator.moveToKey$(key)
-                .subscribe(function (node) { return; }, function (error) { console.error(error); });
+                .subscribe(undefined, function (error) {
+                if (!(error instanceof Error_1.AbortMapillaryError)) {
+                    console.error(error);
+                }
+            });
         };
         return this._createVNode(key, azimuth, rotation, offset, className, "DirectionsCircle", onClick, shiftVertically);
     };
     DirectionDOMRenderer.prototype._createVNodeByDirection = function (navigator, key, azimuth, rotation, direction) {
         var onClick = function (e) {
             navigator.moveDir$(direction)
-                .subscribe(function (node) { return; }, function (error) { console.error(error); });
+                .subscribe(undefined, function (error) {
+                if (!(error instanceof Error_1.AbortMapillaryError)) {
+                    console.error(error);
+                }
+            });
         };
         return this._createVNode(key, azimuth, rotation, this._calculator.outerRadius, "DirectionsArrowStep", "DirectionsCircle", onClick);
     };
     DirectionDOMRenderer.prototype._createVNodeByTurn = function (navigator, key, className, direction) {
         var onClick = function (e) {
             navigator.moveDir$(direction)
-                .subscribe(function (node) { return; }, function (error) { console.error(error); });
+                .subscribe(undefined, function (error) {
+                if (!(error instanceof Error_1.AbortMapillaryError)) {
+                    console.error(error);
+                }
+            });
         };
         var style = {
             height: this._calculator.turnCircleSizeCss,
@@ -25169,7 +25577,7 @@ var DirectionDOMRenderer = /** @class */ (function () {
 exports.DirectionDOMRenderer = DirectionDOMRenderer;
 exports.default = DirectionDOMRenderer;
 
-},{"../../Component":281,"../../Edge":282,"../../Geo":284,"virtual-dom":237}],311:[function(require,module,exports){
+},{"../../Component":290,"../../Edge":291,"../../Error":292,"../../Geo":293,"virtual-dom":246}],320:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -25184,21 +25592,6 @@ var __extends = (this && this.__extends) || (function () {
 Object.defineProperty(exports, "__esModule", { value: true });
 var Observable_1 = require("rxjs/Observable");
 var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/operator/catch");
-require("rxjs/add/operator/combineLatest");
-require("rxjs/add/operator/debounceTime");
-require("rxjs/add/operator/distinctUntilChanged");
-require("rxjs/add/operator/filter");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/pairwise");
-require("rxjs/add/operator/publish");
-require("rxjs/add/operator/publishReplay");
-require("rxjs/add/operator/scan");
-require("rxjs/add/operator/skipWhile");
-require("rxjs/add/operator/startWith");
-require("rxjs/add/operator/switchMap");
-require("rxjs/add/operator/takeUntil");
-require("rxjs/add/operator/withLatestFrom");
 var Component_1 = require("../../Component");
 var Render_1 = require("../../Render");
 var Tiles_1 = require("../../Tiles");
@@ -25466,244 +25859,15 @@ exports.ImagePlaneComponent = ImagePlaneComponent;
 Component_1.ComponentService.register(ImagePlaneComponent);
 exports.default = ImagePlaneComponent;
 
-},{"../../Component":281,"../../Render":287,"../../Tiles":290,"../../Utils":291,"rxjs/Observable":29,"rxjs/Subject":34,"rxjs/add/operator/catch":52,"rxjs/add/operator/combineLatest":53,"rxjs/add/operator/debounceTime":55,"rxjs/add/operator/distinctUntilChanged":58,"rxjs/add/operator/filter":61,"rxjs/add/operator/map":65,"rxjs/add/operator/pairwise":69,"rxjs/add/operator/publish":71,"rxjs/add/operator/publishReplay":72,"rxjs/add/operator/scan":75,"rxjs/add/operator/skipWhile":79,"rxjs/add/operator/startWith":80,"rxjs/add/operator/switchMap":81,"rxjs/add/operator/takeUntil":83,"rxjs/add/operator/withLatestFrom":87}],312:[function(require,module,exports){
-"use strict";
-/// <reference path="../../../typings/index.d.ts" />
-Object.defineProperty(exports, "__esModule", { value: true });
-var THREE = require("three");
-var Component_1 = require("../../Component");
-var ImagePlaneFactory = /** @class */ (function () {
-    function ImagePlaneFactory(imagePlaneDepth, imageSphereRadius) {
-        this._imagePlaneDepth = imagePlaneDepth != null ? imagePlaneDepth : 200;
-        this._imageSphereRadius = imageSphereRadius != null ? imageSphereRadius : 200;
-    }
-    ImagePlaneFactory.prototype.createMesh = function (node, transform) {
-        var mesh = node.pano ?
-            this._createImageSphere(node, transform) :
-            this._createImagePlane(node, transform);
-        return mesh;
-    };
-    ImagePlaneFactory.prototype._createImageSphere = function (node, transform) {
-        var texture = this._createTexture(node.image);
-        var materialParameters = this._createSphereMaterialParameters(transform, texture);
-        var material = new THREE.ShaderMaterial(materialParameters);
-        var mesh = this._useMesh(transform, node) ?
-            new THREE.Mesh(this._getImageSphereGeo(transform, node), material) :
-            new THREE.Mesh(this._getFlatImageSphereGeo(transform), material);
-        return mesh;
-    };
-    ImagePlaneFactory.prototype._createImagePlane = function (node, transform) {
-        var texture = this._createTexture(node.image);
-        var materialParameters = this._createPlaneMaterialParameters(transform, texture);
-        var material = new THREE.ShaderMaterial(materialParameters);
-        var geometry = this._useMesh(transform, node) ?
-            this._getImagePlaneGeo(transform, node) :
-            this._getFlatImagePlaneGeo(transform);
-        return new THREE.Mesh(geometry, material);
-    };
-    ImagePlaneFactory.prototype._createSphereMaterialParameters = function (transform, texture) {
-        var gpano = transform.gpano;
-        var halfCroppedWidth = (gpano.FullPanoWidthPixels - gpano.CroppedAreaImageWidthPixels) / 2;
-        var phiShift = 2 * Math.PI * (gpano.CroppedAreaLeftPixels - halfCroppedWidth) / gpano.FullPanoWidthPixels;
-        var phiLength = 2 * Math.PI * gpano.CroppedAreaImageWidthPixels / gpano.FullPanoWidthPixels;
-        var halfCroppedHeight = (gpano.FullPanoHeightPixels - gpano.CroppedAreaImageHeightPixels) / 2;
-        var thetaShift = Math.PI * (halfCroppedHeight - gpano.CroppedAreaTopPixels) / gpano.FullPanoHeightPixels;
-        var thetaLength = Math.PI * gpano.CroppedAreaImageHeightPixels / gpano.FullPanoHeightPixels;
-        var materialParameters = {
-            depthWrite: false,
-            fragmentShader: Component_1.ImagePlaneShaders.equirectangular.fragment,
-            side: THREE.DoubleSide,
-            transparent: true,
-            uniforms: {
-                opacity: {
-                    type: "f",
-                    value: 1,
-                },
-                phiLength: {
-                    type: "f",
-                    value: phiLength,
-                },
-                phiShift: {
-                    type: "f",
-                    value: phiShift,
-                },
-                projectorMat: {
-                    type: "m4",
-                    value: transform.rt,
-                },
-                projectorTex: {
-                    type: "t",
-                    value: texture,
-                },
-                thetaLength: {
-                    type: "f",
-                    value: thetaLength,
-                },
-                thetaShift: {
-                    type: "f",
-                    value: thetaShift,
-                },
-            },
-            vertexShader: Component_1.ImagePlaneShaders.equirectangular.vertex,
-        };
-        return materialParameters;
-    };
-    ImagePlaneFactory.prototype._createPlaneMaterialParameters = function (transform, texture) {
-        var materialParameters = {
-            depthWrite: false,
-            fragmentShader: Component_1.ImagePlaneShaders.perspective.fragment,
-            side: THREE.DoubleSide,
-            transparent: true,
-            uniforms: {
-                bbox: {
-                    type: "v4",
-                    value: new THREE.Vector4(0, 0, 1, 1),
-                },
-                opacity: {
-                    type: "f",
-                    value: 1,
-                },
-                projectorMat: {
-                    type: "m4",
-                    value: transform.projectorMatrix(),
-                },
-                projectorTex: {
-                    type: "t",
-                    value: texture,
-                },
-            },
-            vertexShader: Component_1.ImagePlaneShaders.perspective.vertex,
-        };
-        return materialParameters;
-    };
-    ImagePlaneFactory.prototype._createTexture = function (image) {
-        var texture = new THREE.Texture(image);
-        texture.minFilter = THREE.LinearFilter;
-        texture.needsUpdate = true;
-        return texture;
-    };
-    ImagePlaneFactory.prototype._useMesh = function (transform, node) {
-        return node.mesh.vertices.length && transform.hasValidScale;
-    };
-    ImagePlaneFactory.prototype._getImageSphereGeo = function (transform, node) {
-        var t = new THREE.Matrix4().getInverse(transform.srt);
-        // push everything at least 5 meters in front of the camera
-        var minZ = 5.0 * transform.scale;
-        var maxZ = this._imageSphereRadius * transform.scale;
-        var vertices = node.mesh.vertices;
-        var numVertices = vertices.length / 3;
-        var positions = new Float32Array(vertices.length);
-        for (var i = 0; i < numVertices; ++i) {
-            var index = 3 * i;
-            var x = vertices[index + 0];
-            var y = vertices[index + 1];
-            var z = vertices[index + 2];
-            var l = Math.sqrt(x * x + y * y + z * z);
-            var boundedL = Math.max(minZ, Math.min(l, maxZ));
-            var factor = boundedL / l;
-            var p = new THREE.Vector3(x * factor, y * factor, z * factor);
-            p.applyMatrix4(t);
-            positions[index + 0] = p.x;
-            positions[index + 1] = p.y;
-            positions[index + 2] = p.z;
-        }
-        var faces = node.mesh.faces;
-        var indices = new Uint16Array(faces.length);
-        for (var i = 0; i < faces.length; ++i) {
-            indices[i] = faces[i];
-        }
-        var geometry = new THREE.BufferGeometry();
-        geometry.addAttribute("position", new THREE.BufferAttribute(positions, 3));
-        geometry.setIndex(new THREE.BufferAttribute(indices, 1));
-        return geometry;
-    };
-    ImagePlaneFactory.prototype._getImagePlaneGeo = function (transform, node) {
-        var t = new THREE.Matrix4().getInverse(transform.srt);
-        // push everything at least 5 meters in front of the camera
-        var minZ = 5.0 * transform.scale;
-        var maxZ = this._imagePlaneDepth * transform.scale;
-        var vertices = node.mesh.vertices;
-        var numVertices = vertices.length / 3;
-        var positions = new Float32Array(vertices.length);
-        for (var i = 0; i < numVertices; ++i) {
-            var index = 3 * i;
-            var x = vertices[index + 0];
-            var y = vertices[index + 1];
-            var z = vertices[index + 2];
-            var boundedZ = Math.max(minZ, Math.min(z, maxZ));
-            var factor = boundedZ / z;
-            var p = new THREE.Vector3(x * factor, y * factor, boundedZ);
-            p.applyMatrix4(t);
-            positions[index + 0] = p.x;
-            positions[index + 1] = p.y;
-            positions[index + 2] = p.z;
-        }
-        var faces = node.mesh.faces;
-        var indices = new Uint16Array(faces.length);
-        for (var i = 0; i < faces.length; ++i) {
-            indices[i] = faces[i];
-        }
-        var geometry = new THREE.BufferGeometry();
-        geometry.addAttribute("position", new THREE.BufferAttribute(positions, 3));
-        geometry.setIndex(new THREE.BufferAttribute(indices, 1));
-        return geometry;
-    };
-    ImagePlaneFactory.prototype._getFlatImageSphereGeo = function (transform) {
-        var gpano = transform.gpano;
-        var phiStart = 2 * Math.PI * gpano.CroppedAreaLeftPixels / gpano.FullPanoWidthPixels;
-        var phiLength = 2 * Math.PI * gpano.CroppedAreaImageWidthPixels / gpano.FullPanoWidthPixels;
-        var thetaStart = Math.PI *
-            (gpano.FullPanoHeightPixels - gpano.CroppedAreaImageHeightPixels - gpano.CroppedAreaTopPixels) /
-            gpano.FullPanoHeightPixels;
-        var thetaLength = Math.PI * gpano.CroppedAreaImageHeightPixels / gpano.FullPanoHeightPixels;
-        var geometry = new THREE.SphereGeometry(this._imageSphereRadius, 20, 40, phiStart - Math.PI / 2, phiLength, thetaStart, thetaLength);
-        geometry.applyMatrix(new THREE.Matrix4().getInverse(transform.rt));
-        return geometry;
-    };
-    ImagePlaneFactory.prototype._getFlatImagePlaneGeo = function (transform) {
-        var width = transform.width;
-        var height = transform.height;
-        var size = Math.max(width, height);
-        var dx = width / 2.0 / size;
-        var dy = height / 2.0 / size;
-        var vertices = [];
-        vertices.push(transform.unprojectSfM([-dx, -dy], this._imagePlaneDepth));
-        vertices.push(transform.unprojectSfM([dx, -dy], this._imagePlaneDepth));
-        vertices.push(transform.unprojectSfM([dx, dy], this._imagePlaneDepth));
-        vertices.push(transform.unprojectSfM([-dx, dy], this._imagePlaneDepth));
-        var positions = new Float32Array(12);
-        for (var i = 0; i < vertices.length; i++) {
-            var index = 3 * i;
-            positions[index + 0] = vertices[i][0];
-            positions[index + 1] = vertices[i][1];
-            positions[index + 2] = vertices[i][2];
-        }
-        var indices = new Uint16Array(6);
-        indices[0] = 0;
-        indices[1] = 1;
-        indices[2] = 3;
-        indices[3] = 1;
-        indices[4] = 2;
-        indices[5] = 3;
-        var geometry = new THREE.BufferGeometry();
-        geometry.addAttribute("position", new THREE.BufferAttribute(positions, 3));
-        geometry.setIndex(new THREE.BufferAttribute(indices, 1));
-        return geometry;
-    };
-    return ImagePlaneFactory;
-}());
-exports.ImagePlaneFactory = ImagePlaneFactory;
-exports.default = ImagePlaneFactory;
-
-},{"../../Component":281,"three":231}],313:[function(require,module,exports){
+},{"../../Component":290,"../../Render":296,"../../Tiles":299,"../../Utils":300,"rxjs/Observable":29,"rxjs/Subject":34}],321:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
 var Component_1 = require("../../Component");
 var ImagePlaneGLRenderer = /** @class */ (function () {
     function ImagePlaneGLRenderer() {
-        this._imagePlaneFactory = new Component_1.ImagePlaneFactory();
-        this._imagePlaneScene = new Component_1.ImagePlaneScene();
+        this._factory = new Component_1.MeshFactory();
+        this._scene = new Component_1.MeshScene();
         this._alpha = 0;
         this._alphaOld = 0;
         this._fadeOutSpeed = 0.05;
@@ -25763,7 +25927,7 @@ var ImagePlaneGLRenderer = /** @class */ (function () {
     };
     ImagePlaneGLRenderer.prototype._updateTexture = function (texture) {
         this._needsRender = true;
-        for (var _i = 0, _a = this._imagePlaneScene.imagePlanes; _i < _a.length; _i++) {
+        for (var _i = 0, _a = this._scene.imagePlanes; _i < _a.length; _i++) {
             var plane = _a[_i];
             var material = plane.material;
             var oldTexture = material.uniforms.projectorTex.value;
@@ -25777,7 +25941,7 @@ var ImagePlaneGLRenderer = /** @class */ (function () {
             return;
         }
         this._needsRender = true;
-        for (var _i = 0, _a = this._imagePlaneScene.imagePlanes; _i < _a.length; _i++) {
+        for (var _i = 0, _a = this._scene.imagePlanes; _i < _a.length; _i++) {
             var plane = _a[_i];
             var material = plane.material;
             var texture = material.uniforms.projectorTex.value;
@@ -25786,28 +25950,28 @@ var ImagePlaneGLRenderer = /** @class */ (function () {
         }
     };
     ImagePlaneGLRenderer.prototype.render = function (perspectiveCamera, renderer) {
-        var planeAlpha = this._imagePlaneScene.imagePlanesOld.length ? 1 : this._alpha;
-        for (var _i = 0, _a = this._imagePlaneScene.imagePlanes; _i < _a.length; _i++) {
+        var planeAlpha = this._scene.imagePlanesOld.length ? 1 : this._alpha;
+        for (var _i = 0, _a = this._scene.imagePlanes; _i < _a.length; _i++) {
             var plane = _a[_i];
             plane.material.uniforms.opacity.value = planeAlpha;
         }
-        for (var _b = 0, _c = this._imagePlaneScene.imagePlanesOld; _b < _c.length; _b++) {
+        for (var _b = 0, _c = this._scene.imagePlanesOld; _b < _c.length; _b++) {
             var plane = _c[_b];
             plane.material.uniforms.opacity.value = this._alphaOld;
         }
-        renderer.render(this._imagePlaneScene.scene, perspectiveCamera);
-        renderer.render(this._imagePlaneScene.sceneOld, perspectiveCamera);
-        for (var _d = 0, _e = this._imagePlaneScene.imagePlanes; _d < _e.length; _d++) {
+        renderer.render(this._scene.scene, perspectiveCamera);
+        renderer.render(this._scene.sceneOld, perspectiveCamera);
+        for (var _d = 0, _e = this._scene.imagePlanes; _d < _e.length; _d++) {
             var plane = _e[_d];
             plane.material.uniforms.opacity.value = this._alpha;
         }
-        renderer.render(this._imagePlaneScene.scene, perspectiveCamera);
+        renderer.render(this._scene.scene, perspectiveCamera);
     };
     ImagePlaneGLRenderer.prototype.clearNeedsRender = function () {
         this._needsRender = false;
     };
     ImagePlaneGLRenderer.prototype.dispose = function () {
-        this._imagePlaneScene.clear();
+        this._scene.clear();
     };
     ImagePlaneGLRenderer.prototype._updateFrameId = function (frameId) {
         this._frameId = frameId;
@@ -25841,14 +26005,14 @@ var ImagePlaneGLRenderer = /** @class */ (function () {
         }
         if (previousKey != null) {
             if (previousKey !== this._currentKey && previousKey !== this._previousKey) {
-                var previousMesh = this._imagePlaneFactory.createMesh(state.previousNode, state.previousTransform);
-                this._imagePlaneScene.updateImagePlanes([previousMesh]);
+                var previousMesh = this._factory.createMesh(state.previousNode, state.previousTransform);
+                this._scene.updateImagePlanes([previousMesh]);
             }
             this._previousKey = previousKey;
         }
         this._currentKey = currentKey;
-        var currentMesh = this._imagePlaneFactory.createMesh(state.currentNode, state.currentTransform);
-        this._imagePlaneScene.updateImagePlanes([currentMesh]);
+        var currentMesh = this._factory.createMesh(state.currentNode, state.currentTransform);
+        this._scene.updateImagePlanes([currentMesh]);
         this._alphaOld = 1;
         return true;
     };
@@ -25857,565 +26021,65 @@ var ImagePlaneGLRenderer = /** @class */ (function () {
 exports.ImagePlaneGLRenderer = ImagePlaneGLRenderer;
 exports.default = ImagePlaneGLRenderer;
 
-},{"../../Component":281}],314:[function(require,module,exports){
+},{"../../Component":290}],322:[function(require,module,exports){
 "use strict";
-/// <reference path="../../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
-var THREE = require("three");
-var ImagePlaneScene = /** @class */ (function () {
-    function ImagePlaneScene() {
-        this.scene = new THREE.Scene();
-        this.sceneOld = new THREE.Scene();
-        this.imagePlanes = [];
-        this.imagePlanesOld = [];
-    }
-    ImagePlaneScene.prototype.updateImagePlanes = function (planes) {
-        this._dispose(this.imagePlanesOld, this.sceneOld);
-        for (var _i = 0, _a = this.imagePlanes; _i < _a.length; _i++) {
-            var plane = _a[_i];
-            this.scene.remove(plane);
-            this.sceneOld.add(plane);
-        }
-        for (var _b = 0, planes_1 = planes; _b < planes_1.length; _b++) {
-            var plane = planes_1[_b];
-            this.scene.add(plane);
-        }
-        this.imagePlanesOld = this.imagePlanes;
-        this.imagePlanes = planes;
-    };
-    ImagePlaneScene.prototype.addImagePlanes = function (planes) {
-        for (var _i = 0, planes_2 = planes; _i < planes_2.length; _i++) {
-            var plane = planes_2[_i];
-            this.scene.add(plane);
-            this.imagePlanes.push(plane);
-        }
-    };
-    ImagePlaneScene.prototype.addImagePlanesOld = function (planes) {
-        for (var _i = 0, planes_3 = planes; _i < planes_3.length; _i++) {
-            var plane = planes_3[_i];
-            this.sceneOld.add(plane);
-            this.imagePlanesOld.push(plane);
-        }
-    };
-    ImagePlaneScene.prototype.setImagePlanes = function (planes) {
-        this._clear();
-        this.addImagePlanes(planes);
-    };
-    ImagePlaneScene.prototype.setImagePlanesOld = function (planes) {
-        this._clearOld();
-        this.addImagePlanesOld(planes);
-    };
-    ImagePlaneScene.prototype.clear = function () {
-        this._clear();
-        this._clearOld();
-    };
-    ImagePlaneScene.prototype._clear = function () {
-        this._dispose(this.imagePlanes, this.scene);
-        this.imagePlanes.length = 0;
-    };
-    ImagePlaneScene.prototype._clearOld = function () {
-        this._dispose(this.imagePlanesOld, this.sceneOld);
-        this.imagePlanesOld.length = 0;
-    };
-    ImagePlaneScene.prototype._dispose = function (planes, scene) {
-        for (var _i = 0, planes_4 = planes; _i < planes_4.length; _i++) {
-            var plane = planes_4[_i];
-            scene.remove(plane);
-            plane.geometry.dispose();
-            plane.material.dispose();
-            var texture = plane.material.uniforms.projectorTex.value;
-            if (texture != null) {
-                texture.dispose();
-            }
-        }
-    };
-    return ImagePlaneScene;
-}());
-exports.ImagePlaneScene = ImagePlaneScene;
-exports.default = ImagePlaneScene;
-
-},{"three":231}],315:[function(require,module,exports){
-"use strict";
-/// <reference path="../../../typings/index.d.ts" />
-Object.defineProperty(exports, "__esModule", { value: true });
-
-var path = require("path");
-var ImagePlaneShaders = /** @class */ (function () {
-    function ImagePlaneShaders() {
-    }
-    ImagePlaneShaders.equirectangular = {
-        fragment: "#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n\nuniform sampler2D projectorTex;\nuniform float opacity;\nuniform float phiLength;\nuniform float phiShift;\nuniform float thetaLength;\nuniform float thetaShift;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n    vec3 b = normalize(vRstq.xyz);\n    float lat = -asin(b.y);\n    float lon = atan(b.x, b.z);\n    float x = (lon - phiShift) / phiLength + 0.5;\n    float y = (lat - thetaShift) / thetaLength + 0.5;\n    vec4 baseColor = texture2D(projectorTex, vec2(x, y));\n    baseColor.a = opacity;\n    gl_FragColor = baseColor;\n}",
-        vertex: "#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform mat4 projectorMat;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n    vRstq = projectorMat * vec4(position, 1.0);\n    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}",
-    };
-    ImagePlaneShaders.perspective = {
-        fragment: "#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n\nuniform sampler2D projectorTex;\nuniform float opacity;\nuniform vec4 bbox;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n    float x = vRstq.x / vRstq.w;\n    float y = vRstq.y / vRstq.w;\n\n    vec4 baseColor;\n    if (x > bbox[0] && y > bbox[1] && x < bbox[2] && y < bbox[3]) {\n        baseColor = texture2D(projectorTex, vec2(x, y));\n        baseColor.a = opacity;\n    } else {\n        baseColor = vec4(0.0, 0.0, 0.0, 0.0);\n    }\n\n    gl_FragColor = baseColor;\n}",
-        vertex: "#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform mat4 projectorMat;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n    vRstq = projectorMat * vec4(position, 1.0);\n    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}",
-    };
-    return ImagePlaneShaders;
-}());
-exports.ImagePlaneShaders = ImagePlaneShaders;
+var CoverState;
+(function (CoverState) {
+    CoverState[CoverState["Hidden"] = 0] = "Hidden";
+    CoverState[CoverState["Loading"] = 1] = "Loading";
+    CoverState[CoverState["Visible"] = 2] = "Visible";
+})(CoverState = exports.CoverState || (exports.CoverState = {}));
 
-},{"path":22}],316:[function(require,module,exports){
+},{}],323:[function(require,module,exports){
 "use strict";
-/// <reference path="../../../typings/index.d.ts" />
-var __extends = (this && this.__extends) || (function () {
-    var extendStatics = Object.setPrototypeOf ||
-        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
-    return function (d, b) {
-        extendStatics(d, b);
-        function __() { this.constructor = d; }
-        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-    };
-})();
 Object.defineProperty(exports, "__esModule", { value: true });
-var Observable_1 = require("rxjs/Observable");
-var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/observable/combineLatest");
-require("rxjs/add/observable/fromEvent");
-require("rxjs/add/observable/of");
-require("rxjs/add/observable/zip");
-require("rxjs/add/operator/distinctUntilChanged");
-require("rxjs/add/operator/filter");
-require("rxjs/add/operator/first");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/merge");
-require("rxjs/add/operator/mergeMap");
-require("rxjs/add/operator/scan");
-require("rxjs/add/operator/switchMap");
-require("rxjs/add/operator/withLatestFrom");
-require("rxjs/add/operator/zip");
-var State_1 = require("../../State");
-var Render_1 = require("../../Render");
-var Utils_1 = require("../../Utils");
-var Component_1 = require("../../Component");
-var SliderState = /** @class */ (function () {
-    function SliderState() {
-        this._imagePlaneFactory = new Component_1.ImagePlaneFactory();
-        this._imagePlaneScene = new Component_1.ImagePlaneScene();
-        this._currentKey = null;
-        this._previousKey = null;
-        this._currentPano = false;
-        this._frameId = 0;
-        this._glNeedsRender = false;
-        this._domNeedsRender = true;
-        this._curtain = 1;
-    }
-    Object.defineProperty(SliderState.prototype, "frameId", {
-        get: function () {
-            return this._frameId;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    Object.defineProperty(SliderState.prototype, "curtain", {
-        get: function () {
-            return this._curtain;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    Object.defineProperty(SliderState.prototype, "glNeedsRender", {
-        get: function () {
-            return this._glNeedsRender;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    Object.defineProperty(SliderState.prototype, "domNeedsRender", {
-        get: function () {
-            return this._domNeedsRender;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    Object.defineProperty(SliderState.prototype, "sliderVisible", {
-        get: function () {
-            return this._sliderVisible;
-        },
-        set: function (value) {
-            this._sliderVisible = value;
-            this._domNeedsRender = true;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    Object.defineProperty(SliderState.prototype, "disabled", {
-        get: function () {
-            return this._currentKey == null ||
-                this._previousKey == null ||
-                this._currentPano;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    SliderState.prototype.update = function (frame) {
-        this._updateFrameId(frame.id);
-        var needsRender = this._updateImagePlanes(frame.state);
-        this._domNeedsRender = needsRender || this._domNeedsRender;
-        needsRender = this._updateCurtain(frame.state.alpha) || needsRender;
-        this._glNeedsRender = needsRender || this._glNeedsRender;
-    };
-    SliderState.prototype.updateTexture = function (image, node) {
-        var imagePlanes = node.key === this._currentKey ?
-            this._imagePlaneScene.imagePlanes :
-            node.key === this._previousKey ?
-                this._imagePlaneScene.imagePlanesOld :
-                [];
-        if (imagePlanes.length === 0) {
-            return;
-        }
-        this._glNeedsRender = true;
-        for (var _i = 0, imagePlanes_1 = imagePlanes; _i < imagePlanes_1.length; _i++) {
-            var plane = imagePlanes_1[_i];
-            var material = plane.material;
-            var texture = material.uniforms.projectorTex.value;
-            texture.image = image;
-            texture.needsUpdate = true;
-        }
-    };
-    SliderState.prototype.render = function (perspectiveCamera, renderer) {
-        if (!this.disabled) {
-            renderer.render(this._imagePlaneScene.sceneOld, perspectiveCamera);
-        }
-        renderer.render(this._imagePlaneScene.scene, perspectiveCamera);
-    };
-    SliderState.prototype.dispose = function () {
-        this._imagePlaneScene.clear();
-    };
-    SliderState.prototype.clearGLNeedsRender = function () {
-        this._glNeedsRender = false;
-    };
-    SliderState.prototype.clearDomNeedsRender = function () {
-        this._domNeedsRender = false;
-    };
-    SliderState.prototype._updateFrameId = function (frameId) {
-        this._frameId = frameId;
-    };
-    SliderState.prototype._updateImagePlanes = function (state) {
-        if (state.currentNode == null) {
-            return;
-        }
-        var needsRender = false;
-        if (state.previousNode != null && this._previousKey !== state.previousNode.key) {
-            needsRender = true;
-            this._previousKey = state.previousNode.key;
-            this._imagePlaneScene.setImagePlanesOld([
-                this._imagePlaneFactory.createMesh(state.previousNode, state.previousTransform),
-            ]);
-        }
-        if (this._currentKey !== state.currentNode.key) {
-            needsRender = true;
-            this._currentKey = state.currentNode.key;
-            this._currentPano = state.currentNode.pano;
-            this._imagePlaneScene.setImagePlanes([
-                this._imagePlaneFactory.createMesh(state.currentNode, state.currentTransform),
-            ]);
-            if (!this.disabled) {
-                this._updateBbox();
-            }
-        }
-        return needsRender;
-    };
-    SliderState.prototype._updateCurtain = function (alpha) {
-        if (this.disabled ||
-            Math.abs(this._curtain - alpha) < 0.001) {
-            return false;
-        }
-        this._curtain = alpha;
-        this._updateBbox();
-        return true;
-    };
-    SliderState.prototype._updateBbox = function () {
-        for (var _i = 0, _a = this._imagePlaneScene.imagePlanes; _i < _a.length; _i++) {
-            var plane = _a[_i];
-            var shaderMaterial = plane.material;
-            var bbox = shaderMaterial.uniforms.bbox.value;
-            bbox.z = this._curtain;
-        }
-    };
-    return SliderState;
-}());
-var SliderComponent = /** @class */ (function (_super) {
-    __extends(SliderComponent, _super);
-    /**
-     * Create a new slider component instance.
-     * @class SliderComponent
-     */
-    function SliderComponent(name, container, navigator, dom) {
-        var _this = _super.call(this, name, container, navigator) || this;
-        _this._dom = !!dom ? dom : new Utils_1.DOM();
-        _this._sliderStateOperation$ = new Subject_1.Subject();
-        _this._sliderStateCreator$ = new Subject_1.Subject();
-        _this._sliderStateDisposer$ = new Subject_1.Subject();
-        _this._sliderState$ = _this._sliderStateOperation$
-            .scan(function (sliderState, operation) {
-            return operation(sliderState);
-        }, null)
-            .filter(function (sliderState) {
-            return sliderState != null;
-        })
-            .distinctUntilChanged(undefined, function (sliderState) {
-            return sliderState.frameId;
-        });
-        _this._sliderStateCreator$
-            .map(function () {
-            return function (sliderState) {
-                if (sliderState != null) {
-                    throw new Error("Multiple slider states can not be created at the same time");
-                }
-                return new SliderState();
-            };
-        })
-            .subscribe(_this._sliderStateOperation$);
-        _this._sliderStateDisposer$
-            .map(function () {
-            return function (sliderState) {
-                sliderState.dispose();
-                return null;
-            };
-        })
-            .subscribe(_this._sliderStateOperation$);
-        return _this;
-    }
+/**
+ * Enumeration for slider mode.
+ *
+ * @enum {number}
+ * @readonly
+ *
+ * @description Modes for specifying how transitions
+ * between nodes are performed in slider mode. Only
+ * applicable when the slider component determines
+ * that transitions with motion is possilble. When it
+ * is not, the stationary mode will be applied.
+ */
+var SliderMode;
+(function (SliderMode) {
     /**
-     * Set the image keys.
+     * Transitions with motion.
      *
-     * Configures the component to show the image planes for the supplied image keys.
+     * @description The slider component moves the
+     * camera between the node origins.
      *
-     * @param {keys} ISliderKeys - Slider keys object specifying the images to be shown in the foreground and the background.
-     */
-    SliderComponent.prototype.setKeys = function (keys) {
-        this.configure({ keys: keys });
-    };
-    /**
-     * Set the initial position.
+     * In this mode it is not possible to zoom or pan.
      *
-     * Configures the intial position of the slider. The inital position value will be used when the component is activated.
-     *
-     * @param {number} initialPosition - Initial slider position.
+     * The slider component falls back to stationary
+     * mode when it determines that the pair of nodes
+     * does not have a strong enough relation.
      */
-    SliderComponent.prototype.setInitialPosition = function (initialPosition) {
-        this.configure({ initialPosition: initialPosition });
-    };
+    SliderMode[SliderMode["Motion"] = 0] = "Motion";
     /**
-     * Set the value controlling if the slider is visible.
+     * Stationary transitions.
      *
-     * @param {boolean} sliderVisible - Value indicating if the slider should be visible or not.
+     * @description The camera is stationary.
+     *
+     * In this mode it is possible to zoom and pan.
      */
-    SliderComponent.prototype.setSliderVisible = function (sliderVisible) {
-        this.configure({ sliderVisible: sliderVisible });
-    };
-    SliderComponent.prototype._activate = function () {
-        var _this = this;
-        this._sliderContainer = this._dom.createElement("div", "mapillary-js-slider-container", this._container.element);
-        this._sliderWrapper = this._dom.createElement("div", "SliderWrapper", this._sliderContainer);
-        this._sliderControl = this._dom.createElement("input", "SliderControl", this._sliderWrapper);
-        this._sliderControl.setAttribute("type", "range");
-        this._sliderControl.setAttribute("min", "0");
-        this._sliderControl.setAttribute("max", "1000");
-        this._sliderControl.style.visibility = "hidden";
-        this._moveToHandler = function (e) {
-            var curtain = Number(e.target.value) / 1000;
-            _this._navigator.stateService.moveTo(curtain);
-        };
-        this._sliderControl.addEventListener("input", this._moveToHandler);
-        this._sliderControl.addEventListener("change", this._moveToHandler);
-        Observable_1.Observable
-            .combineLatest(this._navigator.stateService.state$, this._configuration$)
-            .first()
-            .subscribe(function (_a) {
-            var state = _a[0], configuration = _a[1];
-            if (state === State_1.State.Traversing) {
-                _this._navigator.stateService.wait();
-                var position = configuration.initialPosition != null ? configuration.initialPosition : 1;
-                _this._sliderControl.value = (1000 * position).toString();
-                _this._navigator.stateService.moveTo(position);
-            }
-        });
-        this._glRenderSubscription = this._sliderState$
-            .map(function (sliderState) {
-            var renderHash = {
-                name: _this._name,
-                render: {
-                    frameId: sliderState.frameId,
-                    needsRender: sliderState.glNeedsRender,
-                    render: sliderState.render.bind(sliderState),
-                    stage: Render_1.GLRenderStage.Background,
-                },
-            };
-            sliderState.clearGLNeedsRender();
-            return renderHash;
-        })
-            .subscribe(this._container.glRenderer.render$);
-        this._domRenderSubscription = this._sliderState$
-            .filter(function (sliderState) {
-            return sliderState.domNeedsRender;
-        })
-            .subscribe(function (sliderState) {
-            _this._sliderControl.value = (1000 * sliderState.curtain).toString();
-            var visibility = sliderState.disabled || !sliderState.sliderVisible ? "hidden" : "visible";
-            _this._sliderControl.style.visibility = visibility;
-            sliderState.clearDomNeedsRender();
-        });
-        this._sliderStateCreator$.next(null);
-        this._stateSubscription = this._navigator.stateService.currentState$
-            .map(function (frame) {
-            return function (sliderState) {
-                sliderState.update(frame);
-                return sliderState;
-            };
-        })
-            .subscribe(this._sliderStateOperation$);
-        this._setSliderVisibleSubscription = this._configuration$
-            .map(function (configuration) {
-            return configuration.sliderVisible == null || configuration.sliderVisible;
-        })
-            .distinctUntilChanged()
-            .map(function (sliderVisible) {
-            return function (sliderState) {
-                sliderState.sliderVisible = sliderVisible;
-                return sliderState;
-            };
-        })
-            .subscribe(this._sliderStateOperation$);
-        this._setKeysSubscription = this._configuration$
-            .filter(function (configuration) {
-            return configuration.keys != null;
-        })
-            .switchMap(function (configuration) {
-            return Observable_1.Observable
-                .zip(_this._catchCacheNode$(configuration.keys.background), _this._catchCacheNode$(configuration.keys.foreground))
-                .map(function (nodes) {
-                return { background: nodes[0], foreground: nodes[1] };
-            })
-                .zip(_this._navigator.stateService.currentState$.first())
-                .map(function (nf) {
-                return { nodes: nf[0], state: nf[1].state };
-            });
-        })
-            .subscribe(function (co) {
-            if (co.state.currentNode != null &&
-                co.state.previousNode != null &&
-                co.state.currentNode.key === co.nodes.foreground.key &&
-                co.state.previousNode.key === co.nodes.background.key) {
-                return;
-            }
-            if (co.state.currentNode.key === co.nodes.background.key) {
-                _this._navigator.stateService.setNodes([co.nodes.foreground]);
-                return;
-            }
-            if (co.state.currentNode.key === co.nodes.foreground.key &&
-                co.state.trajectory.length === 1) {
-                _this._navigator.stateService.prependNodes([co.nodes.background]);
-                return;
-            }
-            _this._navigator.stateService.setNodes([co.nodes.background]);
-            _this._navigator.stateService.setNodes([co.nodes.foreground]);
-        }, function (e) {
-            console.error(e);
-        });
-        var previousNode$ = this._navigator.stateService.currentState$
-            .map(function (frame) {
-            return frame.state.previousNode;
-        })
-            .filter(function (node) {
-            return node != null;
-        })
-            .distinctUntilChanged(undefined, function (node) {
-            return node.key;
-        });
-        this._nodeSubscription = Observable_1.Observable
-            .merge(previousNode$, this._navigator.stateService.currentNode$)
-            .filter(function (node) {
-            return node.pano ?
-                Utils_1.Settings.maxImageSize > Utils_1.Settings.basePanoramaSize :
-                Utils_1.Settings.maxImageSize > Utils_1.Settings.baseImageSize;
-        })
-            .mergeMap(function (node) {
-            var baseImageSize = node.pano ?
-                Utils_1.Settings.basePanoramaSize :
-                Utils_1.Settings.baseImageSize;
-            if (Math.max(node.image.width, node.image.height) > baseImageSize) {
-                return Observable_1.Observable.empty();
-            }
-            return node.cacheImage$(Utils_1.Settings.maxImageSize)
-                .map(function (n) {
-                return [n.image, n];
-            })
-                .catch(function (error, caught) {
-                console.error("Failed to fetch high res slider image (" + node.key + ")", error);
-                return Observable_1.Observable.empty();
-            });
-        })
-            .map(function (_a) {
-            var element = _a[0], node = _a[1];
-            return function (sliderState) {
-                sliderState.updateTexture(element, node);
-                return sliderState;
-            };
-        })
-            .subscribe(this._sliderStateOperation$);
-    };
-    SliderComponent.prototype._deactivate = function () {
-        var _this = this;
-        this._navigator.stateService.state$
-            .first()
-            .subscribe(function (state) {
-            if (state === State_1.State.Waiting) {
-                _this._navigator.stateService.traverse();
-            }
-        });
-        this._sliderStateDisposer$.next(null);
-        this._setKeysSubscription.unsubscribe();
-        this._setSliderVisibleSubscription.unsubscribe();
-        this._stateSubscription.unsubscribe();
-        this._glRenderSubscription.unsubscribe();
-        this._domRenderSubscription.unsubscribe();
-        this._nodeSubscription.unsubscribe();
-        this.configure({ keys: null });
-        this._sliderControl.removeEventListener("input", this._moveToHandler);
-        this._sliderControl.removeEventListener("change", this._moveToHandler);
-        this._container.element.removeChild(this._sliderContainer);
-        this._moveToHandler = null;
-        this._sliderControl = null;
-        this._sliderWrapper = null;
-        this._sliderContainer = null;
-    };
-    SliderComponent.prototype._getDefaultConfiguration = function () {
-        return {};
-    };
-    SliderComponent.prototype._catchCacheNode$ = function (key) {
-        return this._navigator.graphService.cacheNode$(key)
-            .catch(function (error, caught) {
-            console.error("Failed to cache slider node (" + key + ")", error);
-            return Observable_1.Observable.empty();
-        });
-    };
-    SliderComponent.componentName = "slider";
-    return SliderComponent;
-}(Component_1.Component));
-exports.SliderComponent = SliderComponent;
-Component_1.ComponentService.register(SliderComponent);
-exports.default = SliderComponent;
+    SliderMode[SliderMode["Stationary"] = 1] = "Stationary";
+})(SliderMode = exports.SliderMode || (exports.SliderMode = {}));
 
-},{"../../Component":281,"../../Render":287,"../../State":288,"../../Utils":291,"rxjs/Observable":29,"rxjs/Subject":34,"rxjs/add/observable/combineLatest":38,"rxjs/add/observable/fromEvent":42,"rxjs/add/observable/of":45,"rxjs/add/observable/zip":48,"rxjs/add/operator/distinctUntilChanged":58,"rxjs/add/operator/filter":61,"rxjs/add/operator/first":63,"rxjs/add/operator/map":65,"rxjs/add/operator/merge":66,"rxjs/add/operator/mergeMap":68,"rxjs/add/operator/scan":75,"rxjs/add/operator/switchMap":81,"rxjs/add/operator/withLatestFrom":87,"rxjs/add/operator/zip":88}],317:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-var CoverState;
-(function (CoverState) {
-    CoverState[CoverState["Hidden"] = 0] = "Hidden";
-    CoverState[CoverState["Loading"] = 1] = "Loading";
-    CoverState[CoverState["Visible"] = 2] = "Visible";
-})(CoverState = exports.CoverState || (exports.CoverState = {}));
-
-},{}],318:[function(require,module,exports){
+},{}],324:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var ICoverConfiguration_1 = require("./ICoverConfiguration");
 exports.CoverState = ICoverConfiguration_1.CoverState;
+var ISliderConfiguration_1 = require("./ISliderConfiguration");
+exports.SliderMode = ISliderConfiguration_1.SliderMode;
 
-},{"./ICoverConfiguration":317}],319:[function(require,module,exports){
+},{"./ICoverConfiguration":322,"./ISliderConfiguration":323}],325:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -26519,7 +26183,7 @@ var KeyPlayHandler = /** @class */ (function (_super) {
 exports.KeyPlayHandler = KeyPlayHandler;
 exports.default = KeyPlayHandler;
 
-},{"../../Component":281,"../../Edge":282}],320:[function(require,module,exports){
+},{"../../Component":290,"../../Edge":291}],326:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -26533,10 +26197,9 @@ var __extends = (this && this.__extends) || (function () {
     };
 })();
 Object.defineProperty(exports, "__esModule", { value: true });
-require("rxjs/add/operator/switchMap");
-require("rxjs/add/operator/withLatestFrom");
 var Component_1 = require("../../Component");
 var Edge_1 = require("../../Edge");
+var Error_1 = require("../../Error");
 /**
  * The `KeySequenceNavigationHandler` allows the user to navigate through a sequence using the
  * following key commands:
@@ -26588,7 +26251,11 @@ var KeySequenceNavigationHandler = /** @class */ (function (_super) {
                 var edge = _b[_i];
                 if (edge.data.direction === direction) {
                     _this._navigator.moveToKey$(edge.to)
-                        .subscribe(function (n) { return; }, function (e) { console.error(e); });
+                        .subscribe(undefined, function (error) {
+                        if (!(error instanceof Error_1.AbortMapillaryError)) {
+                            console.error(error);
+                        }
+                    });
                     return;
                 }
             }
@@ -26605,7 +26272,7 @@ var KeySequenceNavigationHandler = /** @class */ (function (_super) {
 exports.KeySequenceNavigationHandler = KeySequenceNavigationHandler;
 exports.default = KeySequenceNavigationHandler;
 
-},{"../../Component":281,"../../Edge":282,"rxjs/add/operator/switchMap":81,"rxjs/add/operator/withLatestFrom":87}],321:[function(require,module,exports){
+},{"../../Component":290,"../../Edge":291,"../../Error":292}],327:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -26619,10 +26286,9 @@ var __extends = (this && this.__extends) || (function () {
     };
 })();
 Object.defineProperty(exports, "__esModule", { value: true });
-require("rxjs/add/operator/switchMap");
-require("rxjs/add/operator/withLatestFrom");
 var Component_1 = require("../../Component");
 var Edge_1 = require("../../Edge");
+var Error_1 = require("../../Error");
 /**
  * The `KeySpatialNavigationHandler` allows the user to navigate through a sequence using the
  * following key commands:
@@ -26734,7 +26400,11 @@ var KeySpatialNavigationHandler = /** @class */ (function (_super) {
     };
     KeySpatialNavigationHandler.prototype._moveToKey = function (key) {
         this._navigator.moveToKey$(key)
-            .subscribe(function (n) { }, function (e) { console.error(e); });
+            .subscribe(undefined, function (error) {
+            if (!(error instanceof Error_1.AbortMapillaryError)) {
+                console.error(error);
+            }
+        });
     };
     KeySpatialNavigationHandler.prototype._rotationFromCamera = function (camera) {
         var direction = camera.lookat.clone().sub(camera.position);
@@ -26749,7 +26419,7 @@ var KeySpatialNavigationHandler = /** @class */ (function (_super) {
 exports.KeySpatialNavigationHandler = KeySpatialNavigationHandler;
 exports.default = KeySpatialNavigationHandler;
 
-},{"../../Component":281,"../../Edge":282,"rxjs/add/operator/switchMap":81,"rxjs/add/operator/withLatestFrom":87}],322:[function(require,module,exports){
+},{"../../Component":290,"../../Edge":291,"../../Error":292}],328:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -26763,7 +26433,6 @@ var __extends = (this && this.__extends) || (function () {
     };
 })();
 Object.defineProperty(exports, "__esModule", { value: true });
-require("rxjs/add/operator/withLatestFrom");
 var Component_1 = require("../../Component");
 /**
  * The `KeyZoomHandler` allows the user to zoom in and out using the
@@ -26826,7 +26495,7 @@ var KeyZoomHandler = /** @class */ (function (_super) {
 exports.KeyZoomHandler = KeyZoomHandler;
 exports.default = KeyZoomHandler;
 
-},{"../../Component":281,"rxjs/add/operator/withLatestFrom":87}],323:[function(require,module,exports){
+},{"../../Component":290}],329:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -26963,7 +26632,7 @@ exports.KeyboardComponent = KeyboardComponent;
 Component_1.ComponentService.register(KeyboardComponent);
 exports.default = KeyboardComponent;
 
-},{"../../Component":281,"../../Geo":284}],324:[function(require,module,exports){
+},{"../../Component":290,"../../Geo":293}],330:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var MarkerComponent_1 = require("./MarkerComponent");
@@ -26973,7 +26642,7 @@ exports.SimpleMarker = SimpleMarker_1.SimpleMarker;
 var CircleMarker_1 = require("./marker/CircleMarker");
 exports.CircleMarker = CircleMarker_1.CircleMarker;
 
-},{"./MarkerComponent":325,"./marker/CircleMarker":328,"./marker/SimpleMarker":330}],325:[function(require,module,exports){
+},{"./MarkerComponent":331,"./marker/CircleMarker":334,"./marker/SimpleMarker":336}],331:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -26990,9 +26659,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
 var THREE = require("three");
 var when = require("when");
 var Observable_1 = require("rxjs/Observable");
-require("rxjs/add/observable/combineLatest");
-require("rxjs/add/operator/distinctUntilChanged");
-require("rxjs/add/operator/map");
 var Component_1 = require("../../Component");
 var Render_1 = require("../../Render");
 var Graph_1 = require("../../Graph");
@@ -27466,7 +27132,7 @@ exports.MarkerComponent = MarkerComponent;
 Component_1.ComponentService.register(MarkerComponent);
 exports.default = MarkerComponent;
 
-},{"../../Component":281,"../../Geo":284,"../../Graph":285,"../../Render":287,"rxjs/Observable":29,"rxjs/add/observable/combineLatest":38,"rxjs/add/operator/distinctUntilChanged":58,"rxjs/add/operator/map":65,"three":231,"when":278}],326:[function(require,module,exports){
+},{"../../Component":290,"../../Geo":293,"../../Graph":294,"../../Render":296,"rxjs/Observable":29,"three":240,"when":287}],332:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -27589,15 +27255,12 @@ var MarkerScene = /** @class */ (function () {
 exports.MarkerScene = MarkerScene;
 exports.default = MarkerScene;
 
-},{"three":231}],327:[function(require,module,exports){
+},{"three":240}],333:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
 var rbush = require("rbush");
 var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/publishReplay");
-require("rxjs/add/operator/scan");
 var MarkerSet = /** @class */ (function () {
     function MarkerSet() {
         this._hash = {};
@@ -27710,7 +27373,7 @@ var MarkerSet = /** @class */ (function () {
 exports.MarkerSet = MarkerSet;
 exports.default = MarkerSet;
 
-},{"rbush":25,"rxjs/Subject":34,"rxjs/add/operator/map":65,"rxjs/add/operator/publishReplay":72,"rxjs/add/operator/scan":75}],328:[function(require,module,exports){
+},{"rbush":25,"rxjs/Subject":34}],334:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -27793,7 +27456,7 @@ var CircleMarker = /** @class */ (function (_super) {
 exports.CircleMarker = CircleMarker;
 exports.default = CircleMarker;
 
-},{"../../../Component":281,"three":231}],329:[function(require,module,exports){
+},{"../../../Component":290,"three":240}],335:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -27880,7 +27543,7 @@ var Marker = /** @class */ (function () {
 exports.Marker = Marker;
 exports.default = Marker;
 
-},{}],330:[function(require,module,exports){
+},{}],336:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -28027,7 +27690,7 @@ var SimpleMarker = /** @class */ (function (_super) {
 exports.SimpleMarker = SimpleMarker;
 exports.default = SimpleMarker;
 
-},{"../../../Component":281,"three":231}],331:[function(require,module,exports){
+},{"../../../Component":290,"three":240}],337:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -28137,7 +27800,7 @@ var BounceHandler = /** @class */ (function (_super) {
 exports.BounceHandler = BounceHandler;
 exports.default = BounceHandler;
 
-},{"../../Component":281,"rxjs/Observable":29}],332:[function(require,module,exports){
+},{"../../Component":290,"rxjs/Observable":29}],338:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -28203,7 +27866,7 @@ var DoubleClickZoomHandler = /** @class */ (function (_super) {
 exports.DoubleClickZoomHandler = DoubleClickZoomHandler;
 exports.default = DoubleClickZoomHandler;
 
-},{"../../Component":281,"rxjs/Observable":29}],333:[function(require,module,exports){
+},{"../../Component":290,"rxjs/Observable":29}],339:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -28219,9 +27882,6 @@ var __extends = (this && this.__extends) || (function () {
 Object.defineProperty(exports, "__esModule", { value: true });
 var THREE = require("three");
 var Observable_1 = require("rxjs/Observable");
-require("rxjs/add/operator/concat");
-require("rxjs/add/operator/sample");
-require("rxjs/add/operator/takeWhile");
 var Component_1 = require("../../Component");
 /**
  * The `DragPanHandler` allows the user to pan the viewer image by clicking and dragging the cursor.
@@ -28456,7 +28116,7 @@ var DragPanHandler = /** @class */ (function (_super) {
 exports.DragPanHandler = DragPanHandler;
 exports.default = DragPanHandler;
 
-},{"../../Component":281,"rxjs/Observable":29,"rxjs/add/operator/concat":54,"rxjs/add/operator/sample":74,"rxjs/add/operator/takeWhile":84,"three":231}],334:[function(require,module,exports){
+},{"../../Component":290,"rxjs/Observable":29,"three":240}],340:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -28469,10 +28129,6 @@ var __extends = (this && this.__extends) || (function () {
     };
 })();
 Object.defineProperty(exports, "__esModule", { value: true });
-require("rxjs/add/observable/merge");
-require("rxjs/add/operator/filter");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/withLatestFrom");
 var Component_1 = require("../../Component");
 var Geo_1 = require("../../Geo");
 /**
@@ -28595,7 +28251,7 @@ var MouseComponent = /** @class */ (function (_super) {
         this._touchZoomHandler.disable();
     };
     MouseComponent.prototype._getDefaultConfiguration = function () {
-        return { doubleClickZoom: true, dragPan: true, scrollZoom: true, touchZoom: true };
+        return { doubleClickZoom: false, dragPan: true, scrollZoom: true, touchZoom: true };
     };
     /** @inheritdoc */
     MouseComponent.componentName = "mouse";
@@ -28605,7 +28261,7 @@ exports.MouseComponent = MouseComponent;
 Component_1.ComponentService.register(MouseComponent);
 exports.default = MouseComponent;
 
-},{"../../Component":281,"../../Geo":284,"rxjs/add/observable/merge":44,"rxjs/add/operator/filter":61,"rxjs/add/operator/map":65,"rxjs/add/operator/withLatestFrom":87}],335:[function(require,module,exports){
+},{"../../Component":290,"../../Geo":293}],341:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -28696,7 +28352,7 @@ var ScrollZoomHandler = /** @class */ (function (_super) {
 exports.ScrollZoomHandler = ScrollZoomHandler;
 exports.default = ScrollZoomHandler;
 
-},{"../../Component":281}],336:[function(require,module,exports){
+},{"../../Component":290}],342:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -28785,7 +28441,7 @@ var TouchZoomHandler = /** @class */ (function (_super) {
 exports.TouchZoomHandler = TouchZoomHandler;
 exports.default = TouchZoomHandler;
 
-},{"../../Component":281,"rxjs/Observable":29}],337:[function(require,module,exports){
+},{"../../Component":290,"rxjs/Observable":29}],343:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Popup_1 = require("./popup/Popup");
@@ -28793,7 +28449,7 @@ exports.Popup = Popup_1.Popup;
 var PopupComponent_1 = require("./PopupComponent");
 exports.PopupComponent = PopupComponent_1.PopupComponent;
 
-},{"./PopupComponent":338,"./popup/Popup":339}],338:[function(require,module,exports){
+},{"./PopupComponent":344,"./popup/Popup":345}],344:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -28977,7 +28633,7 @@ exports.PopupComponent = PopupComponent;
 Component_1.ComponentService.register(PopupComponent);
 exports.default = PopupComponent;
 
-},{"../../Component":281,"../../Utils":291,"rxjs/Observable":29,"rxjs/Subject":34}],339:[function(require,module,exports){
+},{"../../Component":290,"../../Utils":300,"rxjs/Observable":29,"rxjs/Subject":34}],345:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -29463,17 +29119,7 @@ var Popup = /** @class */ (function () {
 exports.Popup = Popup;
 exports.default = Popup;
 
-},{"../../../Geo":284,"../../../Utils":291,"../../../Viewer":292,"rxjs/Subject":34}],340:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-var ControlMode;
-(function (ControlMode) {
-    ControlMode[ControlMode["Default"] = 0] = "Default";
-    ControlMode[ControlMode["Playback"] = 1] = "Playback";
-})(ControlMode = exports.ControlMode || (exports.ControlMode = {}));
-exports.default = ControlMode;
-
-},{}],341:[function(require,module,exports){
+},{"../../../Geo":293,"../../../Utils":300,"../../../Viewer":301,"rxjs/Subject":34}],346:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -29489,24 +29135,9 @@ var __extends = (this && this.__extends) || (function () {
 Object.defineProperty(exports, "__esModule", { value: true });
 var Observable_1 = require("rxjs/Observable");
 var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/observable/combineLatest");
-require("rxjs/add/observable/of");
-require("rxjs/add/operator/bufferCount");
-require("rxjs/add/operator/concat");
-require("rxjs/add/operator/distinctUntilChanged");
-require("rxjs/add/operator/filter");
-require("rxjs/add/operator/finally");
-require("rxjs/add/operator/first");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/publishReplay");
-require("rxjs/add/operator/retry");
-require("rxjs/add/operator/scan");
-require("rxjs/add/operator/share");
-require("rxjs/add/operator/switchMap");
-require("rxjs/add/operator/takeUntil");
-require("rxjs/add/operator/withLatestFrom");
 var Component_1 = require("../../Component");
 var Edge_1 = require("../../Edge");
+var Graph_1 = require("../../Graph");
 /**
  * @class SequenceComponent
  * @classdesc Component showing navigation arrows for sequence directions
@@ -29514,10 +29145,10 @@ var Edge_1 = require("../../Edge");
  */
 var SequenceComponent = /** @class */ (function (_super) {
     __extends(SequenceComponent, _super);
-    function SequenceComponent(name, container, navigator) {
+    function SequenceComponent(name, container, navigator, renderer, scheduler) {
         var _this = _super.call(this, name, container, navigator) || this;
-        _this._sequenceDOMRenderer = new Component_1.SequenceDOMRenderer(container);
-        _this._sequenceDOMInteraction = new Component_1.SequenceDOMInteraction();
+        _this._sequenceDOMRenderer = !!renderer ? renderer : new Component_1.SequenceDOMRenderer(container);
+        _this._scheduler = scheduler;
         _this._containerWidth$ = new Subject_1.Subject();
         _this._hoveredKeySubject$ = new Subject_1.Subject();
         _this._hoveredKey$ = _this._hoveredKeySubject$.share();
@@ -29658,12 +29289,135 @@ var SequenceComponent = /** @class */ (function (_super) {
         })
             .publishReplay(1)
             .refCount();
+        var sequence$ = this._navigator.stateService.currentNode$
+            .distinctUntilChanged(undefined, function (node) {
+            return node.sequenceKey;
+        })
+            .switchMap(function (node) {
+            return Observable_1.Observable
+                .concat(Observable_1.Observable.of(null), _this._navigator.graphService.cacheSequence$(node.sequenceKey)
+                .retry(3)
+                .catch(function (e) {
+                console.error("Failed to cache sequence", e);
+                return Observable_1.Observable.of(null);
+            }));
+        })
+            .startWith(null)
+            .publishReplay(1)
+            .refCount();
+        this._sequenceSubscription = sequence$.subscribe();
+        var rendererKey$ = this._sequenceDOMRenderer.index$
+            .withLatestFrom(sequence$)
+            .map(function (_a) {
+            var index = _a[0], sequence = _a[1];
+            return sequence != null ? sequence.keys[index] : null;
+        })
+            .filter(function (key) {
+            return !!key;
+        })
+            .distinctUntilChanged()
+            .publish()
+            .refCount();
+        this._moveSubscription = Observable_1.Observable
+            .merge(rendererKey$.debounceTime(100, this._scheduler), rendererKey$.auditTime(400, this._scheduler))
+            .distinctUntilChanged()
+            .switchMap(function (key) {
+            return _this._navigator.moveToKey$(key)
+                .catch(function (e) {
+                return Observable_1.Observable.empty();
+            });
+        })
+            .subscribe();
+        this._setSequenceGraphModeSubscription = this._sequenceDOMRenderer.changingPositionChanged$
+            .filter(function (changing) {
+            return changing;
+        })
+            .subscribe(function () {
+            _this._navigator.graphService.setGraphMode(Graph_1.GraphMode.Sequence);
+        });
+        this._setSpatialGraphModeSubscription = this._sequenceDOMRenderer.changingPositionChanged$
+            .filter(function (changing) {
+            return !changing;
+        })
+            .subscribe(function () {
+            _this._navigator.graphService.setGraphMode(Graph_1.GraphMode.Spatial);
+        });
+        this._navigator.graphService.graphMode$
+            .switchMap(function (mode) {
+            return mode === Graph_1.GraphMode.Spatial ?
+                _this._navigator.stateService.currentNode$
+                    .take(2) :
+                Observable_1.Observable.empty();
+        })
+            .filter(function (node) {
+            return !node.spatialEdges.cached;
+        })
+            .switchMap(function (node) {
+            return _this._navigator.graphService.cacheNode$(node.key)
+                .catch(function (e) {
+                return Observable_1.Observable.empty();
+            });
+        })
+            .subscribe();
+        this._stopSubscription = this._sequenceDOMRenderer.changingPositionChanged$
+            .filter(function (changing) {
+            return changing;
+        })
+            .subscribe(function () {
+            _this._navigator.playService.stop();
+        });
+        this._cacheSequenceNodesSubscription = Observable_1.Observable
+            .combineLatest(this._navigator.graphService.graphMode$, this._sequenceDOMRenderer.changingPositionChanged$
+            .startWith(false)
+            .distinctUntilChanged())
+            .withLatestFrom(this._navigator.stateService.currentNode$)
+            .switchMap(function (_a) {
+            var _b = _a[0], mode = _b[0], changing = _b[1], node = _a[1];
+            return changing && mode === Graph_1.GraphMode.Sequence ?
+                _this._navigator.graphService.cacheSequenceNodes$(node.sequenceKey, node.key)
+                    .retry(3)
+                    .catch(function (error) {
+                    console.error("Failed to cache sequence nodes.", error);
+                    return Observable_1.Observable.empty();
+                }) :
+                Observable_1.Observable.empty();
+        })
+            .subscribe();
+        var position$ = sequence$
+            .switchMap(function (sequence) {
+            if (!sequence) {
+                return Observable_1.Observable.of({ index: null, max: null });
+            }
+            var firstCurrentKey = true;
+            return _this._sequenceDOMRenderer.changingPositionChanged$
+                .startWith(false)
+                .distinctUntilChanged()
+                .switchMap(function (changingPosition) {
+                var skip = !changingPosition && firstCurrentKey ? 0 : 1;
+                firstCurrentKey = false;
+                return changingPosition ?
+                    rendererKey$ :
+                    _this._navigator.stateService.currentNode$
+                        .map(function (node) {
+                        return node.key;
+                    })
+                        .distinctUntilChanged()
+                        .skip(skip);
+            })
+                .map(function (key) {
+                var index = sequence.keys.indexOf(key);
+                if (index === -1) {
+                    return { index: null, max: null };
+                }
+                return { index: index, max: sequence.keys.length - 1 };
+            });
+        });
         this._renderSubscription = Observable_1.Observable
-            .combineLatest(edgeStatus$, this._configuration$, this._containerWidth$, this._sequenceDOMRenderer.changed$.startWith(this._sequenceDOMRenderer), this._navigator.playService.speed$)
+            .combineLatest(edgeStatus$, this._configuration$, this._containerWidth$, this._sequenceDOMRenderer.changed$.startWith(this._sequenceDOMRenderer), this._navigator.playService.speed$, position$)
             .map(function (_a) {
-            var edgeStatus = _a[0], configuration = _a[1], containerWidth = _a[2], renderer = _a[3], speed = _a[4];
+            var edgeStatus = _a[0], configuration = _a[1], containerWidth = _a[2], renderer = _a[3], speed = _a[4], position = _a[5];
             var vNode = _this._sequenceDOMRenderer
-                .render(edgeStatus, configuration, containerWidth, speed, _this, _this._sequenceDOMInteraction, _this._navigator);
+                .render(edgeStatus, configuration, containerWidth, speed, position.index, position.max, _this, _this._navigator);
             return { name: _this._name, vnode: vNode };
         })
             .subscribe(this._container.domRenderer.render$);
@@ -29702,7 +29456,7 @@ var SequenceComponent = /** @class */ (function (_super) {
                 _this._navigator.playService.stop();
             }
         });
-        this._hoveredKeySubscription = this._sequenceDOMInteraction.mouseEnterDirection$
+        this._hoveredKeySubscription = this._sequenceDOMRenderer.mouseEnterDirection$
             .switchMap(function (direction) {
             return edgeStatus$
                 .map(function (edgeStatus) {
@@ -29714,7 +29468,7 @@ var SequenceComponent = /** @class */ (function (_super) {
                 }
                 return null;
             })
-                .takeUntil(_this._sequenceDOMInteraction.mouseLeaveDirection$)
+                .takeUntil(_this._sequenceDOMRenderer.mouseLeaveDirection$)
                 .concat(Observable_1.Observable.of(null));
         })
             .distinctUntilChanged()
@@ -29727,6 +29481,12 @@ var SequenceComponent = /** @class */ (function (_super) {
         this._hoveredKeySubscription.unsubscribe();
         this._setSpeedSubscription.unsubscribe();
         this._setDirectionSubscription.unsubscribe();
+        this._setSequenceGraphModeSubscription.unsubscribe();
+        this._setSpatialGraphModeSubscription.unsubscribe();
+        this._sequenceSubscription.unsubscribe();
+        this._moveSubscription.unsubscribe();
+        this._cacheSequenceNodesSubscription.unsubscribe();
+        this._stopSubscription.unsubscribe();
         this._sequenceDOMRenderer.deactivate();
     };
     SequenceComponent.prototype._getDefaultConfiguration = function () {
@@ -29753,35 +29513,7 @@ exports.SequenceComponent = SequenceComponent;
 Component_1.ComponentService.register(SequenceComponent);
 exports.default = SequenceComponent;
 
-},{"../../Component":281,"../../Edge":282,"rxjs/Observable":29,"rxjs/Subject":34,"rxjs/add/observable/combineLatest":38,"rxjs/add/observable/of":45,"rxjs/add/operator/bufferCount":50,"rxjs/add/operator/concat":54,"rxjs/add/operator/distinctUntilChanged":58,"rxjs/add/operator/filter":61,"rxjs/add/operator/finally":62,"rxjs/add/operator/first":63,"rxjs/add/operator/map":65,"rxjs/add/operator/publishReplay":72,"rxjs/add/operator/retry":73,"rxjs/add/operator/scan":75,"rxjs/add/operator/share":76,"rxjs/add/operator/switchMap":81,"rxjs/add/operator/takeUntil":83,"rxjs/add/operator/withLatestFrom":87}],342:[function(require,module,exports){
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-var Subject_1 = require("rxjs/Subject");
-var SequenceDOMInteraction = /** @class */ (function () {
-    function SequenceDOMInteraction() {
-        this._mouseEnterDirection$ = new Subject_1.Subject();
-        this._mouseLeaveDirection$ = new Subject_1.Subject();
-    }
-    Object.defineProperty(SequenceDOMInteraction.prototype, "mouseEnterDirection$", {
-        get: function () {
-            return this._mouseEnterDirection$;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    Object.defineProperty(SequenceDOMInteraction.prototype, "mouseLeaveDirection$", {
-        get: function () {
-            return this._mouseLeaveDirection$;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    return SequenceDOMInteraction;
-}());
-exports.SequenceDOMInteraction = SequenceDOMInteraction;
-exports.default = SequenceDOMInteraction;
-
-},{"rxjs/Subject":34}],343:[function(require,module,exports){
+},{"../../Component":290,"../../Edge":291,"../../Graph":294,"rxjs/Observable":29,"rxjs/Subject":34}],347:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -29790,6 +29522,7 @@ var Observable_1 = require("rxjs/Observable");
 var Subject_1 = require("rxjs/Subject");
 var Component_1 = require("../../Component");
 var Edge_1 = require("../../Edge");
+var Error_1 = require("../../Error");
 var SequenceDOMRenderer = /** @class */ (function () {
     function SequenceDOMRenderer(container) {
         this._container = container;
@@ -29798,25 +29531,31 @@ var SequenceDOMRenderer = /** @class */ (function () {
         this._minThresholdHeight = 240;
         this._maxThresholdHeight = 820;
         this._stepperDefaultWidth = 108;
-        this._controlsDefaultWidth = 52;
+        this._controlsDefaultWidth = 88;
         this._defaultHeight = 30;
         this._expandControls = false;
-        this._mode = Component_1.ControlMode.Default;
+        this._mode = Component_1.SequenceMode.Default;
         this._speed = 0.5;
         this._changingSpeed = false;
+        this._index = null;
+        this._changingPosition = false;
+        this._mouseEnterDirection$ = new Subject_1.Subject();
+        this._mouseLeaveDirection$ = new Subject_1.Subject();
         this._notifyChanged$ = new Subject_1.Subject();
+        this._notifyChangingPositionChanged$ = new Subject_1.Subject();
         this._notifySpeedChanged$ = new Subject_1.Subject();
+        this._notifyIndexChanged$ = new Subject_1.Subject();
     }
-    Object.defineProperty(SequenceDOMRenderer.prototype, "speed", {
+    Object.defineProperty(SequenceDOMRenderer.prototype, "changed$", {
         get: function () {
-            return this._speed;
+            return this._notifyChanged$;
         },
         enumerable: true,
         configurable: true
     });
-    Object.defineProperty(SequenceDOMRenderer.prototype, "changed$", {
+    Object.defineProperty(SequenceDOMRenderer.prototype, "changingPositionChanged$", {
         get: function () {
-            return this._notifyChanged$;
+            return this._notifyChangingPositionChanged$;
         },
         enumerable: true,
         configurable: true
@@ -29828,12 +29567,33 @@ var SequenceDOMRenderer = /** @class */ (function () {
         enumerable: true,
         configurable: true
     });
+    Object.defineProperty(SequenceDOMRenderer.prototype, "index$", {
+        get: function () {
+            return this._notifyIndexChanged$;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(SequenceDOMRenderer.prototype, "mouseEnterDirection$", {
+        get: function () {
+            return this._mouseEnterDirection$;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(SequenceDOMRenderer.prototype, "mouseLeaveDirection$", {
+        get: function () {
+            return this._mouseLeaveDirection$;
+        },
+        enumerable: true,
+        configurable: true
+    });
     SequenceDOMRenderer.prototype.activate = function () {
         var _this = this;
-        if (!!this._changingSpeedSubscription) {
+        if (!!this._changingSubscription) {
             return;
         }
-        this._changingSpeedSubscription = Observable_1.Observable
+        this._changingSubscription = Observable_1.Observable
             .merge(this._container.mouseService.documentMouseUp$, this._container.touchService.touchEnd$
             .filter(function (touchEvent) {
             return touchEvent.touches.length === 0;
@@ -29842,26 +29602,31 @@ var SequenceDOMRenderer = /** @class */ (function () {
             if (_this._changingSpeed) {
                 _this._changingSpeed = false;
             }
+            if (_this._changingPosition) {
+                _this._setChangingPosition(false);
+            }
         });
     };
     SequenceDOMRenderer.prototype.deactivate = function () {
-        if (!this._changingSpeedSubscription) {
+        if (!this._changingSubscription) {
             return;
         }
         this._changingSpeed = false;
+        this._changingPosition = false;
         this._expandControls = false;
-        this._mode = Component_1.ControlMode.Default;
-        this._changingSpeedSubscription.unsubscribe();
-        this._changingSpeedSubscription = null;
+        this._mode = Component_1.SequenceMode.Default;
+        this._changingSubscription.unsubscribe();
+        this._changingSubscription = null;
     };
-    SequenceDOMRenderer.prototype.render = function (edgeStatus, configuration, containerWidth, speed, component, interaction, navigator) {
+    SequenceDOMRenderer.prototype.render = function (edgeStatus, configuration, containerWidth, speed, index, max, component, navigator) {
         if (configuration.visible === false) {
             return vd.h("div.SequenceContainer", {}, []);
         }
-        var stepper = this._createStepper(edgeStatus, configuration, containerWidth, component, interaction, navigator);
+        var stepper = this._createStepper(edgeStatus, configuration, containerWidth, component, navigator);
         var controls = this._createSequenceControls(containerWidth);
         var playback = this._createPlaybackControls(containerWidth, speed, component, configuration);
-        return vd.h("div.SequenceContainer", [stepper, controls, playback]);
+        var timeline = this._createTimelineControls(containerWidth, index, max);
+        return vd.h("div.SequenceContainer", [stepper, controls, playback, timeline]);
     };
     SequenceDOMRenderer.prototype.getContainerWidth = function (element, configuration) {
         var elementWidth = element.offsetWidth;
@@ -29876,6 +29641,54 @@ var SequenceDOMRenderer = /** @class */ (function () {
         var coeff = Math.max(0, Math.min(1, Math.min(relativeWidth, relativeHeight)));
         return minWidth + coeff * (maxWidth - minWidth);
     };
+    SequenceDOMRenderer.prototype._createPositionInput = function (index, max) {
+        var _this = this;
+        this._index = index;
+        var onPosition = function (e) {
+            _this._index = Number(e.target.value);
+            _this._notifyIndexChanged$.next(_this._index);
+        };
+        var boundingRect = this._container.domContainer.getBoundingClientRect();
+        var width = Math.max(276, Math.min(410, 5 + 0.8 * boundingRect.width)) - 65;
+        var onStart = function (e) {
+            e.stopPropagation();
+            _this._setChangingPosition(true);
+        };
+        var onMove = function (e) {
+            if (_this._changingPosition === true) {
+                e.stopPropagation();
+            }
+        };
+        var onKeyDown = function (e) {
+            if (e.key === "ArrowDown" || e.key === "ArrowLeft" ||
+                e.key === "ArrowRight" || e.key === "ArrowUp") {
+                e.preventDefault();
+            }
+        };
+        var positionInputProperties = {
+            max: max != null ? max : 1,
+            min: 0,
+            onchange: onPosition,
+            oninput: onPosition,
+            onkeydown: onKeyDown,
+            onmousedown: onStart,
+            onmousemove: onMove,
+            ontouchmove: onMove,
+            ontouchstart: onStart,
+            style: {
+                width: width + "px",
+            },
+            type: "range",
+            value: index != null ? index : 0,
+        };
+        var disabled = index == null || max == null || max <= 1;
+        if (disabled) {
+            positionInputProperties.disabled = "true";
+        }
+        var positionInput = vd.h("input.SequencePosition", positionInputProperties, []);
+        var positionContainerClass = disabled ? ".SequencePositionContainerDisabled" : ".SequencePositionContainer";
+        return vd.h("div" + positionContainerClass, [positionInput]);
+    };
     SequenceDOMRenderer.prototype._createSpeedInput = function (speed) {
         var _this = this;
         this._speed = speed;
@@ -29894,11 +29707,18 @@ var SequenceDOMRenderer = /** @class */ (function () {
                 e.stopPropagation();
             }
         };
+        var onKeyDown = function (e) {
+            if (e.key === "ArrowDown" || e.key === "ArrowLeft" ||
+                e.key === "ArrowRight" || e.key === "ArrowUp") {
+                e.preventDefault();
+            }
+        };
         var speedInput = vd.h("input.SequenceSpeed", {
             max: 1000,
             min: 0,
             onchange: onSpeed,
             oninput: onSpeed,
+            onkeydown: onKeyDown,
             onmousedown: onStart,
             onmousemove: onMove,
             ontouchmove: onMove,
@@ -29913,7 +29733,7 @@ var SequenceDOMRenderer = /** @class */ (function () {
     };
     SequenceDOMRenderer.prototype._createPlaybackControls = function (containerWidth, speed, component, configuration) {
         var _this = this;
-        if (this._mode !== Component_1.ControlMode.Playback) {
+        if (this._mode !== Component_1.SequenceMode.Playback) {
             return vd.h("div.SequencePlayback", []);
         }
         var switchIcon = vd.h("div.SequenceSwitchIcon.SequenceIconVisible", []);
@@ -29931,12 +29751,12 @@ var SequenceDOMRenderer = /** @class */ (function () {
         var switchButton = vd.h("div" + switchButtonClassName, switchButtonProperties, [switchIcon]);
         var slowIcon = vd.h("div.SequenceSlowIcon.SequenceIconVisible", []);
         var slowContainer = vd.h("div.SequenceSlowContainer", [slowIcon]);
-        var fastIcon = vd.h("div.SequenceFastIconGrey.SequenceIconVisible", []);
+        var fastIcon = vd.h("div.SequenceFastIcon.SequenceIconVisible", []);
         var fastContainer = vd.h("div.SequenceFastContainer", [fastIcon]);
         var closeIcon = vd.h("div.SequenceCloseIcon.SequenceIconVisible", []);
         var closeButtonProperties = {
             onclick: function () {
-                _this._mode = Component_1.ControlMode.Default;
+                _this._mode = Component_1.SequenceMode.Default;
                 _this._notifyChanged$.next(_this);
             },
         };
@@ -29973,7 +29793,7 @@ var SequenceDOMRenderer = /** @class */ (function () {
         var expanderProperties = {
             onclick: function () {
                 _this._expandControls = !_this._expandControls;
-                _this._mode = Component_1.ControlMode.Default;
+                _this._mode = Component_1.SequenceMode.Default;
                 _this._notifyChanged$.next(_this);
             },
             style: {
@@ -29983,18 +29803,30 @@ var SequenceDOMRenderer = /** @class */ (function () {
         };
         var expanderBar = vd.h("div.SequenceExpanderBar", []);
         var expander = vd.h("div.SequenceExpanderButton", expanderProperties, [expanderBar]);
-        var fastIconClassName = this._mode === Component_1.ControlMode.Playback ?
+        var fastIconClassName = this._mode === Component_1.SequenceMode.Playback ?
             ".SequenceFastIconGrey.SequenceIconVisible" : ".SequenceFastIcon";
         var fastIcon = vd.h("div" + fastIconClassName, []);
         var playbackProperties = {
             onclick: function () {
-                _this._mode = _this._mode === Component_1.ControlMode.Playback ?
-                    Component_1.ControlMode.Default :
-                    Component_1.ControlMode.Playback;
+                _this._mode = _this._mode === Component_1.SequenceMode.Playback ?
+                    Component_1.SequenceMode.Default :
+                    Component_1.SequenceMode.Playback;
+                _this._notifyChanged$.next(_this);
+            },
+        };
+        var playback = vd.h("div.SequencePlaybackButton", playbackProperties, [fastIcon]);
+        var timelineIconClassName = this._mode === Component_1.SequenceMode.Timeline ?
+            ".SequenceTimelineIconGrey.SequenceIconVisible" : ".SequenceTimelineIcon";
+        var timelineIcon = vd.h("div" + timelineIconClassName, []);
+        var timelineProperties = {
+            onclick: function () {
+                _this._mode = _this._mode === Component_1.SequenceMode.Timeline ?
+                    Component_1.SequenceMode.Default :
+                    Component_1.SequenceMode.Timeline;
                 _this._notifyChanged$.next(_this);
             },
         };
-        var controls = vd.h("div.SequencePlaybackButton", playbackProperties, [fastIcon]);
+        var timeline = vd.h("div.SequenceTimelineButton", timelineProperties, [timelineIcon]);
         var properties = {
             style: {
                 height: (this._defaultHeight / this._stepperDefaultWidth * containerWidth) + "px",
@@ -30004,29 +29836,38 @@ var SequenceDOMRenderer = /** @class */ (function () {
         };
         var className = ".SequenceControls" +
             (this._expandControls ? ".SequenceControlsExpanded" : "");
-        return vd.h("div" + className, properties, [controls, expander]);
+        return vd.h("div" + className, properties, [playback, timeline, expander]);
     };
-    SequenceDOMRenderer.prototype._createSequenceArrows = function (nextKey, prevKey, containerWidth, configuration, interaction, navigator) {
+    SequenceDOMRenderer.prototype._createSequenceArrows = function (nextKey, prevKey, containerWidth, configuration, navigator) {
+        var _this = this;
         var nextProperties = {
             onclick: nextKey != null ?
                 function (e) {
                     navigator.moveDir$(Edge_1.EdgeDirection.Next)
-                        .subscribe(function (node) { return; }, function (error) { console.error(error); });
+                        .subscribe(undefined, function (error) {
+                        if (!(error instanceof Error_1.AbortMapillaryError)) {
+                            console.error(error);
+                        }
+                    });
                 } :
                 null,
-            onmouseenter: function (e) { interaction.mouseEnterDirection$.next(Edge_1.EdgeDirection.Next); },
-            onmouseleave: function (e) { interaction.mouseLeaveDirection$.next(Edge_1.EdgeDirection.Next); },
+            onmouseenter: function (e) { _this._mouseEnterDirection$.next(Edge_1.EdgeDirection.Next); },
+            onmouseleave: function (e) { _this._mouseLeaveDirection$.next(Edge_1.EdgeDirection.Next); },
         };
         var borderRadius = Math.round(8 / this._stepperDefaultWidth * containerWidth);
         var prevProperties = {
             onclick: prevKey != null ?
                 function (e) {
                     navigator.moveDir$(Edge_1.EdgeDirection.Prev)
-                        .subscribe(function (node) { return; }, function (error) { console.error(error); });
+                        .subscribe(undefined, function (error) {
+                        if (!(error instanceof Error_1.AbortMapillaryError)) {
+                            console.error(error);
+                        }
+                    });
                 } :
                 null,
-            onmouseenter: function (e) { interaction.mouseEnterDirection$.next(Edge_1.EdgeDirection.Prev); },
-            onmouseleave: function (e) { interaction.mouseLeaveDirection$.next(Edge_1.EdgeDirection.Prev); },
+            onmouseenter: function (e) { _this._mouseEnterDirection$.next(Edge_1.EdgeDirection.Prev); },
+            onmouseleave: function (e) { _this._mouseLeaveDirection$.next(Edge_1.EdgeDirection.Prev); },
             style: {
                 "border-bottom-left-radius": borderRadius + "px",
                 "border-top-left-radius": borderRadius + "px",
@@ -30041,7 +29882,7 @@ var SequenceDOMRenderer = /** @class */ (function () {
             vd.h("div." + nextClass, nextProperties, [nextIcon]),
         ];
     };
-    SequenceDOMRenderer.prototype._createStepper = function (edgeStatus, configuration, containerWidth, component, interaction, navigator) {
+    SequenceDOMRenderer.prototype._createStepper = function (edgeStatus, configuration, containerWidth, component, navigator) {
         var nextKey = null;
         var prevKey = null;
         for (var _i = 0, _a = edgeStatus.edges; _i < _a.length; _i++) {
@@ -30054,7 +29895,7 @@ var SequenceDOMRenderer = /** @class */ (function () {
             }
         }
         var playingButton = this._createPlayingButton(nextKey, prevKey, configuration, component);
-        var buttons = this._createSequenceArrows(nextKey, prevKey, containerWidth, configuration, interaction, navigator);
+        var buttons = this._createSequenceArrows(nextKey, prevKey, containerWidth, configuration, navigator);
         buttons.splice(1, 0, playingButton);
         var containerProperties = {
             oncontextmenu: function (event) { event.preventDefault(); },
@@ -30065,6 +29906,24 @@ var SequenceDOMRenderer = /** @class */ (function () {
         };
         return vd.h("div.SequenceStepper", containerProperties, buttons);
     };
+    SequenceDOMRenderer.prototype._createTimelineControls = function (containerWidth, index, max) {
+        var _this = this;
+        if (this._mode !== Component_1.SequenceMode.Timeline) {
+            return vd.h("div.SequenceTimeline", []);
+        }
+        var positionInput = this._createPositionInput(index, max);
+        var closeIcon = vd.h("div.SequenceCloseIcon.SequenceIconVisible", []);
+        var closeButtonProperties = {
+            onclick: function () {
+                _this._mode = Component_1.SequenceMode.Default;
+                _this._notifyChanged$.next(_this);
+            },
+        };
+        var closeButton = vd.h("div.SequenceCloseButton", closeButtonProperties, [closeIcon]);
+        var top = Math.round(containerWidth / this._stepperDefaultWidth * this._defaultHeight + 10);
+        var playbackProperties = { style: { top: top + "px" } };
+        return vd.h("div.SequenceTimeline", playbackProperties, [positionInput, closeButton]);
+    };
     SequenceDOMRenderer.prototype._getStepClassName = function (direction, key, highlightKey) {
         var className = direction === Edge_1.EdgeDirection.Next ?
             "SequenceStepNext" :
@@ -30079,32 +29938,56 @@ var SequenceDOMRenderer = /** @class */ (function () {
         }
         return className;
     };
+    SequenceDOMRenderer.prototype._setChangingPosition = function (value) {
+        this._changingPosition = value;
+        this._notifyChangingPositionChanged$.next(value);
+    };
     return SequenceDOMRenderer;
 }());
 exports.SequenceDOMRenderer = SequenceDOMRenderer;
 exports.default = SequenceDOMRenderer;
 
-},{"../../Component":281,"../../Edge":282,"rxjs/Observable":29,"rxjs/Subject":34,"virtual-dom":237}],344:[function(require,module,exports){
+},{"../../Component":290,"../../Edge":291,"../../Error":292,"rxjs/Observable":29,"rxjs/Subject":34,"virtual-dom":246}],348:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
-var GeometryTagError_1 = require("./error/GeometryTagError");
-exports.GeometryTagError = GeometryTagError_1.GeometryTagError;
-var PointGeometry_1 = require("./geometry/PointGeometry");
-exports.PointGeometry = PointGeometry_1.PointGeometry;
-var RectGeometry_1 = require("./geometry/RectGeometry");
-exports.RectGeometry = RectGeometry_1.RectGeometry;
-var PolygonGeometry_1 = require("./geometry/PolygonGeometry");
-exports.PolygonGeometry = PolygonGeometry_1.PolygonGeometry;
-var OutlineTag_1 = require("./tag/OutlineTag");
-exports.OutlineTag = OutlineTag_1.OutlineTag;
-var SpotTag_1 = require("./tag/SpotTag");
-exports.SpotTag = SpotTag_1.SpotTag;
-var TagComponent_1 = require("./TagComponent");
-exports.TagComponent = TagComponent_1.TagComponent;
-var TagMode_1 = require("./TagMode");
-exports.TagMode = TagMode_1.TagMode;
+var SequenceMode;
+(function (SequenceMode) {
+    SequenceMode[SequenceMode["Default"] = 0] = "Default";
+    SequenceMode[SequenceMode["Playback"] = 1] = "Playback";
+    SequenceMode[SequenceMode["Timeline"] = 2] = "Timeline";
+})(SequenceMode = exports.SequenceMode || (exports.SequenceMode = {}));
+exports.default = SequenceMode;
+
+},{}],349:[function(require,module,exports){
+"use strict";
+/// <reference path="../../../typings/index.d.ts" />
+Object.defineProperty(exports, "__esModule", { value: true });
+
+var path = require("path");
+var Shaders = /** @class */ (function () {
+    function Shaders() {
+    }
+    Shaders.equirectangular = {
+        fragment: "#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n\nuniform sampler2D projectorTex;\nuniform float opacity;\nuniform float phiLength;\nuniform float phiShift;\nuniform float thetaLength;\nuniform float thetaShift;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n    vec3 b = normalize(vRstq.xyz);\n    float lat = -asin(b.y);\n    float lon = atan(b.x, b.z);\n    float x = (lon - phiShift) / phiLength + 0.5;\n    float y = (lat - thetaShift) / thetaLength + 0.5;\n    vec4 baseColor = texture2D(projectorTex, vec2(x, y));\n    baseColor.a = opacity;\n    gl_FragColor = baseColor;\n}",
+        vertex: "#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform mat4 projectorMat;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n    vRstq = projectorMat * vec4(position, 1.0);\n    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}",
+    };
+    Shaders.equirectangularCurtain = {
+        fragment: "#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n\nuniform sampler2D projectorTex;\nuniform float curtain;\nuniform float opacity;\nuniform float phiLength;\nuniform float phiShift;\nuniform float thetaLength;\nuniform float thetaShift;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n    vec3 b = normalize(vRstq.xyz);\n    float lat = -asin(b.y);\n    float lon = atan(b.x, b.z);\n    float x = (lon - phiShift) / phiLength + 0.5;\n    float y = (lat - thetaShift) / thetaLength + 0.5;\n\n    bool inverted = curtain < 0.5;\n\n    float curtainMin = inverted ? curtain + 0.5 : curtain - 0.5;\n    float curtainMax = curtain;\n\n    bool insideCurtain = inverted ?\n        x > curtainMin || x < curtainMax :\n        x > curtainMin && x < curtainMax;\n\n    vec4 baseColor;\n    if (insideCurtain) {\n        baseColor = texture2D(projectorTex, vec2(x, y));\n        baseColor.a = opacity;\n    } else {\n        baseColor = vec4(0.0, 0.0, 0.0, 0.0);\n    }\n\n    gl_FragColor = baseColor;\n}",
+        vertex: "#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform mat4 projectorMat;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n    vRstq = projectorMat * vec4(position, 1.0);\n    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}",
+    };
+    Shaders.perspective = {
+        fragment: "#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n\nuniform sampler2D projectorTex;\nuniform float opacity;\nuniform vec4 bbox;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n    float x = vRstq.x / vRstq.w;\n    float y = vRstq.y / vRstq.w;\n\n    vec4 baseColor = texture2D(projectorTex, vec2(x, y));\n    baseColor.a = opacity;\n\n    gl_FragColor = baseColor;\n}",
+        vertex: "#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform mat4 projectorMat;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n    vRstq = projectorMat * vec4(position, 1.0);\n    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}",
+    };
+    Shaders.perspectiveCurtain = {
+        fragment: "#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n\nuniform sampler2D projectorTex;\nuniform float opacity;\nuniform float curtain;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n    float x = vRstq.x / vRstq.w;\n    float y = vRstq.y / vRstq.w;\n\n    vec4 baseColor;\n    if (x < curtain || curtain >= 1.0) {\n        baseColor = texture2D(projectorTex, vec2(x, y));\n        baseColor.a = opacity;\n    } else {\n        baseColor = vec4(0.0, 0.0, 0.0, 0.0);\n    }\n\n    gl_FragColor = baseColor;\n}\n",
+        vertex: "#ifdef GL_ES\nprecision highp float;\n#endif\n\nuniform mat4 projectorMat;\n\nvarying vec4 vRstq;\n\nvoid main()\n{\n    vRstq = projectorMat * vec4(position, 1.0);\n    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}",
+    };
+    return Shaders;
+}());
+exports.Shaders = Shaders;
 
-},{"./TagComponent":345,"./TagMode":348,"./error/GeometryTagError":352,"./geometry/PointGeometry":354,"./geometry/PolygonGeometry":355,"./geometry/RectGeometry":356,"./tag/OutlineTag":368,"./tag/SpotTag":371}],345:[function(require,module,exports){
+},{"path":22}],350:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -30118,316 +30001,1502 @@ var __extends = (this && this.__extends) || (function () {
     };
 })();
 Object.defineProperty(exports, "__esModule", { value: true });
-var when = require("when");
 var Observable_1 = require("rxjs/Observable");
-require("rxjs/add/observable/combineLatest");
-require("rxjs/add/observable/empty");
-require("rxjs/add/observable/from");
-require("rxjs/add/observable/merge");
-require("rxjs/add/observable/of");
-require("rxjs/add/operator/combineLatest");
-require("rxjs/add/operator/concat");
-require("rxjs/add/operator/distinctUntilChanged");
-require("rxjs/add/operator/do");
-require("rxjs/add/operator/filter");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/merge");
-require("rxjs/add/operator/mergeMap");
-require("rxjs/add/operator/publishReplay");
-require("rxjs/add/operator/scan");
-require("rxjs/add/operator/share");
-require("rxjs/add/operator/skip");
-require("rxjs/add/operator/skipUntil");
-require("rxjs/add/operator/startWith");
-require("rxjs/add/operator/switchMap");
-require("rxjs/add/operator/take");
-require("rxjs/add/operator/takeUntil");
-require("rxjs/add/operator/withLatestFrom");
+var Subject_1 = require("rxjs/Subject");
 var Component_1 = require("../../Component");
 var Geo_1 = require("../../Geo");
+var State_1 = require("../../State");
 var Render_1 = require("../../Render");
+var Tiles_1 = require("../../Tiles");
+var Utils_1 = require("../../Utils");
 /**
- * @class TagComponent
- *
- * @classdesc Component for showing and editing tags with different
- * geometries composed from 2D basic image coordinates (see the
- * {@link Viewer} class documentation for more information about coordinate
- * systems).
- *
- * The `add` method is used for adding new tags or replacing
- * tags already in the set. Tags are removed by id.
- *
- * If a tag already in the set has the same
- * id as one of the tags added, the old tag will be removed and
- * the added tag will take its place.
- *
- * The tag component mode can be set to either be non interactive or
- * to be in creating mode of a certain geometry type.
+ * @class SliderComponent
  *
- * The tag properties can be updated at any time and the change will
- * be visibile immediately.
+ * @classdesc Component for comparing pairs of images. Renders
+ * a slider for adjusting the curtain of the first image.
  *
- * Tags are only relevant to a single image because they are based on
- * 2D basic image coordinates. Tags related to a certain image should
- * be removed when the viewer is moved to another node.
+ * Deactivate the sequence, direction and image plane
+ * components when activating the slider component to avoid
+ * interfering UI elements.
  *
- * To retrive and use the tag component
+ * To retrive and use the marker component
  *
  * @example
  * ```
  * var viewer = new Mapillary.Viewer(
  *     "<element-id>",
  *     "<client-id>",
- *     "<my key>",
- *     { component: { tag: true } });
+ *     "<my key>");
  *
- * var tagComponent = viewer.getComponent("tag");
+ * viewer.deactivateComponent("imagePlane");
+ * viewer.deactivateComponent("direction");
+ * viewer.deactivateComponent("sequence");
+ *
+ * viewer.activateComponent("slider");
+ *
+ * var sliderComponent = viewer.getComponent("marker");
  * ```
  */
-var TagComponent = /** @class */ (function (_super) {
-    __extends(TagComponent, _super);
-    function TagComponent(name, container, navigator) {
+var SliderComponent = /** @class */ (function (_super) {
+    __extends(SliderComponent, _super);
+    function SliderComponent(name, container, navigator, viewportCoords) {
         var _this = _super.call(this, name, container, navigator) || this;
-        _this._tagDomRenderer = new Component_1.TagDOMRenderer();
-        _this._tagScene = new Component_1.TagScene();
-        _this._tagSet = new Component_1.TagSet();
-        _this._tagCreator = new Component_1.TagCreator(_this, navigator);
-        _this._viewportCoords = new Geo_1.ViewportCoords();
-        _this._createHandlers = {
-            "CreatePoint": new Component_1.CreatePointHandler(_this, container, navigator, _this._viewportCoords, _this._tagCreator),
-            "CreatePolygon": new Component_1.CreatePolygonHandler(_this, container, navigator, _this._viewportCoords, _this._tagCreator),
-            "CreateRect": new Component_1.CreateRectHandler(_this, container, navigator, _this._viewportCoords, _this._tagCreator),
-            "CreateRectDrag": new Component_1.CreateRectDragHandler(_this, container, navigator, _this._viewportCoords, _this._tagCreator),
-            "Default": undefined,
-        };
-        _this._editVertexHandler = new Component_1.EditVertexHandler(_this, container, navigator, _this._viewportCoords, _this._tagSet);
-        _this._renderTags$ = _this._tagSet.changed$
-            .map(function (tagSet) {
-            var tags = tagSet.getAll();
-            // ensure that tags are always rendered in the same order
-            // to avoid hover tracking problems on first resize.
-            tags.sort(function (t1, t2) {
-                var id1 = t1.tag.id;
-                var id2 = t2.tag.id;
-                if (id1 < id2) {
-                    return -1;
-                }
-                if (id1 > id2) {
-                    return 1;
-                }
-                return 0;
-            });
-            return tags;
-        })
-            .share();
-        _this._tagChanged$ = _this._renderTags$
-            .switchMap(function (tags) {
-            return Observable_1.Observable
-                .from(tags)
-                .mergeMap(function (tag) {
-                return Observable_1.Observable
-                    .merge(tag.tag.changed$, tag.tag.geometryChanged$);
-            });
-        })
-            .share();
-        _this._renderTagGLChanged$ = _this._renderTags$
-            .switchMap(function (tags) {
-            return Observable_1.Observable
-                .from(tags)
-                .mergeMap(function (tag) {
-                return tag.glObjectsChanged$;
-            });
-        })
-            .share();
-        _this._createGeometryChanged$ = _this._tagCreator.tag$
-            .switchMap(function (tag) {
-            return tag != null ?
-                tag.geometryChanged$ :
-                Observable_1.Observable.empty();
+        _this._viewportCoords = !!viewportCoords ? viewportCoords : new Geo_1.ViewportCoords();
+        _this._domRenderer = new Component_1.SliderDOMRenderer(container);
+        _this._imageTileLoader = new Tiles_1.ImageTileLoader(Utils_1.Urls.tileScheme, Utils_1.Urls.tileDomain, Utils_1.Urls.origin);
+        _this._roiCalculator = new Tiles_1.RegionOfInterestCalculator();
+        _this._spatial = new Geo_1.Spatial();
+        _this._glRendererOperation$ = new Subject_1.Subject();
+        _this._glRendererCreator$ = new Subject_1.Subject();
+        _this._glRendererDisposer$ = new Subject_1.Subject();
+        _this._glRenderer$ = _this._glRendererOperation$
+            .scan(function (glRenderer, operation) {
+            return operation(glRenderer);
+        }, null)
+            .filter(function (glRenderer) {
+            return glRenderer != null;
         })
-            .share();
-        _this._createGLObjectsChanged$ = _this._tagCreator.tag$
-            .switchMap(function (tag) {
-            return tag != null ?
-                tag.glObjectsChanged$ :
-                Observable_1.Observable.empty();
+            .distinctUntilChanged(undefined, function (glRenderer) {
+            return glRenderer.frameId;
+        });
+        _this._glRendererCreator$
+            .map(function () {
+            return function (glRenderer) {
+                if (glRenderer != null) {
+                    throw new Error("Multiple slider states can not be created at the same time");
+                }
+                return new Component_1.SliderGLRenderer();
+            };
         })
-            .share();
-        _this._creatingConfiguration$ = _this._configuration$
-            .distinctUntilChanged(function (c1, c2) {
-            return c1.mode === c2.mode;
-        }, function (configuration) {
-            return {
-                createColor: configuration.createColor,
-                mode: configuration.mode,
+            .subscribe(_this._glRendererOperation$);
+        _this._glRendererDisposer$
+            .map(function () {
+            return function (glRenderer) {
+                glRenderer.dispose();
+                return null;
             };
         })
-            .publishReplay(1)
-            .refCount();
-        _this._creatingConfiguration$
-            .subscribe(function (configuration) {
-            _this.fire(TagComponent.modechanged, configuration.mode);
-        });
+            .subscribe(_this._glRendererOperation$);
         return _this;
     }
     /**
-     * Add tags to the tag set or replace tags in the tag set.
-     *
-     * @description If a tag already in the set has the same
-     * id as one of the tags added, the old tag will be removed
-     * the added tag will take its place.
+     * Set the initial position.
      *
-     * @param {Array<Tag>} tags - Tags to add.
+     * @description Configures the intial position of the slider.
+     * The inital position value will be used when the component
+     * is activated.
      *
-     * @example ```tagComponent.add([tag1, tag2]);```
+     * @param {number} initialPosition - Initial slider position.
      */
-    TagComponent.prototype.add = function (tags) {
-        var _this = this;
-        if (this._activated) {
-            this._navigator.stateService.currentTransform$
-                .first()
-                .subscribe(function (transform) {
-                _this._tagSet.add(tags, transform);
-                var renderTags = tags
-                    .map(function (tag) {
-                    return _this._tagSet.get(tag.id);
-                });
-                _this._tagScene.add(renderTags);
-            });
-        }
-        else {
-            this._tagSet.addDeactivated(tags);
-        }
+    SliderComponent.prototype.setInitialPosition = function (initialPosition) {
+        this.configure({ initialPosition: initialPosition });
     };
     /**
-     * Change the current tag mode.
-     *
-     * @description Change the tag mode to one of the create modes for creating new geometries.
-     *
-     * @param {TagMode} mode - New tag mode.
+     * Set the image keys.
      *
-     * @fires TagComponent#modechanged
+     * @description Configures the component to show the image
+     * planes for the supplied image keys.
      *
-     * @example ```tagComponent.changeMode(Mapillary.TagComponent.TagMode.CreateRect);```
+     * @param {ISliderKeys} keys - Slider keys object specifying
+     * the images to be shown in the foreground and the background.
      */
-    TagComponent.prototype.changeMode = function (mode) {
-        this.configure({ mode: mode });
+    SliderComponent.prototype.setKeys = function (keys) {
+        this.configure({ keys: keys });
     };
     /**
-     * Returns the tag in the tag set with the specified id, or
-     * undefined if the id matches no tag.
+     * Set the slider mode.
      *
-     * @param {string} tagId - Id of the tag.
+     * @description Configures the mode for transitions between
+     * image pairs.
      *
-     * @example ```var tag = tagComponent.get("tagId");```
+     * @param {SliderMode} mode - Slider mode to be set.
      */
-    TagComponent.prototype.get = function (tagId) {
-        if (this._activated) {
-            var renderTag = this._tagSet.get(tagId);
-            return renderTag !== undefined ? renderTag.tag : undefined;
-        }
-        else {
-            return this._tagSet.getDeactivated(tagId);
-        }
+    SliderComponent.prototype.setSliderMode = function (mode) {
+        this.configure({ mode: mode });
     };
     /**
-     * Returns an array of all tags.
+     * Set the value controlling if the slider is visible.
      *
-     * @example ```var tags = tagComponent.getAll();```
+     * @param {boolean} sliderVisible - Value indicating if
+     * the slider should be visible or not.
      */
-    TagComponent.prototype.getAll = function () {
-        if (this.activated) {
-            return this._tagSet
-                .getAll()
-                .map(function (renderTag) {
-                return renderTag.tag;
-            });
-        }
-        else {
-            return this._tagSet.getAllDeactivated();
-        }
+    SliderComponent.prototype.setSliderVisible = function (sliderVisible) {
+        this.configure({ sliderVisible: sliderVisible });
     };
-    /**
-     * Returns an array of tag ids for tags that contain the specified point.
-     *
-     * @description The pixel point must lie inside the polygon or rectangle
-     * of an added tag for the tag id to be returned. Tag ids for
-     * tags that do not have a fill will also be returned if the point is inside
-     * the geometry of the tag. Tags with point geometries can not be retrieved.
-     *
-     * No tag ids will be returned for panoramas.
-     *
-     * Notice that the pixelPoint argument requires x, y coordinates from pixel space.
-     *
-     * With this function, you can use the coordinates provided by mouse
-     * events to get information out of the tag component.
-     *
-     * If no tag at exist the pixel point, an empty array will be returned.
-     *
-     * @param {Array<number>} pixelPoint - Pixel coordinates on the viewer element.
-     * @returns {Array<string>} Ids of the tags that contain the specified pixel point.
-     *
-     * @example
-     * ```
-     * tagComponent.getTagIdsAt([100, 100])
-     *     .then((tagIds) => { console.log(tagIds); });
-     * ```
-     */
-    TagComponent.prototype.getTagIdsAt = function (pixelPoint) {
+    SliderComponent.prototype._activate = function () {
         var _this = this;
-        return when.promise(function (resolve, reject) {
-            _this._container.renderService.renderCamera$
-                .first()
-                .map(function (render) {
-                var viewport = _this._viewportCoords
-                    .canvasToViewport(pixelPoint[0], pixelPoint[1], _this._container.element);
-                var ids = _this._tagScene.intersectObjects(viewport, render.perspective);
-                return ids;
-            })
-                .subscribe(function (ids) {
-                resolve(ids);
-            }, function (error) {
-                reject(error);
-            });
+        this._modeSubcription = this._domRenderer.mode$
+            .subscribe(function (mode) {
+            _this.setSliderMode(mode);
         });
-    };
-    /**
-     * Check if a tag exist in the tag set.
-     *
-     * @param {string} tagId - Id of the tag.
-     *
-     * @example ```var tagExists = tagComponent.has("tagId");```
-     */
-    TagComponent.prototype.has = function (tagId) {
-        return this._activated ? this._tagSet.has(tagId) : this._tagSet.hasDeactivated(tagId);
-    };
-    /**
-     * Remove tags with the specified ids from the tag set.
-     *
-     * @param {Array<string>} tagIds - Ids for tags to remove.
-     *
-     * @example ```tagComponent.remove(["id-1", "id-2"]);```
-     */
-    TagComponent.prototype.remove = function (tagIds) {
-        if (this._activated) {
-            this._tagSet.remove(tagIds);
-            this._tagScene.remove(tagIds);
-        }
-        else {
-            this._tagSet.removeDeactivated(tagIds);
-        }
-    };
-    /**
-     * Remove all tags from the tag set.
-     *
-     * @example ```tagComponent.removeAll();```
-     */
-    TagComponent.prototype.removeAll = function () {
-        if (this._activated) {
-            this._tagSet.removeAll();
-            this._tagScene.removeAll();
-        }
-        else {
+        this._glRenderSubscription = this._glRenderer$
+            .map(function (glRenderer) {
+            var renderHash = {
+                name: _this._name,
+                render: {
+                    frameId: glRenderer.frameId,
+                    needsRender: glRenderer.needsRender,
+                    render: glRenderer.render.bind(glRenderer),
+                    stage: Render_1.GLRenderStage.Background,
+                },
+            };
+            return renderHash;
+        })
+            .subscribe(this._container.glRenderer.render$);
+        var position$ = this.configuration$
+            .map(function (configuration) {
+            return configuration.initialPosition != null ?
+                configuration.initialPosition : 1;
+        })
+            .first()
+            .concat(this._domRenderer.position$);
+        var mode$ = this.configuration$
+            .map(function (configuration) {
+            return configuration.mode;
+        })
+            .distinctUntilChanged();
+        var motionless$ = this._navigator.stateService.currentState$
+            .map(function (frame) {
+            return frame.state.motionless;
+        })
+            .distinctUntilChanged();
+        var fullPano$ = this._navigator.stateService.currentState$
+            .map(function (frame) {
+            return frame.state.currentNode.fullPano;
+        })
+            .distinctUntilChanged();
+        var sliderVisible$ = Observable_1.Observable
+            .combineLatest(this._configuration$
+            .map(function (configuration) {
+            return configuration.sliderVisible;
+        }), this._navigator.stateService.currentState$
+            .map(function (frame) {
+            return !(frame.state.currentNode == null ||
+                frame.state.previousNode == null ||
+                (frame.state.currentNode.pano && !frame.state.currentNode.fullPano) ||
+                (frame.state.previousNode.pano && !frame.state.previousNode.fullPano) ||
+                (frame.state.currentNode.fullPano && !frame.state.previousNode.fullPano));
+        })
+            .distinctUntilChanged())
+            .map(function (_a) {
+            var sliderVisible = _a[0], enabledState = _a[1];
+            return sliderVisible && enabledState;
+        })
+            .distinctUntilChanged();
+        this._waitSubscription = Observable_1.Observable
+            .combineLatest(mode$, motionless$, fullPano$, sliderVisible$)
+            .withLatestFrom(this._navigator.stateService.state$)
+            .subscribe(function (_a) {
+            var _b = _a[0], mode = _b[0], motionless = _b[1], fullPano = _b[2], sliderVisible = _b[3], state = _a[1];
+            var interactive = sliderVisible &&
+                (motionless || mode === Component_1.SliderMode.Stationary || fullPano);
+            if (interactive && state !== State_1.State.WaitingInteractively) {
+                _this._navigator.stateService.waitInteractively();
+            }
+            else if (!interactive && state !== State_1.State.Waiting) {
+                _this._navigator.stateService.wait();
+            }
+        });
+        this._moveSubscription = Observable_1.Observable
+            .combineLatest(position$, mode$, motionless$, fullPano$, sliderVisible$)
+            .subscribe(function (_a) {
+            var position = _a[0], mode = _a[1], motionless = _a[2], fullPano = _a[3], sliderVisible = _a[4];
+            if (motionless || mode === Component_1.SliderMode.Stationary || fullPano) {
+                _this._navigator.stateService.moveTo(1);
+            }
+            else {
+                _this._navigator.stateService.moveTo(position);
+            }
+        });
+        this._domRenderSubscription = Observable_1.Observable
+            .combineLatest(position$, mode$, motionless$, fullPano$, sliderVisible$, this._container.renderService.size$)
+            .map(function (_a) {
+            var position = _a[0], mode = _a[1], motionless = _a[2], fullPano = _a[3], sliderVisible = _a[4], size = _a[5];
+            return {
+                name: _this._name,
+                vnode: _this._domRenderer.render(position, mode, motionless, fullPano, sliderVisible),
+            };
+        })
+            .subscribe(this._container.domRenderer.render$);
+        this._glRendererCreator$.next(null);
+        this._updateCurtainSubscription = Observable_1.Observable
+            .combineLatest(position$, fullPano$, sliderVisible$, this._container.renderService.renderCamera$, this._navigator.stateService.currentTransform$)
+            .map(function (_a) {
+            var position = _a[0], fullPano = _a[1], visible = _a[2], render = _a[3], transform = _a[4];
+            if (!fullPano) {
+                return visible ? position : 1;
+            }
+            var basicMin = _this._viewportCoords.viewportToBasic(-1.15, 0, transform, render.perspective);
+            var basicMax = _this._viewportCoords.viewportToBasic(1.15, 0, transform, render.perspective);
+            var shiftedMax = basicMax[0] < basicMin[0] ? basicMax[0] + 1 : basicMax[0];
+            var basicPosition = basicMin[0] + position * (shiftedMax - basicMin[0]);
+            return basicPosition > 1 ? basicPosition - 1 : basicPosition;
+        })
+            .map(function (position) {
+            return function (glRenderer) {
+                glRenderer.updateCurtain(position);
+                return glRenderer;
+            };
+        })
+            .subscribe(this._glRendererOperation$);
+        this._stateSubscription = Observable_1.Observable
+            .combineLatest(this._navigator.stateService.currentState$, mode$)
+            .map(function (_a) {
+            var frame = _a[0], mode = _a[1];
+            return function (glRenderer) {
+                glRenderer.update(frame, mode);
+                return glRenderer;
+            };
+        })
+            .subscribe(this._glRendererOperation$);
+        this._setKeysSubscription = this._configuration$
+            .filter(function (configuration) {
+            return configuration.keys != null;
+        })
+            .switchMap(function (configuration) {
+            return Observable_1.Observable
+                .zip(_this._catchCacheNode$(configuration.keys.background), _this._catchCacheNode$(configuration.keys.foreground))
+                .map(function (nodes) {
+                return { background: nodes[0], foreground: nodes[1] };
+            })
+                .zip(_this._navigator.stateService.currentState$.first())
+                .map(function (nf) {
+                return { nodes: nf[0], state: nf[1].state };
+            });
+        })
+            .subscribe(function (co) {
+            if (co.state.currentNode != null &&
+                co.state.previousNode != null &&
+                co.state.currentNode.key === co.nodes.foreground.key &&
+                co.state.previousNode.key === co.nodes.background.key) {
+                return;
+            }
+            if (co.state.currentNode.key === co.nodes.background.key) {
+                _this._navigator.stateService.setNodes([co.nodes.foreground]);
+                return;
+            }
+            if (co.state.currentNode.key === co.nodes.foreground.key &&
+                co.state.trajectory.length === 1) {
+                _this._navigator.stateService.prependNodes([co.nodes.background]);
+                return;
+            }
+            _this._navigator.stateService.setNodes([co.nodes.background]);
+            _this._navigator.stateService.setNodes([co.nodes.foreground]);
+        }, function (e) {
+            console.error(e);
+        });
+        var previousNode$ = this._navigator.stateService.currentState$
+            .map(function (frame) {
+            return frame.state.previousNode;
+        })
+            .filter(function (node) {
+            return node != null;
+        })
+            .distinctUntilChanged(undefined, function (node) {
+            return node.key;
+        });
+        var textureProvider$ = this._navigator.stateService.currentState$
+            .distinctUntilChanged(undefined, function (frame) {
+            return frame.state.currentNode.key;
+        })
+            .withLatestFrom(this._container.glRenderer.webGLRenderer$, this._container.renderService.size$)
+            .map(function (_a) {
+            var frame = _a[0], renderer = _a[1], size = _a[2];
+            var state = frame.state;
+            var viewportSize = Math.max(size.width, size.height);
+            var currentNode = state.currentNode;
+            var currentTransform = state.currentTransform;
+            var tileSize = viewportSize > 2048 ? 2048 : viewportSize > 1024 ? 1024 : 512;
+            return new Tiles_1.TextureProvider(currentNode.key, currentTransform.basicWidth, currentTransform.basicHeight, tileSize, currentNode.image, _this._imageTileLoader, new Tiles_1.ImageTileStore(), renderer);
+        })
+            .publishReplay(1)
+            .refCount();
+        this._textureProviderSubscription = textureProvider$.subscribe(function () { });
+        this._setTextureProviderSubscription = textureProvider$
+            .map(function (provider) {
+            return function (renderer) {
+                renderer.setTextureProvider(provider.key, provider);
+                return renderer;
+            };
+        })
+            .subscribe(this._glRendererOperation$);
+        this._setTileSizeSubscription = this._container.renderService.size$
+            .switchMap(function (size) {
+            return Observable_1.Observable
+                .combineLatest(textureProvider$, Observable_1.Observable.of(size))
+                .first();
+        })
+            .subscribe(function (_a) {
+            var provider = _a[0], size = _a[1];
+            var viewportSize = Math.max(size.width, size.height);
+            var tileSize = viewportSize > 2048 ? 2048 : viewportSize > 1024 ? 1024 : 512;
+            provider.setTileSize(tileSize);
+        });
+        this._abortTextureProviderSubscription = textureProvider$
+            .pairwise()
+            .subscribe(function (pair) {
+            var previous = pair[0];
+            previous.abort();
+        });
+        var roiTrigger$ = Observable_1.Observable
+            .combineLatest(this._container.renderService.renderCameraFrame$, this._container.renderService.size$.debounceTime(250))
+            .map(function (_a) {
+            var camera = _a[0], size = _a[1];
+            return [
+                camera.camera.position.clone(),
+                camera.camera.lookat.clone(),
+                camera.zoom.valueOf(),
+                size.height.valueOf(),
+                size.width.valueOf()
+            ];
+        })
+            .pairwise()
+            .skipWhile(function (pls) {
+            return pls[1][2] - pls[0][2] < 0 || pls[1][2] === 0;
+        })
+            .map(function (pls) {
+            var samePosition = pls[0][0].equals(pls[1][0]);
+            var sameLookat = pls[0][1].equals(pls[1][1]);
+            var sameZoom = pls[0][2] === pls[1][2];
+            var sameHeight = pls[0][3] === pls[1][3];
+            var sameWidth = pls[0][4] === pls[1][4];
+            return samePosition && sameLookat && sameZoom && sameHeight && sameWidth;
+        })
+            .distinctUntilChanged()
+            .filter(function (stalled) {
+            return stalled;
+        })
+            .switchMap(function (stalled) {
+            return _this._container.renderService.renderCameraFrame$
+                .first();
+        })
+            .withLatestFrom(this._container.renderService.size$, this._navigator.stateService.currentTransform$);
+        this._setRegionOfInterestSubscription = textureProvider$
+            .switchMap(function (provider) {
+            return roiTrigger$
+                .map(function (_a) {
+                var camera = _a[0], size = _a[1], transform = _a[2];
+                return [
+                    _this._roiCalculator.computeRegionOfInterest(camera, size, transform),
+                    provider,
+                ];
+            });
+        })
+            .filter(function (args) {
+            return !args[1].disposed;
+        })
+            .subscribe(function (args) {
+            var roi = args[0];
+            var provider = args[1];
+            provider.setRegionOfInterest(roi);
+        });
+        var hasTexture$ = textureProvider$
+            .switchMap(function (provider) {
+            return provider.hasTexture$;
+        })
+            .startWith(false)
+            .publishReplay(1)
+            .refCount();
+        this._hasTextureSubscription = hasTexture$.subscribe(function () { });
+        var nodeImage$ = this._navigator.stateService.currentState$
+            .filter(function (frame) {
+            return frame.state.nodesAhead === 0;
+        })
+            .map(function (frame) {
+            return frame.state.currentNode;
+        })
+            .distinctUntilChanged(undefined, function (node) {
+            return node.key;
+        })
+            .debounceTime(1000)
+            .withLatestFrom(hasTexture$)
+            .filter(function (args) {
+            return !args[1];
+        })
+            .map(function (args) {
+            return args[0];
+        })
+            .filter(function (node) {
+            return node.pano ?
+                Utils_1.Settings.maxImageSize > Utils_1.Settings.basePanoramaSize :
+                Utils_1.Settings.maxImageSize > Utils_1.Settings.baseImageSize;
+        })
+            .switchMap(function (node) {
+            var baseImageSize = node.pano ?
+                Utils_1.Settings.basePanoramaSize :
+                Utils_1.Settings.baseImageSize;
+            if (Math.max(node.image.width, node.image.height) > baseImageSize) {
+                return Observable_1.Observable.empty();
+            }
+            var image$ = node
+                .cacheImage$(Utils_1.Settings.maxImageSize)
+                .map(function (n) {
+                return [n.image, n];
+            });
+            return image$
+                .takeUntil(hasTexture$
+                .filter(function (hasTexture) {
+                return hasTexture;
+            }))
+                .catch(function (error, caught) {
+                console.error("Failed to fetch high res image (" + node.key + ")", error);
+                return Observable_1.Observable.empty();
+            });
+        })
+            .publish()
+            .refCount();
+        this._updateBackgroundSubscription = nodeImage$
+            .withLatestFrom(textureProvider$)
+            .subscribe(function (args) {
+            if (args[0][1].key !== args[1].key ||
+                args[1].disposed) {
+                return;
+            }
+            args[1].updateBackground(args[0][0]);
+        });
+        this._updateTextureImageSubscription = nodeImage$
+            .map(function (imn) {
+            return function (renderer) {
+                renderer.updateTextureImage(imn[0], imn[1]);
+                return renderer;
+            };
+        })
+            .subscribe(this._glRendererOperation$);
+        var textureProviderPrev$ = this._navigator.stateService.currentState$
+            .filter(function (frame) {
+            return !!frame.state.previousNode;
+        })
+            .distinctUntilChanged(undefined, function (frame) {
+            return frame.state.previousNode.key;
+        })
+            .withLatestFrom(this._container.glRenderer.webGLRenderer$, this._container.renderService.size$)
+            .map(function (_a) {
+            var frame = _a[0], renderer = _a[1], size = _a[2];
+            var state = frame.state;
+            var viewportSize = Math.max(size.width, size.height);
+            var previousNode = state.previousNode;
+            var previousTransform = state.previousTransform;
+            var tileSize = viewportSize > 2048 ? 2048 : viewportSize > 1024 ? 1024 : 512;
+            return new Tiles_1.TextureProvider(previousNode.key, previousTransform.basicWidth, previousTransform.basicHeight, tileSize, previousNode.image, _this._imageTileLoader, new Tiles_1.ImageTileStore(), renderer);
+        })
+            .publishReplay(1)
+            .refCount();
+        this._textureProviderSubscriptionPrev = textureProviderPrev$.subscribe(function () { });
+        this._setTextureProviderSubscriptionPrev = textureProviderPrev$
+            .map(function (provider) {
+            return function (renderer) {
+                renderer.setTextureProviderPrev(provider.key, provider);
+                return renderer;
+            };
+        })
+            .subscribe(this._glRendererOperation$);
+        this._setTileSizeSubscriptionPrev = this._container.renderService.size$
+            .switchMap(function (size) {
+            return Observable_1.Observable
+                .combineLatest(textureProviderPrev$, Observable_1.Observable.of(size))
+                .first();
+        })
+            .subscribe(function (_a) {
+            var provider = _a[0], size = _a[1];
+            var viewportSize = Math.max(size.width, size.height);
+            var tileSize = viewportSize > 2048 ? 2048 : viewportSize > 1024 ? 1024 : 512;
+            provider.setTileSize(tileSize);
+        });
+        this._abortTextureProviderSubscriptionPrev = textureProviderPrev$
+            .pairwise()
+            .subscribe(function (pair) {
+            var previous = pair[0];
+            previous.abort();
+        });
+        var roiTriggerPrev$ = Observable_1.Observable
+            .combineLatest(this._container.renderService.renderCameraFrame$, this._container.renderService.size$.debounceTime(250))
+            .map(function (_a) {
+            var camera = _a[0], size = _a[1];
+            return [
+                camera.camera.position.clone(),
+                camera.camera.lookat.clone(),
+                camera.zoom.valueOf(),
+                size.height.valueOf(),
+                size.width.valueOf()
+            ];
+        })
+            .pairwise()
+            .skipWhile(function (pls) {
+            return pls[1][2] - pls[0][2] < 0 || pls[1][2] === 0;
+        })
+            .map(function (pls) {
+            var samePosition = pls[0][0].equals(pls[1][0]);
+            var sameLookat = pls[0][1].equals(pls[1][1]);
+            var sameZoom = pls[0][2] === pls[1][2];
+            var sameHeight = pls[0][3] === pls[1][3];
+            var sameWidth = pls[0][4] === pls[1][4];
+            return samePosition && sameLookat && sameZoom && sameHeight && sameWidth;
+        })
+            .distinctUntilChanged()
+            .filter(function (stalled) {
+            return stalled;
+        })
+            .switchMap(function (stalled) {
+            return _this._container.renderService.renderCameraFrame$
+                .first();
+        })
+            .withLatestFrom(this._container.renderService.size$, this._navigator.stateService.currentTransform$);
+        this._setRegionOfInterestSubscriptionPrev = textureProviderPrev$
+            .switchMap(function (provider) {
+            return roiTriggerPrev$
+                .map(function (_a) {
+                var camera = _a[0], size = _a[1], transform = _a[2];
+                return [
+                    _this._roiCalculator.computeRegionOfInterest(camera, size, transform),
+                    provider,
+                ];
+            });
+        })
+            .filter(function (args) {
+            return !args[1].disposed;
+        })
+            .withLatestFrom(this._navigator.stateService.currentState$)
+            .subscribe(function (_a) {
+            var _b = _a[0], roi = _b[0], provider = _b[1], frame = _a[1];
+            var shiftedRoi = null;
+            if (frame.state.previousNode.fullPano) {
+                if (frame.state.currentNode.fullPano) {
+                    var currentViewingDirection = _this._spatial.viewingDirection(frame.state.currentNode.rotation);
+                    var previousViewingDirection = _this._spatial.viewingDirection(frame.state.previousNode.rotation);
+                    var directionDiff = _this._spatial.angleBetweenVector2(currentViewingDirection.x, currentViewingDirection.y, previousViewingDirection.x, previousViewingDirection.y);
+                    var shift = directionDiff / (2 * Math.PI);
+                    var bbox = {
+                        maxX: _this._spatial.wrap(roi.bbox.maxX + shift, 0, 1),
+                        maxY: roi.bbox.maxY,
+                        minX: _this._spatial.wrap(roi.bbox.minX + shift, 0, 1),
+                        minY: roi.bbox.minY,
+                    };
+                    shiftedRoi = {
+                        bbox: bbox,
+                        pixelHeight: roi.pixelHeight,
+                        pixelWidth: roi.pixelWidth,
+                    };
+                }
+                else {
+                    var currentViewingDirection = _this._spatial.viewingDirection(frame.state.currentNode.rotation);
+                    var previousViewingDirection = _this._spatial.viewingDirection(frame.state.previousNode.rotation);
+                    var directionDiff = _this._spatial.angleBetweenVector2(currentViewingDirection.x, currentViewingDirection.y, previousViewingDirection.x, previousViewingDirection.y);
+                    var shiftX = directionDiff / (2 * Math.PI);
+                    var a1 = _this._spatial.angleToPlane(currentViewingDirection.toArray(), [0, 0, 1]);
+                    var a2 = _this._spatial.angleToPlane(previousViewingDirection.toArray(), [0, 0, 1]);
+                    var shiftY = (a2 - a1) / (2 * Math.PI);
+                    var currentTransform = frame.state.currentTransform;
+                    var size = Math.max(currentTransform.basicWidth, currentTransform.basicHeight);
+                    var hFov = size > 0 ?
+                        2 * Math.atan(0.5 * currentTransform.basicWidth / (size * currentTransform.focal)) :
+                        Math.PI / 3;
+                    var vFov = size > 0 ?
+                        2 * Math.atan(0.5 * currentTransform.basicHeight / (size * currentTransform.focal)) :
+                        Math.PI / 3;
+                    var spanningWidth = hFov / (2 * Math.PI);
+                    var spanningHeight = vFov / Math.PI;
+                    var basicWidth = (roi.bbox.maxX - roi.bbox.minX) * spanningWidth;
+                    var basicHeight = (roi.bbox.maxY - roi.bbox.minY) * spanningHeight;
+                    var pixelWidth = roi.pixelWidth * spanningWidth;
+                    var pixelHeight = roi.pixelHeight * spanningHeight;
+                    var zoomShiftX = (roi.bbox.minX + roi.bbox.maxX) / 2 - 0.5;
+                    var zoomShiftY = (roi.bbox.minY + roi.bbox.maxY) / 2 - 0.5;
+                    var minX = 0.5 + shiftX + spanningWidth * zoomShiftX - basicWidth / 2;
+                    var maxX = 0.5 + shiftX + spanningWidth * zoomShiftX + basicWidth / 2;
+                    var minY = 0.5 + shiftY + spanningHeight * zoomShiftY - basicHeight / 2;
+                    var maxY = 0.5 + shiftY + spanningHeight * zoomShiftY + basicHeight / 2;
+                    var bbox = {
+                        maxX: _this._spatial.wrap(maxX, 0, 1),
+                        maxY: maxY,
+                        minX: _this._spatial.wrap(minX, 0, 1),
+                        minY: minY,
+                    };
+                    shiftedRoi = {
+                        bbox: bbox,
+                        pixelHeight: pixelHeight,
+                        pixelWidth: pixelWidth,
+                    };
+                }
+            }
+            else {
+                var currentBasicAspect = frame.state.currentTransform.basicAspect;
+                var previousBasicAspect = frame.state.previousTransform.basicAspect;
+                var _c = _this._getBasicCorners(currentBasicAspect, previousBasicAspect), _d = _c[0], cornerMinX = _d[0], cornerMinY = _d[1], _e = _c[1], cornerMaxX = _e[0], cornerMaxY = _e[1];
+                var basicWidth = cornerMaxX - cornerMinX;
+                var basicHeight = cornerMaxY - cornerMinY;
+                var pixelWidth = roi.pixelWidth / basicWidth;
+                var pixelHeight = roi.pixelHeight / basicHeight;
+                var minX = (basicWidth - 1) / (2 * basicWidth) + roi.bbox.minX / basicWidth;
+                var maxX = (basicWidth - 1) / (2 * basicWidth) + roi.bbox.maxX / basicWidth;
+                var minY = (basicHeight - 1) / (2 * basicHeight) + roi.bbox.minY / basicHeight;
+                var maxY = (basicHeight - 1) / (2 * basicHeight) + roi.bbox.maxY / basicHeight;
+                var bbox = {
+                    maxX: maxX,
+                    maxY: maxY,
+                    minX: minX,
+                    minY: minY,
+                };
+                _this._clipBoundingBox(bbox);
+                shiftedRoi = {
+                    bbox: bbox,
+                    pixelHeight: pixelHeight,
+                    pixelWidth: pixelWidth,
+                };
+            }
+            provider.setRegionOfInterest(shiftedRoi);
+        });
+        var hasTexturePrev$ = textureProviderPrev$
+            .switchMap(function (provider) {
+            return provider.hasTexture$;
+        })
+            .startWith(false)
+            .publishReplay(1)
+            .refCount();
+        this._hasTextureSubscriptionPrev = hasTexturePrev$.subscribe(function () { });
+        var nodeImagePrev$ = this._navigator.stateService.currentState$
+            .filter(function (frame) {
+            return frame.state.nodesAhead === 0 && !!frame.state.previousNode;
+        })
+            .map(function (frame) {
+            return frame.state.previousNode;
+        })
+            .distinctUntilChanged(undefined, function (node) {
+            return node.key;
+        })
+            .debounceTime(1000)
+            .withLatestFrom(hasTexturePrev$)
+            .filter(function (args) {
+            return !args[1];
+        })
+            .map(function (args) {
+            return args[0];
+        })
+            .filter(function (node) {
+            return node.pano ?
+                Utils_1.Settings.maxImageSize > Utils_1.Settings.basePanoramaSize :
+                Utils_1.Settings.maxImageSize > Utils_1.Settings.baseImageSize;
+        })
+            .switchMap(function (node) {
+            var baseImageSize = node.pano ?
+                Utils_1.Settings.basePanoramaSize :
+                Utils_1.Settings.baseImageSize;
+            if (Math.max(node.image.width, node.image.height) > baseImageSize) {
+                return Observable_1.Observable.empty();
+            }
+            var image$ = node
+                .cacheImage$(Utils_1.Settings.maxImageSize)
+                .map(function (n) {
+                return [n.image, n];
+            });
+            return image$
+                .takeUntil(hasTexturePrev$
+                .filter(function (hasTexture) {
+                return hasTexture;
+            }))
+                .catch(function (error, caught) {
+                console.error("Failed to fetch high res image (" + node.key + ")", error);
+                return Observable_1.Observable.empty();
+            });
+        })
+            .publish()
+            .refCount();
+        this._updateBackgroundSubscriptionPrev = nodeImagePrev$
+            .withLatestFrom(textureProviderPrev$)
+            .subscribe(function (args) {
+            if (args[0][1].key !== args[1].key ||
+                args[1].disposed) {
+                return;
+            }
+            args[1].updateBackground(args[0][0]);
+        });
+        this._updateTextureImageSubscriptionPrev = nodeImagePrev$
+            .map(function (imn) {
+            return function (renderer) {
+                renderer.updateTextureImage(imn[0], imn[1]);
+                return renderer;
+            };
+        })
+            .subscribe(this._glRendererOperation$);
+    };
+    SliderComponent.prototype._deactivate = function () {
+        var _this = this;
+        this._waitSubscription.unsubscribe();
+        this._navigator.stateService.state$
+            .first()
+            .subscribe(function (state) {
+            if (state !== State_1.State.Traversing) {
+                _this._navigator.stateService.traverse();
+            }
+        });
+        this._glRendererDisposer$.next(null);
+        this._domRenderer.deactivate();
+        this._modeSubcription.unsubscribe();
+        this._setKeysSubscription.unsubscribe();
+        this._stateSubscription.unsubscribe();
+        this._glRenderSubscription.unsubscribe();
+        this._domRenderSubscription.unsubscribe();
+        this._moveSubscription.unsubscribe();
+        this.configure({ keys: null });
+    };
+    SliderComponent.prototype._getDefaultConfiguration = function () {
+        return {
+            initialPosition: 1,
+            mode: Component_1.SliderMode.Motion,
+            sliderVisible: true,
+        };
+    };
+    SliderComponent.prototype._catchCacheNode$ = function (key) {
+        return this._navigator.graphService.cacheNode$(key)
+            .catch(function (error, caught) {
+            console.error("Failed to cache slider node (" + key + ")", error);
+            return Observable_1.Observable.empty();
+        });
+    };
+    SliderComponent.prototype._getBasicCorners = function (currentAspect, previousAspect) {
+        var offsetX;
+        var offsetY;
+        if (currentAspect > previousAspect) {
+            offsetX = 0.5;
+            offsetY = 0.5 * currentAspect / previousAspect;
+        }
+        else {
+            offsetX = 0.5 * previousAspect / currentAspect;
+            offsetY = 0.5;
+        }
+        return [[0.5 - offsetX, 0.5 - offsetY], [0.5 + offsetX, 0.5 + offsetY]];
+    };
+    SliderComponent.prototype._clipBoundingBox = function (bbox) {
+        bbox.minX = Math.max(0, Math.min(1, bbox.minX));
+        bbox.maxX = Math.max(0, Math.min(1, bbox.maxX));
+        bbox.minY = Math.max(0, Math.min(1, bbox.minY));
+        bbox.maxY = Math.max(0, Math.min(1, bbox.maxY));
+    };
+    SliderComponent.componentName = "slider";
+    return SliderComponent;
+}(Component_1.Component));
+exports.SliderComponent = SliderComponent;
+Component_1.ComponentService.register(SliderComponent);
+exports.default = SliderComponent;
+
+},{"../../Component":290,"../../Geo":293,"../../Render":296,"../../State":297,"../../Tiles":299,"../../Utils":300,"rxjs/Observable":29,"rxjs/Subject":34}],351:[function(require,module,exports){
+"use strict";
+/// <reference path="../../../typings/index.d.ts" />
+Object.defineProperty(exports, "__esModule", { value: true });
+var vd = require("virtual-dom");
+var Observable_1 = require("rxjs/Observable");
+var Subject_1 = require("rxjs/Subject");
+var Component_1 = require("../../Component");
+var SliderDOMRenderer = /** @class */ (function () {
+    function SliderDOMRenderer(container) {
+        this._container = container;
+        this._interacting = false;
+        this._notifyModeChanged$ = new Subject_1.Subject();
+        this._notifyPositionChanged$ = new Subject_1.Subject();
+        this._stopInteractionSubscription = null;
+    }
+    Object.defineProperty(SliderDOMRenderer.prototype, "mode$", {
+        get: function () {
+            return this._notifyModeChanged$;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(SliderDOMRenderer.prototype, "position$", {
+        get: function () {
+            return this._notifyPositionChanged$;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    SliderDOMRenderer.prototype.activate = function () {
+        var _this = this;
+        if (!!this._stopInteractionSubscription) {
+            return;
+        }
+        this._stopInteractionSubscription = Observable_1.Observable
+            .merge(this._container.mouseService.documentMouseUp$, this._container.touchService.touchEnd$
+            .filter(function (touchEvent) {
+            return touchEvent.touches.length === 0;
+        }))
+            .subscribe(function (event) {
+            if (_this._interacting) {
+                _this._interacting = false;
+            }
+        });
+    };
+    SliderDOMRenderer.prototype.deactivate = function () {
+        if (!this._stopInteractionSubscription) {
+            return;
+        }
+        this._interacting = false;
+        this._stopInteractionSubscription.unsubscribe();
+        this._stopInteractionSubscription = null;
+    };
+    SliderDOMRenderer.prototype.render = function (position, mode, motionless, pano, visible) {
+        var children = [];
+        if (visible) {
+            children.push(vd.h("div.SliderBorder", []));
+            var modeVisible = !(motionless || pano);
+            if (modeVisible) {
+                children.push(this._createModeButton(mode));
+            }
+            children.push(this._createPositionInput(position, modeVisible));
+        }
+        var boundingRect = this._container.domContainer.getBoundingClientRect();
+        var width = Math.max(215, Math.min(400, boundingRect.width - 100));
+        return vd.h("div.SliderContainer", { style: { width: width + "px" } }, children);
+    };
+    SliderDOMRenderer.prototype._createModeButton = function (mode) {
+        var _this = this;
+        var properties = {
+            onclick: function () {
+                _this._notifyModeChanged$.next(mode === Component_1.SliderMode.Motion ?
+                    Component_1.SliderMode.Stationary :
+                    Component_1.SliderMode.Motion);
+            },
+        };
+        var className = mode === Component_1.SliderMode.Stationary ?
+            "SliderModeButtonPressed" :
+            "SliderModeButton";
+        return vd.h("div." + className, properties, [vd.h("div.SliderModeIcon", [])]);
+    };
+    SliderDOMRenderer.prototype._createPositionInput = function (position, modeVisible) {
+        var _this = this;
+        var onChange = function (e) {
+            _this._notifyPositionChanged$.next(Number(e.target.value) / 1000);
+        };
+        var onStart = function (e) {
+            _this._interacting = true;
+            e.stopPropagation();
+        };
+        var onMove = function (e) {
+            if (_this._interacting) {
+                e.stopPropagation();
+            }
+        };
+        var onKeyDown = function (e) {
+            if (e.key === "ArrowDown" || e.key === "ArrowLeft" ||
+                e.key === "ArrowRight" || e.key === "ArrowUp") {
+                e.preventDefault();
+            }
+        };
+        var boundingRect = this._container.domContainer.getBoundingClientRect();
+        var width = Math.max(215, Math.min(400, boundingRect.width - 105)) - 68 + (modeVisible ? 0 : 36);
+        var positionInput = vd.h("input.SliderPosition", {
+            max: 1000,
+            min: 0,
+            onchange: onChange,
+            oninput: onChange,
+            onkeydown: onKeyDown,
+            onmousedown: onStart,
+            onmousemove: onMove,
+            ontouchmove: onMove,
+            ontouchstart: onStart,
+            style: {
+                width: width + "px",
+            },
+            type: "range",
+            value: 1000 * position,
+        }, []);
+        return vd.h("div.SliderPositionContainer", [positionInput]);
+    };
+    return SliderDOMRenderer;
+}());
+exports.SliderDOMRenderer = SliderDOMRenderer;
+exports.default = SliderDOMRenderer;
+
+},{"../../Component":290,"rxjs/Observable":29,"rxjs/Subject":34,"virtual-dom":246}],352:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var Component_1 = require("../../Component");
+var Geo_1 = require("../../Geo");
+var SliderGLRenderer = /** @class */ (function () {
+    function SliderGLRenderer() {
+        this._factory = new Component_1.MeshFactory();
+        this._scene = new Component_1.MeshScene();
+        this._spatial = new Geo_1.Spatial();
+        this._currentKey = null;
+        this._previousKey = null;
+        this._disabled = false;
+        this._curtain = 1;
+        this._frameId = 0;
+        this._needsRender = false;
+        this._mode = null;
+        this._currentProviderDisposers = {};
+        this._previousProviderDisposers = {};
+    }
+    Object.defineProperty(SliderGLRenderer.prototype, "disabled", {
+        get: function () {
+            return this._disabled;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(SliderGLRenderer.prototype, "frameId", {
+        get: function () {
+            return this._frameId;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(SliderGLRenderer.prototype, "needsRender", {
+        get: function () {
+            return this._needsRender;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    SliderGLRenderer.prototype.setTextureProvider = function (key, provider) {
+        this._setTextureProvider(key, this._currentKey, provider, this._currentProviderDisposers, this._updateTexture.bind(this));
+    };
+    SliderGLRenderer.prototype.setTextureProviderPrev = function (key, provider) {
+        this._setTextureProvider(key, this._previousKey, provider, this._previousProviderDisposers, this._updateTexturePrev.bind(this));
+    };
+    SliderGLRenderer.prototype.update = function (frame, mode) {
+        this._updateFrameId(frame.id);
+        this._updateImagePlanes(frame.state, mode);
+    };
+    SliderGLRenderer.prototype.updateCurtain = function (curtain) {
+        if (this._curtain === curtain) {
+            return;
+        }
+        this._curtain = curtain;
+        this._updateCurtain();
+        this._needsRender = true;
+    };
+    SliderGLRenderer.prototype.updateTexture = function (image, node) {
+        var imagePlanes = node.key === this._currentKey ?
+            this._scene.imagePlanes :
+            node.key === this._previousKey ?
+                this._scene.imagePlanesOld :
+                [];
+        if (imagePlanes.length === 0) {
+            return;
+        }
+        this._needsRender = true;
+        for (var _i = 0, imagePlanes_1 = imagePlanes; _i < imagePlanes_1.length; _i++) {
+            var plane = imagePlanes_1[_i];
+            var material = plane.material;
+            var texture = material.uniforms.projectorTex.value;
+            texture.image = image;
+            texture.needsUpdate = true;
+        }
+    };
+    SliderGLRenderer.prototype.updateTextureImage = function (image, node) {
+        if (this._currentKey !== node.key) {
+            return;
+        }
+        this._needsRender = true;
+        for (var _i = 0, _a = this._scene.imagePlanes; _i < _a.length; _i++) {
+            var plane = _a[_i];
+            var material = plane.material;
+            var texture = material.uniforms.projectorTex.value;
+            texture.image = image;
+            texture.needsUpdate = true;
+        }
+    };
+    SliderGLRenderer.prototype.render = function (perspectiveCamera, renderer) {
+        if (!this.disabled) {
+            renderer.render(this._scene.sceneOld, perspectiveCamera);
+        }
+        renderer.render(this._scene.scene, perspectiveCamera);
+        this._needsRender = false;
+    };
+    SliderGLRenderer.prototype.dispose = function () {
+        this._scene.clear();
+        for (var key in this._currentProviderDisposers) {
+            if (!this._currentProviderDisposers.hasOwnProperty(key)) {
+                continue;
+            }
+            this._currentProviderDisposers[key]();
+        }
+        for (var key in this._previousProviderDisposers) {
+            if (!this._previousProviderDisposers.hasOwnProperty(key)) {
+                continue;
+            }
+            this._previousProviderDisposers[key]();
+        }
+        this._currentProviderDisposers = {};
+        this._previousProviderDisposers = {};
+    };
+    SliderGLRenderer.prototype._getBasicCorners = function (currentAspect, previousAspect) {
+        var offsetX;
+        var offsetY;
+        if (currentAspect > previousAspect) {
+            offsetX = 0.5;
+            offsetY = 0.5 * currentAspect / previousAspect;
+        }
+        else {
+            offsetX = 0.5 * previousAspect / currentAspect;
+            offsetY = 0.5;
+        }
+        return [[0.5 - offsetX, 0.5 - offsetY], [0.5 + offsetX, 0.5 + offsetY]];
+    };
+    SliderGLRenderer.prototype._setDisabled = function (state) {
+        this._disabled = state.currentNode == null ||
+            state.previousNode == null ||
+            (state.currentNode.pano && !state.currentNode.fullPano) ||
+            (state.previousNode.pano && !state.previousNode.fullPano) ||
+            (state.currentNode.fullPano && !state.previousNode.fullPano);
+    };
+    SliderGLRenderer.prototype._setTextureProvider = function (key, originalKey, provider, providerDisposers, updateTexture) {
+        var _this = this;
+        if (key !== originalKey) {
+            return;
+        }
+        var createdSubscription = provider.textureCreated$
+            .subscribe(updateTexture);
+        var updatedSubscription = provider.textureUpdated$
+            .subscribe(function (updated) {
+            _this._needsRender = true;
+        });
+        var dispose = function () {
+            createdSubscription.unsubscribe();
+            updatedSubscription.unsubscribe();
+            provider.dispose();
+        };
+        if (key in providerDisposers) {
+            var disposeProvider = providerDisposers[key];
+            disposeProvider();
+            delete providerDisposers[key];
+        }
+        providerDisposers[key] = dispose;
+    };
+    SliderGLRenderer.prototype._updateCurtain = function () {
+        for (var _i = 0, _a = this._scene.imagePlanes; _i < _a.length; _i++) {
+            var plane = _a[_i];
+            var shaderMaterial = plane.material;
+            if (!!shaderMaterial.uniforms.curtain) {
+                shaderMaterial.uniforms.curtain.value = this._curtain;
+            }
+        }
+    };
+    SliderGLRenderer.prototype._updateFrameId = function (frameId) {
+        this._frameId = frameId;
+    };
+    SliderGLRenderer.prototype._updateImagePlanes = function (state, mode) {
+        var currentChanged = state.currentNode != null && this._currentKey !== state.currentNode.key;
+        var previousChanged = state.previousNode != null && this._previousKey !== state.previousNode.key;
+        var modeChanged = this._mode !== mode;
+        if (!(currentChanged || previousChanged || modeChanged)) {
+            return;
+        }
+        this._setDisabled(state);
+        this._needsRender = true;
+        this._mode = mode;
+        var motionless = state.motionless || mode === Component_1.SliderMode.Stationary || state.currentNode.pano;
+        if (this.disabled || previousChanged) {
+            if (this._previousKey in this._previousProviderDisposers) {
+                this._previousProviderDisposers[this._previousKey]();
+                delete this._previousProviderDisposers[this._previousKey];
+            }
+        }
+        if (this.disabled) {
+            this._scene.setImagePlanesOld([]);
+        }
+        else {
+            if (previousChanged || modeChanged) {
+                var previousNode = state.previousNode;
+                this._previousKey = previousNode.key;
+                var elements = state.currentTransform.rt.elements;
+                var translation = [elements[12], elements[13], elements[14]];
+                var currentAspect = state.currentTransform.basicAspect;
+                var previousAspect = state.previousTransform.basicAspect;
+                var textureScale = currentAspect > previousAspect ?
+                    [1, previousAspect / currentAspect] :
+                    [currentAspect / previousAspect, 1];
+                var rotation = state.currentNode.rotation;
+                var width = state.currentNode.width;
+                var height = state.currentNode.height;
+                if (previousNode.fullPano) {
+                    rotation = state.previousNode.rotation;
+                    translation = this._spatial
+                        .rotate(this._spatial
+                        .opticalCenter(state.currentNode.rotation, translation)
+                        .toArray(), rotation)
+                        .multiplyScalar(-1)
+                        .toArray();
+                    width = state.previousNode.width;
+                    height = state.previousNode.height;
+                }
+                var transform = new Geo_1.Transform(state.currentNode.orientation, width, height, state.currentNode.focal, state.currentNode.scale, previousNode.gpano, rotation, translation, previousNode.image, textureScale);
+                var mesh = undefined;
+                if (previousNode.fullPano) {
+                    mesh = this._factory.createMesh(previousNode, motionless || state.currentNode.fullPano ? transform : state.previousTransform);
+                }
+                else {
+                    if (motionless) {
+                        var _a = this._getBasicCorners(currentAspect, previousAspect), _b = _a[0], basicX0 = _b[0], basicY0 = _b[1], _c = _a[1], basicX1 = _c[0], basicY1 = _c[1];
+                        mesh = this._factory.createFlatMesh(state.previousNode, transform, basicX0, basicX1, basicY0, basicY1);
+                    }
+                    else {
+                        mesh = this._factory.createMesh(state.previousNode, state.previousTransform);
+                    }
+                }
+                this._scene.setImagePlanesOld([mesh]);
+            }
+        }
+        if (currentChanged) {
+            if (this._currentKey in this._currentProviderDisposers) {
+                this._currentProviderDisposers[this._currentKey]();
+                delete this._currentProviderDisposers[this._currentKey];
+            }
+            this._currentKey = state.currentNode.key;
+            var imagePlane = state.currentNode.pano && !state.currentNode.fullPano ?
+                this._factory.createMesh(state.currentNode, state.currentTransform) :
+                this._factory.createCurtainMesh(state.currentNode, state.currentTransform);
+            this._scene.setImagePlanes([imagePlane]);
+            this._updateCurtain();
+        }
+    };
+    SliderGLRenderer.prototype._updateTexture = function (texture) {
+        this._needsRender = true;
+        for (var _i = 0, _a = this._scene.imagePlanes; _i < _a.length; _i++) {
+            var plane = _a[_i];
+            var material = plane.material;
+            var oldTexture = material.uniforms.projectorTex.value;
+            material.uniforms.projectorTex.value = null;
+            oldTexture.dispose();
+            material.uniforms.projectorTex.value = texture;
+        }
+    };
+    SliderGLRenderer.prototype._updateTexturePrev = function (texture) {
+        this._needsRender = true;
+        for (var _i = 0, _a = this._scene.imagePlanesOld; _i < _a.length; _i++) {
+            var plane = _a[_i];
+            var material = plane.material;
+            var oldTexture = material.uniforms.projectorTex.value;
+            material.uniforms.projectorTex.value = null;
+            oldTexture.dispose();
+            material.uniforms.projectorTex.value = texture;
+        }
+    };
+    return SliderGLRenderer;
+}());
+exports.SliderGLRenderer = SliderGLRenderer;
+exports.default = SliderGLRenderer;
+
+},{"../../Component":290,"../../Geo":293}],353:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var GeometryTagError_1 = require("./error/GeometryTagError");
+exports.GeometryTagError = GeometryTagError_1.GeometryTagError;
+var PointGeometry_1 = require("./geometry/PointGeometry");
+exports.PointGeometry = PointGeometry_1.PointGeometry;
+var RectGeometry_1 = require("./geometry/RectGeometry");
+exports.RectGeometry = RectGeometry_1.RectGeometry;
+var PolygonGeometry_1 = require("./geometry/PolygonGeometry");
+exports.PolygonGeometry = PolygonGeometry_1.PolygonGeometry;
+var OutlineTag_1 = require("./tag/OutlineTag");
+exports.OutlineTag = OutlineTag_1.OutlineTag;
+var SpotTag_1 = require("./tag/SpotTag");
+exports.SpotTag = SpotTag_1.SpotTag;
+var TagComponent_1 = require("./TagComponent");
+exports.TagComponent = TagComponent_1.TagComponent;
+var TagMode_1 = require("./TagMode");
+exports.TagMode = TagMode_1.TagMode;
+
+},{"./TagComponent":354,"./TagMode":357,"./error/GeometryTagError":361,"./geometry/PointGeometry":363,"./geometry/PolygonGeometry":364,"./geometry/RectGeometry":365,"./tag/OutlineTag":377,"./tag/SpotTag":380}],354:[function(require,module,exports){
+"use strict";
+/// <reference path="../../../typings/index.d.ts" />
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var when = require("when");
+var Observable_1 = require("rxjs/Observable");
+var Component_1 = require("../../Component");
+var Geo_1 = require("../../Geo");
+var Render_1 = require("../../Render");
+/**
+ * @class TagComponent
+ *
+ * @classdesc Component for showing and editing tags with different
+ * geometries composed from 2D basic image coordinates (see the
+ * {@link Viewer} class documentation for more information about coordinate
+ * systems).
+ *
+ * The `add` method is used for adding new tags or replacing
+ * tags already in the set. Tags are removed by id.
+ *
+ * If a tag already in the set has the same
+ * id as one of the tags added, the old tag will be removed and
+ * the added tag will take its place.
+ *
+ * The tag component mode can be set to either be non interactive or
+ * to be in creating mode of a certain geometry type.
+ *
+ * The tag properties can be updated at any time and the change will
+ * be visibile immediately.
+ *
+ * Tags are only relevant to a single image because they are based on
+ * 2D basic image coordinates. Tags related to a certain image should
+ * be removed when the viewer is moved to another node.
+ *
+ * To retrive and use the tag component
+ *
+ * @example
+ * ```
+ * var viewer = new Mapillary.Viewer(
+ *     "<element-id>",
+ *     "<client-id>",
+ *     "<my key>",
+ *     { component: { tag: true } });
+ *
+ * var tagComponent = viewer.getComponent("tag");
+ * ```
+ */
+var TagComponent = /** @class */ (function (_super) {
+    __extends(TagComponent, _super);
+    function TagComponent(name, container, navigator) {
+        var _this = _super.call(this, name, container, navigator) || this;
+        _this._tagDomRenderer = new Component_1.TagDOMRenderer();
+        _this._tagScene = new Component_1.TagScene();
+        _this._tagSet = new Component_1.TagSet();
+        _this._tagCreator = new Component_1.TagCreator(_this, navigator);
+        _this._viewportCoords = new Geo_1.ViewportCoords();
+        _this._createHandlers = {
+            "CreatePoint": new Component_1.CreatePointHandler(_this, container, navigator, _this._viewportCoords, _this._tagCreator),
+            "CreatePolygon": new Component_1.CreatePolygonHandler(_this, container, navigator, _this._viewportCoords, _this._tagCreator),
+            "CreateRect": new Component_1.CreateRectHandler(_this, container, navigator, _this._viewportCoords, _this._tagCreator),
+            "CreateRectDrag": new Component_1.CreateRectDragHandler(_this, container, navigator, _this._viewportCoords, _this._tagCreator),
+            "Default": undefined,
+        };
+        _this._editVertexHandler = new Component_1.EditVertexHandler(_this, container, navigator, _this._viewportCoords, _this._tagSet);
+        _this._renderTags$ = _this._tagSet.changed$
+            .map(function (tagSet) {
+            var tags = tagSet.getAll();
+            // ensure that tags are always rendered in the same order
+            // to avoid hover tracking problems on first resize.
+            tags.sort(function (t1, t2) {
+                var id1 = t1.tag.id;
+                var id2 = t2.tag.id;
+                if (id1 < id2) {
+                    return -1;
+                }
+                if (id1 > id2) {
+                    return 1;
+                }
+                return 0;
+            });
+            return tags;
+        })
+            .share();
+        _this._tagChanged$ = _this._renderTags$
+            .switchMap(function (tags) {
+            return Observable_1.Observable
+                .from(tags)
+                .mergeMap(function (tag) {
+                return Observable_1.Observable
+                    .merge(tag.tag.changed$, tag.tag.geometryChanged$);
+            });
+        })
+            .share();
+        _this._renderTagGLChanged$ = _this._renderTags$
+            .switchMap(function (tags) {
+            return Observable_1.Observable
+                .from(tags)
+                .mergeMap(function (tag) {
+                return tag.glObjectsChanged$;
+            });
+        })
+            .share();
+        _this._createGeometryChanged$ = _this._tagCreator.tag$
+            .switchMap(function (tag) {
+            return tag != null ?
+                tag.geometryChanged$ :
+                Observable_1.Observable.empty();
+        })
+            .share();
+        _this._createGLObjectsChanged$ = _this._tagCreator.tag$
+            .switchMap(function (tag) {
+            return tag != null ?
+                tag.glObjectsChanged$ :
+                Observable_1.Observable.empty();
+        })
+            .share();
+        _this._creatingConfiguration$ = _this._configuration$
+            .distinctUntilChanged(function (c1, c2) {
+            return c1.mode === c2.mode;
+        }, function (configuration) {
+            return {
+                createColor: configuration.createColor,
+                mode: configuration.mode,
+            };
+        })
+            .publishReplay(1)
+            .refCount();
+        _this._creatingConfiguration$
+            .subscribe(function (configuration) {
+            _this.fire(TagComponent.modechanged, configuration.mode);
+        });
+        return _this;
+    }
+    /**
+     * Add tags to the tag set or replace tags in the tag set.
+     *
+     * @description If a tag already in the set has the same
+     * id as one of the tags added, the old tag will be removed
+     * the added tag will take its place.
+     *
+     * @param {Array<Tag>} tags - Tags to add.
+     *
+     * @example ```tagComponent.add([tag1, tag2]);```
+     */
+    TagComponent.prototype.add = function (tags) {
+        var _this = this;
+        if (this._activated) {
+            this._navigator.stateService.currentTransform$
+                .first()
+                .subscribe(function (transform) {
+                _this._tagSet.add(tags, transform);
+                var renderTags = tags
+                    .map(function (tag) {
+                    return _this._tagSet.get(tag.id);
+                });
+                _this._tagScene.add(renderTags);
+            });
+        }
+        else {
+            this._tagSet.addDeactivated(tags);
+        }
+    };
+    /**
+     * Change the current tag mode.
+     *
+     * @description Change the tag mode to one of the create modes for creating new geometries.
+     *
+     * @param {TagMode} mode - New tag mode.
+     *
+     * @fires TagComponent#modechanged
+     *
+     * @example ```tagComponent.changeMode(Mapillary.TagComponent.TagMode.CreateRect);```
+     */
+    TagComponent.prototype.changeMode = function (mode) {
+        this.configure({ mode: mode });
+    };
+    /**
+     * Returns the tag in the tag set with the specified id, or
+     * undefined if the id matches no tag.
+     *
+     * @param {string} tagId - Id of the tag.
+     *
+     * @example ```var tag = tagComponent.get("tagId");```
+     */
+    TagComponent.prototype.get = function (tagId) {
+        if (this._activated) {
+            var renderTag = this._tagSet.get(tagId);
+            return renderTag !== undefined ? renderTag.tag : undefined;
+        }
+        else {
+            return this._tagSet.getDeactivated(tagId);
+        }
+    };
+    /**
+     * Returns an array of all tags.
+     *
+     * @example ```var tags = tagComponent.getAll();```
+     */
+    TagComponent.prototype.getAll = function () {
+        if (this.activated) {
+            return this._tagSet
+                .getAll()
+                .map(function (renderTag) {
+                return renderTag.tag;
+            });
+        }
+        else {
+            return this._tagSet.getAllDeactivated();
+        }
+    };
+    /**
+     * Returns an array of tag ids for tags that contain the specified point.
+     *
+     * @description The pixel point must lie inside the polygon or rectangle
+     * of an added tag for the tag id to be returned. Tag ids for
+     * tags that do not have a fill will also be returned if the point is inside
+     * the geometry of the tag. Tags with point geometries can not be retrieved.
+     *
+     * No tag ids will be returned for panoramas.
+     *
+     * Notice that the pixelPoint argument requires x, y coordinates from pixel space.
+     *
+     * With this function, you can use the coordinates provided by mouse
+     * events to get information out of the tag component.
+     *
+     * If no tag at exist the pixel point, an empty array will be returned.
+     *
+     * @param {Array<number>} pixelPoint - Pixel coordinates on the viewer element.
+     * @returns {Array<string>} Ids of the tags that contain the specified pixel point.
+     *
+     * @example
+     * ```
+     * tagComponent.getTagIdsAt([100, 100])
+     *     .then((tagIds) => { console.log(tagIds); });
+     * ```
+     */
+    TagComponent.prototype.getTagIdsAt = function (pixelPoint) {
+        var _this = this;
+        return when.promise(function (resolve, reject) {
+            _this._container.renderService.renderCamera$
+                .first()
+                .map(function (render) {
+                var viewport = _this._viewportCoords
+                    .canvasToViewport(pixelPoint[0], pixelPoint[1], _this._container.element);
+                var ids = _this._tagScene.intersectObjects(viewport, render.perspective);
+                return ids;
+            })
+                .subscribe(function (ids) {
+                resolve(ids);
+            }, function (error) {
+                reject(error);
+            });
+        });
+    };
+    /**
+     * Check if a tag exist in the tag set.
+     *
+     * @param {string} tagId - Id of the tag.
+     *
+     * @example ```var tagExists = tagComponent.has("tagId");```
+     */
+    TagComponent.prototype.has = function (tagId) {
+        return this._activated ? this._tagSet.has(tagId) : this._tagSet.hasDeactivated(tagId);
+    };
+    /**
+     * Remove tags with the specified ids from the tag set.
+     *
+     * @param {Array<string>} tagIds - Ids for tags to remove.
+     *
+     * @example ```tagComponent.remove(["id-1", "id-2"]);```
+     */
+    TagComponent.prototype.remove = function (tagIds) {
+        if (this._activated) {
+            this._tagSet.remove(tagIds);
+            this._tagScene.remove(tagIds);
+        }
+        else {
+            this._tagSet.removeDeactivated(tagIds);
+        }
+    };
+    /**
+     * Remove all tags from the tag set.
+     *
+     * @example ```tagComponent.removeAll();```
+     */
+    TagComponent.prototype.removeAll = function () {
+        if (this._activated) {
+            this._tagSet.removeAll();
+            this._tagScene.removeAll();
+        }
+        else {
             this._tagSet.removeAllDeactivated();
         }
     };
@@ -30663,14 +31732,10 @@ exports.TagComponent = TagComponent;
 Component_1.ComponentService.register(TagComponent);
 exports.default = TagComponent;
 
-},{"../../Component":281,"../../Geo":284,"../../Render":287,"rxjs/Observable":29,"rxjs/add/observable/combineLatest":38,"rxjs/add/observable/empty":40,"rxjs/add/observable/from":41,"rxjs/add/observable/merge":44,"rxjs/add/observable/of":45,"rxjs/add/operator/combineLatest":53,"rxjs/add/operator/concat":54,"rxjs/add/operator/distinctUntilChanged":58,"rxjs/add/operator/do":59,"rxjs/add/operator/filter":61,"rxjs/add/operator/map":65,"rxjs/add/operator/merge":66,"rxjs/add/operator/mergeMap":68,"rxjs/add/operator/publishReplay":72,"rxjs/add/operator/scan":75,"rxjs/add/operator/share":76,"rxjs/add/operator/skip":77,"rxjs/add/operator/skipUntil":78,"rxjs/add/operator/startWith":80,"rxjs/add/operator/switchMap":81,"rxjs/add/operator/take":82,"rxjs/add/operator/takeUntil":83,"rxjs/add/operator/withLatestFrom":87,"when":278}],346:[function(require,module,exports){
+},{"../../Component":290,"../../Geo":293,"../../Render":296,"rxjs/Observable":29,"when":287}],355:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/scan");
-require("rxjs/add/operator/share");
-require("rxjs/add/operator/withLatestFrom");
 var Component_1 = require("../../Component");
 var TagCreator = /** @class */ (function () {
     function TagCreator(component, navigator) {
@@ -30755,7 +31820,7 @@ var TagCreator = /** @class */ (function () {
 exports.TagCreator = TagCreator;
 exports.default = TagCreator;
 
-},{"../../Component":281,"rxjs/Subject":34,"rxjs/add/operator/map":65,"rxjs/add/operator/scan":75,"rxjs/add/operator/share":76,"rxjs/add/operator/withLatestFrom":87}],347:[function(require,module,exports){
+},{"../../Component":290,"rxjs/Subject":34}],356:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -30781,7 +31846,7 @@ var TagDOMRenderer = /** @class */ (function () {
 }());
 exports.TagDOMRenderer = TagDOMRenderer;
 
-},{"virtual-dom":237}],348:[function(require,module,exports){
+},{"virtual-dom":246}],357:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 /**
@@ -30818,7 +31883,7 @@ var TagMode;
 })(TagMode = exports.TagMode || (exports.TagMode = {}));
 exports.default = TagMode;
 
-},{}],349:[function(require,module,exports){
+},{}],358:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var TagOperation;
@@ -30829,7 +31894,7 @@ var TagOperation;
 })(TagOperation = exports.TagOperation || (exports.TagOperation = {}));
 exports.default = TagOperation;
 
-},{}],350:[function(require,module,exports){
+},{}],359:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -30997,13 +32062,10 @@ var TagScene = /** @class */ (function () {
 exports.TagScene = TagScene;
 exports.default = TagScene;
 
-},{"three":231}],351:[function(require,module,exports){
+},{"three":240}],360:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/scan");
-require("rxjs/add/operator/share");
 var Component_1 = require("../../Component");
 var TagSet = /** @class */ (function () {
     function TagSet() {
@@ -31151,7 +32213,7 @@ var TagSet = /** @class */ (function () {
 exports.TagSet = TagSet;
 exports.default = TagSet;
 
-},{"../../Component":281,"rxjs/Subject":34,"rxjs/add/operator/map":65,"rxjs/add/operator/scan":75,"rxjs/add/operator/share":76}],352:[function(require,module,exports){
+},{"../../Component":290,"rxjs/Subject":34}],361:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -31177,7 +32239,7 @@ var GeometryTagError = /** @class */ (function (_super) {
 exports.GeometryTagError = GeometryTagError;
 exports.default = Error_1.MapillaryError;
 
-},{"../../../Error":283}],353:[function(require,module,exports){
+},{"../../../Error":292}],362:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Subject_1 = require("rxjs/Subject");
@@ -31216,7 +32278,7 @@ var Geometry = /** @class */ (function () {
 exports.Geometry = Geometry;
 exports.default = Geometry;
 
-},{"rxjs/Subject":34}],354:[function(require,module,exports){
+},{"rxjs/Subject":34}],363:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -31311,7 +32373,7 @@ var PointGeometry = /** @class */ (function (_super) {
 }(Component_1.Geometry));
 exports.PointGeometry = PointGeometry;
 
-},{"../../../Component":281}],355:[function(require,module,exports){
+},{"../../../Component":290}],364:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -31583,7 +32645,7 @@ var PolygonGeometry = /** @class */ (function (_super) {
 exports.PolygonGeometry = PolygonGeometry;
 exports.default = PolygonGeometry;
 
-},{"../../../Component":281}],356:[function(require,module,exports){
+},{"../../../Component":290}],365:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -32109,8 +33171,8 @@ var RectGeometry = /** @class */ (function (_super) {
         var x1 = this._inverted ? rect[2] + 1 : rect[2];
         var y0 = rect[1];
         var y1 = rect[3];
-        var centroidX = x0 + (x1 - x0) / 2;
-        var centroidY = y0 + (y1 - y0) / 2;
+        var centroidX = (x0 + x1) / 2;
+        var centroidY = (y0 + y1) / 2;
         return [centroidX, centroidY];
     };
     /** @inheritdoc */
@@ -32229,7 +33291,7 @@ var RectGeometry = /** @class */ (function (_super) {
 exports.RectGeometry = RectGeometry;
 exports.default = RectGeometry;
 
-},{"../../../Component":281}],357:[function(require,module,exports){
+},{"../../../Component":290}],366:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -32311,7 +33373,7 @@ var VertexGeometry = /** @class */ (function (_super) {
 exports.VertexGeometry = VertexGeometry;
 exports.default = VertexGeometry;
 
-},{"../../../Component":281,"@mapbox/polylabel":1,"earcut":8}],358:[function(require,module,exports){
+},{"../../../Component":290,"@mapbox/polylabel":1,"earcut":8}],367:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -32369,7 +33431,7 @@ var CreateHandlerBase = /** @class */ (function (_super) {
 exports.CreateHandlerBase = CreateHandlerBase;
 exports.default = CreateHandlerBase;
 
-},{"../../../Component":281,"rxjs/Subject":34}],359:[function(require,module,exports){
+},{"../../../Component":290,"rxjs/Subject":34}],368:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -32409,7 +33471,7 @@ var CreatePointHandler = /** @class */ (function (_super) {
 exports.CreatePointHandler = CreatePointHandler;
 exports.default = CreatePointHandler;
 
-},{"../../../Component":281}],360:[function(require,module,exports){
+},{"../../../Component":290}],369:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -32449,7 +33511,7 @@ var CreatePolygonHandler = /** @class */ (function (_super) {
 exports.CreatePolygonHandler = CreatePolygonHandler;
 exports.default = CreatePolygonHandler;
 
-},{"../../../Component":281}],361:[function(require,module,exports){
+},{"../../../Component":290}],370:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -32555,7 +33617,7 @@ var CreateRectDragHandler = /** @class */ (function (_super) {
 exports.CreateRectDragHandler = CreateRectDragHandler;
 exports.default = CreateRectDragHandler;
 
-},{"../../../Component":281,"rxjs/Observable":29}],362:[function(require,module,exports){
+},{"../../../Component":290,"rxjs/Observable":29}],371:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -32613,7 +33675,7 @@ var CreateRectHandler = /** @class */ (function (_super) {
 exports.CreateRectHandler = CreateRectHandler;
 exports.default = CreateRectHandler;
 
-},{"../../../Component":281}],363:[function(require,module,exports){
+},{"../../../Component":290}],372:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -32700,7 +33762,7 @@ var CreateVertexHandler = /** @class */ (function (_super) {
 exports.CreateVertexHandler = CreateVertexHandler;
 exports.default = CreateVertexHandler;
 
-},{"../../../Component":281,"rxjs/Observable":29}],364:[function(require,module,exports){
+},{"../../../Component":290,"rxjs/Observable":29}],373:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -32832,7 +33894,7 @@ var EditVertexHandler = /** @class */ (function (_super) {
 exports.EditVertexHandler = EditVertexHandler;
 exports.default = EditVertexHandler;
 
-},{"../../../Component":281,"rxjs/Observable":29}],365:[function(require,module,exports){
+},{"../../../Component":290,"rxjs/Observable":29}],374:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -32870,7 +33932,7 @@ var TagHandlerBase = /** @class */ (function (_super) {
 exports.TagHandlerBase = TagHandlerBase;
 exports.default = TagHandlerBase;
 
-},{"../../../Component":281}],366:[function(require,module,exports){
+},{"../../../Component":290}],375:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -33096,7 +34158,7 @@ var OutlineCreateTag = /** @class */ (function () {
 exports.OutlineCreateTag = OutlineCreateTag;
 exports.default = OutlineCreateTag;
 
-},{"../../../Component":281,"../../../Geo":284,"rxjs/Subject":34,"three":231,"virtual-dom":237}],367:[function(require,module,exports){
+},{"../../../Component":290,"../../../Geo":293,"rxjs/Subject":34,"three":240,"virtual-dom":246}],376:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -33461,7 +34523,7 @@ var OutlineRenderTag = /** @class */ (function (_super) {
 }(Component_1.RenderTag));
 exports.OutlineRenderTag = OutlineRenderTag;
 
-},{"../../../Component":281,"three":231,"virtual-dom":237}],368:[function(require,module,exports){
+},{"../../../Component":290,"three":240,"virtual-dom":246}],377:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -33839,7 +34901,7 @@ var OutlineTag = /** @class */ (function (_super) {
 exports.OutlineTag = OutlineTag;
 exports.default = OutlineTag;
 
-},{"../../../Component":281,"../../../Viewer":292,"rxjs/Subject":34}],369:[function(require,module,exports){
+},{"../../../Component":290,"../../../Viewer":301,"rxjs/Subject":34}],378:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -33879,7 +34941,7 @@ var RenderTag = /** @class */ (function () {
 exports.RenderTag = RenderTag;
 exports.default = RenderTag;
 
-},{"../../../Geo":284,"rxjs/Subject":34}],370:[function(require,module,exports){
+},{"../../../Geo":293,"rxjs/Subject":34}],379:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -33994,7 +35056,7 @@ var SpotRenderTag = /** @class */ (function (_super) {
 }(Component_1.RenderTag));
 exports.SpotRenderTag = SpotRenderTag;
 
-},{"../../../Component":281,"../../../Viewer":292,"virtual-dom":237}],371:[function(require,module,exports){
+},{"../../../Component":290,"../../../Viewer":301,"virtual-dom":246}],380:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -34169,13 +35231,618 @@ var SpotTag = /** @class */ (function (_super) {
         this._textColor = options.textColor == null ? this._textColor : options.textColor;
         this._notifyChanged$.next(this);
     };
-    return SpotTag;
-}(Component_1.Tag));
-exports.SpotTag = SpotTag;
-exports.default = SpotTag;
+    return SpotTag;
+}(Component_1.Tag));
+exports.SpotTag = SpotTag;
+exports.default = SpotTag;
+
+},{"../../../Component":290}],381:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var Subject_1 = require("rxjs/Subject");
+var Utils_1 = require("../../../Utils");
+/**
+ * @class Tag
+ * @abstract
+ * @classdesc Abstract class representing the basic functionality of for a tag.
+ */
+var Tag = /** @class */ (function (_super) {
+    __extends(Tag, _super);
+    /**
+     * Create a tag.
+     *
+     * @constructor
+     * @param {string} id
+     * @param {Geometry} geometry
+     */
+    function Tag(id, geometry) {
+        var _this = _super.call(this) || this;
+        _this._id = id;
+        _this._geometry = geometry;
+        _this._notifyChanged$ = new Subject_1.Subject();
+        _this._notifyChanged$
+            .subscribe(function (t) {
+            _this.fire(Tag.changed, _this);
+        });
+        _this._geometry.changed$
+            .subscribe(function (g) {
+            _this.fire(Tag.geometrychanged, _this);
+        });
+        return _this;
+    }
+    Object.defineProperty(Tag.prototype, "id", {
+        /**
+         * Get id property.
+         * @returns {string}
+         */
+        get: function () {
+            return this._id;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Tag.prototype, "geometry", {
+        /**
+         * Get geometry property.
+         * @returns {Geometry} The geometry of the tag.
+         */
+        get: function () {
+            return this._geometry;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Tag.prototype, "changed$", {
+        /**
+         * Get changed observable.
+         * @returns {Observable<Tag>}
+         * @ignore
+         */
+        get: function () {
+            return this._notifyChanged$;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Tag.prototype, "geometryChanged$", {
+        /**
+         * Get geometry changed observable.
+         * @returns {Observable<Tag>}
+         * @ignore
+         */
+        get: function () {
+            var _this = this;
+            return this._geometry.changed$
+                .map(function (geometry) {
+                return _this;
+            })
+                .share();
+        },
+        enumerable: true,
+        configurable: true
+    });
+    /**
+     * Event fired when a property related to the visual appearance of the
+     * tag has changed.
+     *
+     * @event Tag#changed
+     * @type {Tag} The tag instance that has changed.
+     */
+    Tag.changed = "changed";
+    /**
+     * Event fired when the geometry of the tag has changed.
+     *
+     * @event Tag#geometrychanged
+     * @type {Tag} The tag instance whose geometry has changed.
+     */
+    Tag.geometrychanged = "geometrychanged";
+    return Tag;
+}(Utils_1.EventEmitter));
+exports.Tag = Tag;
+exports.default = Tag;
+
+},{"../../../Utils":300,"rxjs/Subject":34}],382:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var HandlerBase = /** @class */ (function () {
+    function HandlerBase(component, container, navigator) {
+        this._component = component;
+        this._container = container;
+        this._navigator = navigator;
+        this._enabled = false;
+    }
+    Object.defineProperty(HandlerBase.prototype, "isEnabled", {
+        /**
+         * Returns a Boolean indicating whether the interaction is enabled.
+         *
+         * @returns {boolean} `true` if the interaction is enabled.
+         */
+        get: function () {
+            return this._enabled;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    /**
+     * Enables the interaction.
+     *
+     * @example ```<component-name>.<handler-name>.enable();```
+     */
+    HandlerBase.prototype.enable = function () {
+        if (this._enabled || !this._component.activated) {
+            return;
+        }
+        this._enable();
+        this._enabled = true;
+        this._component.configure(this._getConfiguration(true));
+    };
+    /**
+     * Disables the interaction.
+     *
+     * @example ```<component-name>.<handler-name>.disable();```
+     */
+    HandlerBase.prototype.disable = function () {
+        if (!this._enabled) {
+            return;
+        }
+        this._disable();
+        this._enabled = false;
+        if (this._component.activated) {
+            this._component.configure(this._getConfiguration(false));
+        }
+    };
+    return HandlerBase;
+}());
+exports.HandlerBase = HandlerBase;
+exports.default = HandlerBase;
+
+},{}],383:[function(require,module,exports){
+"use strict";
+/// <reference path="../../../typings/index.d.ts" />
+Object.defineProperty(exports, "__esModule", { value: true });
+var THREE = require("three");
+var Component_1 = require("../../Component");
+var MeshFactory = /** @class */ (function () {
+    function MeshFactory(imagePlaneDepth, imageSphereRadius) {
+        this._imagePlaneDepth = imagePlaneDepth != null ? imagePlaneDepth : 200;
+        this._imageSphereRadius = imageSphereRadius != null ? imageSphereRadius : 200;
+    }
+    MeshFactory.prototype.createMesh = function (node, transform) {
+        var mesh = node.pano ?
+            this._createImageSphere(node, transform) :
+            this._createImagePlane(node, transform);
+        return mesh;
+    };
+    MeshFactory.prototype.createScaledFlatMesh = function (node, transform, dx, dy) {
+        var texture = this._createTexture(node.image);
+        var materialParameters = this._createPlaneMaterialParameters(transform, texture);
+        var material = new THREE.ShaderMaterial(materialParameters);
+        var geometry = this._getFlatImagePlaneGeo(transform, dx, dy);
+        return new THREE.Mesh(geometry, material);
+    };
+    MeshFactory.prototype.createFlatMesh = function (node, transform, basicX0, basicX1, basicY0, basicY1) {
+        var texture = this._createTexture(node.image);
+        var materialParameters = this._createPlaneMaterialParameters(transform, texture);
+        var material = new THREE.ShaderMaterial(materialParameters);
+        var geometry = this._getFlatImagePlaneGeoFromBasic(transform, basicX0, basicX1, basicY0, basicY1);
+        return new THREE.Mesh(geometry, material);
+    };
+    MeshFactory.prototype.createCurtainMesh = function (node, transform) {
+        if (node.pano && !node.fullPano) {
+            throw new Error("Cropped panoramas cannot have curtain.");
+        }
+        return node.pano ?
+            this._createSphereCurtainMesh(node, transform) :
+            this._createCurtainMesh(node, transform);
+    };
+    MeshFactory.prototype._createCurtainMesh = function (node, transform) {
+        var texture = this._createTexture(node.image);
+        var materialParameters = this._createCurtainPlaneMaterialParameters(transform, texture);
+        var material = new THREE.ShaderMaterial(materialParameters);
+        var geometry = this._useMesh(transform, node) ?
+            this._getImagePlaneGeo(transform, node) :
+            this._getRegularFlatImagePlaneGeo(transform);
+        return new THREE.Mesh(geometry, material);
+    };
+    MeshFactory.prototype._createSphereCurtainMesh = function (node, transform) {
+        var texture = this._createTexture(node.image);
+        var materialParameters = this._createCurtainSphereMaterialParameters(transform, texture);
+        var material = new THREE.ShaderMaterial(materialParameters);
+        return this._useMesh(transform, node) ?
+            new THREE.Mesh(this._getImageSphereGeo(transform, node), material) :
+            new THREE.Mesh(this._getFlatImageSphereGeo(transform), material);
+    };
+    MeshFactory.prototype._createImageSphere = function (node, transform) {
+        var texture = this._createTexture(node.image);
+        var materialParameters = this._createSphereMaterialParameters(transform, texture);
+        var material = new THREE.ShaderMaterial(materialParameters);
+        var mesh = this._useMesh(transform, node) ?
+            new THREE.Mesh(this._getImageSphereGeo(transform, node), material) :
+            new THREE.Mesh(this._getFlatImageSphereGeo(transform), material);
+        return mesh;
+    };
+    MeshFactory.prototype._createImagePlane = function (node, transform) {
+        var texture = this._createTexture(node.image);
+        var materialParameters = this._createPlaneMaterialParameters(transform, texture);
+        var material = new THREE.ShaderMaterial(materialParameters);
+        var geometry = this._useMesh(transform, node) ?
+            this._getImagePlaneGeo(transform, node) :
+            this._getRegularFlatImagePlaneGeo(transform);
+        return new THREE.Mesh(geometry, material);
+    };
+    MeshFactory.prototype._createSphereMaterialParameters = function (transform, texture) {
+        var gpano = transform.gpano;
+        var halfCroppedWidth = (gpano.FullPanoWidthPixels - gpano.CroppedAreaImageWidthPixels) / 2;
+        var phiShift = 2 * Math.PI * (gpano.CroppedAreaLeftPixels - halfCroppedWidth) / gpano.FullPanoWidthPixels;
+        var phiLength = 2 * Math.PI * gpano.CroppedAreaImageWidthPixels / gpano.FullPanoWidthPixels;
+        var halfCroppedHeight = (gpano.FullPanoHeightPixels - gpano.CroppedAreaImageHeightPixels) / 2;
+        var thetaShift = Math.PI * (halfCroppedHeight - gpano.CroppedAreaTopPixels) / gpano.FullPanoHeightPixels;
+        var thetaLength = Math.PI * gpano.CroppedAreaImageHeightPixels / gpano.FullPanoHeightPixels;
+        var materialParameters = {
+            depthWrite: false,
+            fragmentShader: Component_1.Shaders.equirectangular.fragment,
+            side: THREE.DoubleSide,
+            transparent: true,
+            uniforms: {
+                opacity: {
+                    type: "f",
+                    value: 1,
+                },
+                phiLength: {
+                    type: "f",
+                    value: phiLength,
+                },
+                phiShift: {
+                    type: "f",
+                    value: phiShift,
+                },
+                projectorMat: {
+                    type: "m4",
+                    value: transform.rt,
+                },
+                projectorTex: {
+                    type: "t",
+                    value: texture,
+                },
+                thetaLength: {
+                    type: "f",
+                    value: thetaLength,
+                },
+                thetaShift: {
+                    type: "f",
+                    value: thetaShift,
+                },
+            },
+            vertexShader: Component_1.Shaders.equirectangular.vertex,
+        };
+        return materialParameters;
+    };
+    MeshFactory.prototype._createCurtainSphereMaterialParameters = function (transform, texture) {
+        var gpano = transform.gpano;
+        var halfCroppedWidth = (gpano.FullPanoWidthPixels - gpano.CroppedAreaImageWidthPixels) / 2;
+        var phiShift = 2 * Math.PI * (gpano.CroppedAreaLeftPixels - halfCroppedWidth) / gpano.FullPanoWidthPixels;
+        var phiLength = 2 * Math.PI * gpano.CroppedAreaImageWidthPixels / gpano.FullPanoWidthPixels;
+        var halfCroppedHeight = (gpano.FullPanoHeightPixels - gpano.CroppedAreaImageHeightPixels) / 2;
+        var thetaShift = Math.PI * (halfCroppedHeight - gpano.CroppedAreaTopPixels) / gpano.FullPanoHeightPixels;
+        var thetaLength = Math.PI * gpano.CroppedAreaImageHeightPixels / gpano.FullPanoHeightPixels;
+        var materialParameters = {
+            depthWrite: false,
+            fragmentShader: Component_1.Shaders.equirectangularCurtain.fragment,
+            side: THREE.DoubleSide,
+            transparent: true,
+            uniforms: {
+                curtain: {
+                    type: "f",
+                    value: 1,
+                },
+                opacity: {
+                    type: "f",
+                    value: 1,
+                },
+                phiLength: {
+                    type: "f",
+                    value: phiLength,
+                },
+                phiShift: {
+                    type: "f",
+                    value: phiShift,
+                },
+                projectorMat: {
+                    type: "m4",
+                    value: transform.rt,
+                },
+                projectorTex: {
+                    type: "t",
+                    value: texture,
+                },
+                thetaLength: {
+                    type: "f",
+                    value: thetaLength,
+                },
+                thetaShift: {
+                    type: "f",
+                    value: thetaShift,
+                },
+            },
+            vertexShader: Component_1.Shaders.equirectangularCurtain.vertex,
+        };
+        return materialParameters;
+    };
+    MeshFactory.prototype._createPlaneMaterialParameters = function (transform, texture) {
+        var materialParameters = {
+            depthWrite: false,
+            fragmentShader: Component_1.Shaders.perspective.fragment,
+            side: THREE.DoubleSide,
+            transparent: true,
+            uniforms: {
+                opacity: {
+                    type: "f",
+                    value: 1,
+                },
+                projectorMat: {
+                    type: "m4",
+                    value: transform.projectorMatrix(),
+                },
+                projectorTex: {
+                    type: "t",
+                    value: texture,
+                },
+            },
+            vertexShader: Component_1.Shaders.perspective.vertex,
+        };
+        return materialParameters;
+    };
+    MeshFactory.prototype._createCurtainPlaneMaterialParameters = function (transform, texture) {
+        var materialParameters = {
+            depthWrite: false,
+            fragmentShader: Component_1.Shaders.perspectiveCurtain.fragment,
+            side: THREE.DoubleSide,
+            transparent: true,
+            uniforms: {
+                curtain: {
+                    type: "f",
+                    value: 1,
+                },
+                opacity: {
+                    type: "f",
+                    value: 1,
+                },
+                projectorMat: {
+                    type: "m4",
+                    value: transform.projectorMatrix(),
+                },
+                projectorTex: {
+                    type: "t",
+                    value: texture,
+                },
+            },
+            vertexShader: Component_1.Shaders.perspective.vertex,
+        };
+        return materialParameters;
+    };
+    MeshFactory.prototype._createTexture = function (image) {
+        var texture = new THREE.Texture(image);
+        texture.minFilter = THREE.LinearFilter;
+        texture.needsUpdate = true;
+        return texture;
+    };
+    MeshFactory.prototype._useMesh = function (transform, node) {
+        return node.mesh.vertices.length && transform.hasValidScale;
+    };
+    MeshFactory.prototype._getImageSphereGeo = function (transform, node) {
+        var t = new THREE.Matrix4().getInverse(transform.srt);
+        // push everything at least 5 meters in front of the camera
+        var minZ = 5.0 * transform.scale;
+        var maxZ = this._imageSphereRadius * transform.scale;
+        var vertices = node.mesh.vertices;
+        var numVertices = vertices.length / 3;
+        var positions = new Float32Array(vertices.length);
+        for (var i = 0; i < numVertices; ++i) {
+            var index = 3 * i;
+            var x = vertices[index + 0];
+            var y = vertices[index + 1];
+            var z = vertices[index + 2];
+            var l = Math.sqrt(x * x + y * y + z * z);
+            var boundedL = Math.max(minZ, Math.min(l, maxZ));
+            var factor = boundedL / l;
+            var p = new THREE.Vector3(x * factor, y * factor, z * factor);
+            p.applyMatrix4(t);
+            positions[index + 0] = p.x;
+            positions[index + 1] = p.y;
+            positions[index + 2] = p.z;
+        }
+        var faces = node.mesh.faces;
+        var indices = new Uint16Array(faces.length);
+        for (var i = 0; i < faces.length; ++i) {
+            indices[i] = faces[i];
+        }
+        var geometry = new THREE.BufferGeometry();
+        geometry.addAttribute("position", new THREE.BufferAttribute(positions, 3));
+        geometry.setIndex(new THREE.BufferAttribute(indices, 1));
+        return geometry;
+    };
+    MeshFactory.prototype._getImagePlaneGeo = function (transform, node) {
+        var t = new THREE.Matrix4().getInverse(transform.srt);
+        // push everything at least 5 meters in front of the camera
+        var minZ = 5.0 * transform.scale;
+        var maxZ = this._imagePlaneDepth * transform.scale;
+        var vertices = node.mesh.vertices;
+        var numVertices = vertices.length / 3;
+        var positions = new Float32Array(vertices.length);
+        for (var i = 0; i < numVertices; ++i) {
+            var index = 3 * i;
+            var x = vertices[index + 0];
+            var y = vertices[index + 1];
+            var z = vertices[index + 2];
+            var boundedZ = Math.max(minZ, Math.min(z, maxZ));
+            var factor = boundedZ / z;
+            var p = new THREE.Vector3(x * factor, y * factor, boundedZ);
+            p.applyMatrix4(t);
+            positions[index + 0] = p.x;
+            positions[index + 1] = p.y;
+            positions[index + 2] = p.z;
+        }
+        var faces = node.mesh.faces;
+        var indices = new Uint16Array(faces.length);
+        for (var i = 0; i < faces.length; ++i) {
+            indices[i] = faces[i];
+        }
+        var geometry = new THREE.BufferGeometry();
+        geometry.addAttribute("position", new THREE.BufferAttribute(positions, 3));
+        geometry.setIndex(new THREE.BufferAttribute(indices, 1));
+        return geometry;
+    };
+    MeshFactory.prototype._getFlatImageSphereGeo = function (transform) {
+        var gpano = transform.gpano;
+        var phiStart = 2 * Math.PI * gpano.CroppedAreaLeftPixels / gpano.FullPanoWidthPixels;
+        var phiLength = 2 * Math.PI * gpano.CroppedAreaImageWidthPixels / gpano.FullPanoWidthPixels;
+        var thetaStart = Math.PI *
+            (gpano.FullPanoHeightPixels - gpano.CroppedAreaImageHeightPixels - gpano.CroppedAreaTopPixels) /
+            gpano.FullPanoHeightPixels;
+        var thetaLength = Math.PI * gpano.CroppedAreaImageHeightPixels / gpano.FullPanoHeightPixels;
+        var geometry = new THREE.SphereGeometry(this._imageSphereRadius, 20, 40, phiStart - Math.PI / 2, phiLength, thetaStart, thetaLength);
+        geometry.applyMatrix(new THREE.Matrix4().getInverse(transform.rt));
+        return geometry;
+    };
+    MeshFactory.prototype._getRegularFlatImagePlaneGeo = function (transform) {
+        var width = transform.width;
+        var height = transform.height;
+        var size = Math.max(width, height);
+        var dx = width / 2.0 / size;
+        var dy = height / 2.0 / size;
+        return this._getFlatImagePlaneGeo(transform, dx, dy);
+    };
+    MeshFactory.prototype._getFlatImagePlaneGeo = function (transform, dx, dy) {
+        var vertices = [];
+        vertices.push(transform.unprojectSfM([-dx, -dy], this._imagePlaneDepth));
+        vertices.push(transform.unprojectSfM([dx, -dy], this._imagePlaneDepth));
+        vertices.push(transform.unprojectSfM([dx, dy], this._imagePlaneDepth));
+        vertices.push(transform.unprojectSfM([-dx, dy], this._imagePlaneDepth));
+        return this._createFlatGeometry(vertices);
+    };
+    MeshFactory.prototype._getFlatImagePlaneGeoFromBasic = function (transform, basicX0, basicX1, basicY0, basicY1) {
+        var vertices = [];
+        vertices.push(transform.unprojectBasic([basicX0, basicY0], this._imagePlaneDepth));
+        vertices.push(transform.unprojectBasic([basicX1, basicY0], this._imagePlaneDepth));
+        vertices.push(transform.unprojectBasic([basicX1, basicY1], this._imagePlaneDepth));
+        vertices.push(transform.unprojectBasic([basicX0, basicY1], this._imagePlaneDepth));
+        return this._createFlatGeometry(vertices);
+    };
+    MeshFactory.prototype._createFlatGeometry = function (vertices) {
+        var positions = new Float32Array(12);
+        for (var i = 0; i < vertices.length; i++) {
+            var index = 3 * i;
+            positions[index + 0] = vertices[i][0];
+            positions[index + 1] = vertices[i][1];
+            positions[index + 2] = vertices[i][2];
+        }
+        var indices = new Uint16Array(6);
+        indices[0] = 0;
+        indices[1] = 1;
+        indices[2] = 3;
+        indices[3] = 1;
+        indices[4] = 2;
+        indices[5] = 3;
+        var geometry = new THREE.BufferGeometry();
+        geometry.addAttribute("position", new THREE.BufferAttribute(positions, 3));
+        geometry.setIndex(new THREE.BufferAttribute(indices, 1));
+        return geometry;
+    };
+    return MeshFactory;
+}());
+exports.MeshFactory = MeshFactory;
+exports.default = MeshFactory;
+
+},{"../../Component":290,"three":240}],384:[function(require,module,exports){
+"use strict";
+/// <reference path="../../../typings/index.d.ts" />
+Object.defineProperty(exports, "__esModule", { value: true });
+var THREE = require("three");
+var MeshScene = /** @class */ (function () {
+    function MeshScene() {
+        this.scene = new THREE.Scene();
+        this.sceneOld = new THREE.Scene();
+        this.imagePlanes = [];
+        this.imagePlanesOld = [];
+    }
+    MeshScene.prototype.updateImagePlanes = function (planes) {
+        this._dispose(this.imagePlanesOld, this.sceneOld);
+        for (var _i = 0, _a = this.imagePlanes; _i < _a.length; _i++) {
+            var plane = _a[_i];
+            this.scene.remove(plane);
+            this.sceneOld.add(plane);
+        }
+        for (var _b = 0, planes_1 = planes; _b < planes_1.length; _b++) {
+            var plane = planes_1[_b];
+            this.scene.add(plane);
+        }
+        this.imagePlanesOld = this.imagePlanes;
+        this.imagePlanes = planes;
+    };
+    MeshScene.prototype.addImagePlanes = function (planes) {
+        for (var _i = 0, planes_2 = planes; _i < planes_2.length; _i++) {
+            var plane = planes_2[_i];
+            this.scene.add(plane);
+            this.imagePlanes.push(plane);
+        }
+    };
+    MeshScene.prototype.addImagePlanesOld = function (planes) {
+        for (var _i = 0, planes_3 = planes; _i < planes_3.length; _i++) {
+            var plane = planes_3[_i];
+            this.sceneOld.add(plane);
+            this.imagePlanesOld.push(plane);
+        }
+    };
+    MeshScene.prototype.setImagePlanes = function (planes) {
+        this._clear();
+        this.addImagePlanes(planes);
+    };
+    MeshScene.prototype.setImagePlanesOld = function (planes) {
+        this._clearOld();
+        this.addImagePlanesOld(planes);
+    };
+    MeshScene.prototype.clear = function () {
+        this._clear();
+        this._clearOld();
+    };
+    MeshScene.prototype._clear = function () {
+        this._dispose(this.imagePlanes, this.scene);
+        this.imagePlanes.length = 0;
+    };
+    MeshScene.prototype._clearOld = function () {
+        this._dispose(this.imagePlanesOld, this.sceneOld);
+        this.imagePlanesOld.length = 0;
+    };
+    MeshScene.prototype._dispose = function (planes, scene) {
+        for (var _i = 0, planes_4 = planes; _i < planes_4.length; _i++) {
+            var plane = planes_4[_i];
+            scene.remove(plane);
+            plane.geometry.dispose();
+            plane.material.dispose();
+            var texture = plane.material.uniforms.projectorTex.value;
+            if (texture != null) {
+                texture.dispose();
+            }
+        }
+    };
+    return MeshScene;
+}());
+exports.MeshScene = MeshScene;
+exports.default = MeshScene;
 
-},{"../../../Component":281}],372:[function(require,module,exports){
+},{"three":240}],385:[function(require,module,exports){
 "use strict";
+/// <reference path="../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
         ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
@@ -34187,166 +35854,101 @@ var __extends = (this && this.__extends) || (function () {
     };
 })();
 Object.defineProperty(exports, "__esModule", { value: true });
+var vd = require("virtual-dom");
+var Observable_1 = require("rxjs/Observable");
 var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/share");
-var Utils_1 = require("../../../Utils");
-/**
- * @class Tag
- * @abstract
- * @classdesc Abstract class representing the basic functionality of for a tag.
- */
-var Tag = /** @class */ (function (_super) {
-    __extends(Tag, _super);
-    /**
-     * Create a tag.
-     *
-     * @constructor
-     * @param {string} id
-     * @param {Geometry} geometry
-     */
-    function Tag(id, geometry) {
-        var _this = _super.call(this) || this;
-        _this._id = id;
-        _this._geometry = geometry;
-        _this._notifyChanged$ = new Subject_1.Subject();
-        _this._notifyChanged$
-            .subscribe(function (t) {
-            _this.fire(Tag.changed, _this);
-        });
-        _this._geometry.changed$
-            .subscribe(function (g) {
-            _this.fire(Tag.geometrychanged, _this);
-        });
+var Component_1 = require("../../Component");
+var Geo_1 = require("../../Geo");
+var State_1 = require("../../State");
+var ZoomComponent = /** @class */ (function (_super) {
+    __extends(ZoomComponent, _super);
+    function ZoomComponent(name, container, navigator) {
+        var _this = _super.call(this, name, container, navigator) || this;
+        _this._viewportCoords = new Geo_1.ViewportCoords();
+        _this._zoomDelta$ = new Subject_1.Subject();
         return _this;
     }
-    Object.defineProperty(Tag.prototype, "id", {
-        /**
-         * Get id property.
-         * @returns {string}
-         */
-        get: function () {
-            return this._id;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    Object.defineProperty(Tag.prototype, "geometry", {
-        /**
-         * Get geometry property.
-         * @returns {Geometry} The geometry of the tag.
-         */
-        get: function () {
-            return this._geometry;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    Object.defineProperty(Tag.prototype, "changed$", {
-        /**
-         * Get changed observable.
-         * @returns {Observable<Tag>}
-         * @ignore
-         */
-        get: function () {
-            return this._notifyChanged$;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    Object.defineProperty(Tag.prototype, "geometryChanged$", {
-        /**
-         * Get geometry changed observable.
-         * @returns {Observable<Tag>}
-         * @ignore
-         */
-        get: function () {
-            var _this = this;
-            return this._geometry.changed$
-                .map(function (geometry) {
-                return _this;
-            })
-                .share();
-        },
-        enumerable: true,
-        configurable: true
-    });
-    /**
-     * Event fired when a property related to the visual appearance of the
-     * tag has changed.
-     *
-     * @event Tag#changed
-     * @type {Tag} The tag instance that has changed.
-     */
-    Tag.changed = "changed";
-    /**
-     * Event fired when the geometry of the tag has changed.
-     *
-     * @event Tag#geometrychanged
-     * @type {Tag} The tag instance whose geometry has changed.
-     */
-    Tag.geometrychanged = "geometrychanged";
-    return Tag;
-}(Utils_1.EventEmitter));
-exports.Tag = Tag;
-exports.default = Tag;
+    ZoomComponent.prototype._activate = function () {
+        var _this = this;
+        this._renderSubscription = Observable_1.Observable
+            .combineLatest(this._navigator.stateService.currentState$, this._navigator.stateService.state$)
+            .map(function (_a) {
+            var frame = _a[0], state = _a[1];
+            return [frame.state.zoom, state];
+        })
+            .map(function (_a) {
+            var zoom = _a[0], state = _a[1];
+            var zoomInIcon = vd.h("div.ZoomInIcon", []);
+            var zoomInButton = zoom >= 3 || state === State_1.State.Waiting ?
+                vd.h("div.ZoomInButtonDisabled", [zoomInIcon]) :
+                vd.h("div.ZoomInButton", { onclick: function () { _this._zoomDelta$.next(1); } }, [zoomInIcon]);
+            var zoomOutIcon = vd.h("div.ZoomOutIcon", []);
+            var zoomOutButton = zoom <= 0 || state === State_1.State.Waiting ?
+                vd.h("div.ZoomOutButtonDisabled", [zoomOutIcon]) :
+                vd.h("div.ZoomOutButton", { onclick: function () { _this._zoomDelta$.next(-1); } }, [zoomOutIcon]);
+            return {
+                name: _this._name,
+                vnode: vd.h("div.ZoomContainer", { oncontextmenu: function (event) { event.preventDefault(); } }, [zoomInButton, zoomOutButton]),
+            };
+        })
+            .subscribe(this._container.domRenderer.render$);
+        this._zoomSubscription = this._zoomDelta$
+            .withLatestFrom(this._container.renderService.renderCamera$, this._navigator.stateService.currentTransform$)
+            .subscribe(function (_a) {
+            var zoomDelta = _a[0], render = _a[1], transform = _a[2];
+            var unprojected = _this._viewportCoords.unprojectFromViewport(0, 0, render.perspective);
+            var reference = transform.projectBasic(unprojected.toArray());
+            _this._navigator.stateService.zoomIn(zoomDelta, reference);
+        });
+    };
+    ZoomComponent.prototype._deactivate = function () {
+        this._renderSubscription.unsubscribe();
+        this._zoomSubscription.unsubscribe();
+    };
+    ZoomComponent.prototype._getDefaultConfiguration = function () {
+        return {};
+    };
+    ZoomComponent.componentName = "zoom";
+    return ZoomComponent;
+}(Component_1.Component));
+exports.ZoomComponent = ZoomComponent;
+Component_1.ComponentService.register(ZoomComponent);
+exports.default = ZoomComponent;
 
-},{"../../../Utils":291,"rxjs/Subject":34,"rxjs/add/operator/map":65,"rxjs/add/operator/share":76}],373:[function(require,module,exports){
+},{"../../Component":290,"../../Geo":293,"../../State":297,"rxjs/Observable":29,"rxjs/Subject":34,"virtual-dom":246}],386:[function(require,module,exports){
 "use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
 Object.defineProperty(exports, "__esModule", { value: true });
-var HandlerBase = /** @class */ (function () {
-    function HandlerBase(component, container, navigator) {
-        this._component = component;
-        this._container = container;
-        this._navigator = navigator;
-        this._enabled = false;
+var MapillaryError_1 = require("./MapillaryError");
+/**
+ * @class AbortMapillaryError
+ *
+ * @classdesc Error thrown when a move to request has been
+ * aborted before completing because of a subsequent request.
+ */
+var AbortMapillaryError = /** @class */ (function (_super) {
+    __extends(AbortMapillaryError, _super);
+    function AbortMapillaryError(message) {
+        var _this = _super.call(this, message != null ? message : "The request was aborted.") || this;
+        Object.setPrototypeOf(_this, AbortMapillaryError.prototype);
+        _this.name = "AbortMapillaryError";
+        return _this;
     }
-    Object.defineProperty(HandlerBase.prototype, "isEnabled", {
-        /**
-         * Returns a Boolean indicating whether the interaction is enabled.
-         *
-         * @returns {boolean} `true` if the interaction is enabled.
-         */
-        get: function () {
-            return this._enabled;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    /**
-     * Enables the interaction.
-     *
-     * @example ```<component-name>.<handler-name>.enable();```
-     */
-    HandlerBase.prototype.enable = function () {
-        if (this._enabled || !this._component.activated) {
-            return;
-        }
-        this._enable();
-        this._enabled = true;
-        this._component.configure(this._getConfiguration(true));
-    };
-    /**
-     * Disables the interaction.
-     *
-     * @example ```<component-name>.<handler-name>.disable();```
-     */
-    HandlerBase.prototype.disable = function () {
-        if (!this._enabled) {
-            return;
-        }
-        this._disable();
-        this._enabled = false;
-        if (this._component.activated) {
-            this._component.configure(this._getConfiguration(false));
-        }
-    };
-    return HandlerBase;
-}());
-exports.HandlerBase = HandlerBase;
-exports.default = HandlerBase;
+    return AbortMapillaryError;
+}(MapillaryError_1.MapillaryError));
+exports.AbortMapillaryError = AbortMapillaryError;
+exports.default = AbortMapillaryError;
 
-},{}],374:[function(require,module,exports){
+},{"./MapillaryError":389}],387:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -34364,6 +35966,7 @@ var ArgumentMapillaryError = /** @class */ (function (_super) {
     __extends(ArgumentMapillaryError, _super);
     function ArgumentMapillaryError(message) {
         var _this = _super.call(this, message != null ? message : "The argument is not valid.") || this;
+        Object.setPrototypeOf(_this, ArgumentMapillaryError.prototype);
         _this.name = "ArgumentMapillaryError";
         return _this;
     }
@@ -34372,7 +35975,7 @@ var ArgumentMapillaryError = /** @class */ (function (_super) {
 exports.ArgumentMapillaryError = ArgumentMapillaryError;
 exports.default = ArgumentMapillaryError;
 
-},{"./MapillaryError":376}],375:[function(require,module,exports){
+},{"./MapillaryError":389}],388:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -34390,6 +35993,7 @@ var GraphMapillaryError = /** @class */ (function (_super) {
     __extends(GraphMapillaryError, _super);
     function GraphMapillaryError(message) {
         var _this = _super.call(this, message) || this;
+        Object.setPrototypeOf(_this, GraphMapillaryError.prototype);
         _this.name = "GraphMapillaryError";
         return _this;
     }
@@ -34398,7 +36002,7 @@ var GraphMapillaryError = /** @class */ (function (_super) {
 exports.GraphMapillaryError = GraphMapillaryError;
 exports.default = GraphMapillaryError;
 
-},{"./MapillaryError":376}],376:[function(require,module,exports){
+},{"./MapillaryError":389}],389:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -34415,6 +36019,7 @@ var MapillaryError = /** @class */ (function (_super) {
     __extends(MapillaryError, _super);
     function MapillaryError(message) {
         var _this = _super.call(this, message) || this;
+        Object.setPrototypeOf(_this, MapillaryError.prototype);
         _this.name = "MapillaryError";
         return _this;
     }
@@ -34423,7 +36028,7 @@ var MapillaryError = /** @class */ (function (_super) {
 exports.MapillaryError = MapillaryError;
 exports.default = MapillaryError;
 
-},{}],377:[function(require,module,exports){
+},{}],390:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -34573,7 +36178,7 @@ var Camera = /** @class */ (function () {
 }());
 exports.Camera = Camera;
 
-},{"three":231}],378:[function(require,module,exports){
+},{"three":240}],391:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 /**
@@ -34797,7 +36402,7 @@ var GeoCoords = /** @class */ (function () {
 exports.GeoCoords = GeoCoords;
 exports.default = GeoCoords;
 
-},{}],379:[function(require,module,exports){
+},{}],392:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -34980,8 +36585,9 @@ var Spatial = /** @class */ (function () {
         var R2 = this.rotationMatrix(rotation2);
         var R = R1T.multiply(R2);
         var elements = R.elements;
-        // from Tr(R) = 1 + 2*cos(theta)
-        var theta = Math.acos((elements[0] + elements[5] + elements[10] - 1) / 2);
+        // from Tr(R) = 1 + 2 * cos(theta)
+        var tr = elements[0] + elements[5] + elements[10];
+        var theta = Math.acos(Math.max(Math.min((tr - 1) / 2, 1), -1));
         return theta;
     };
     /**
@@ -35005,18 +36611,18 @@ var Spatial = /** @class */ (function () {
      * (latitude longitude pairs) in meters according to
      * the haversine formula.
      *
-     * @param {number} lat1 - Latitude of the first coordinate.
-     * @param {number} lon1 - Longitude of the first coordinate.
-     * @param {number} lat2 - Latitude of the second coordinate.
-     * @param {number} lon2 - Longitude of the second coordinate.
-     * @returns {number} Distance between lat lon positions.
+     * @param {number} lat1 - Latitude of the first coordinate in degrees.
+     * @param {number} lon1 - Longitude of the first coordinate in degrees.
+     * @param {number} lat2 - Latitude of the second coordinate in degrees.
+     * @param {number} lon2 - Longitude of the second coordinate in degrees.
+     * @returns {number} Distance between lat lon positions in meters.
      */
     Spatial.prototype.distanceFromLatLon = function (lat1, lon1, lat2, lon2) {
         var r = 6371000;
         var dLat = this.degToRad(lat2 - lat1);
         var dLon = this.degToRad(lon2 - lon1);
         var hav = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
-            Math.cos(lat1) * Math.cos(lat2) *
+            Math.cos(this.degToRad(lat1)) * Math.cos(this.degToRad(lat2)) *
                 Math.sin(dLon / 2) * Math.sin(dLon / 2);
         var d = 2 * r * Math.atan2(Math.sqrt(hav), Math.sqrt(1 - hav));
         return d;
@@ -35026,7 +36632,7 @@ var Spatial = /** @class */ (function () {
 exports.Spatial = Spatial;
 exports.default = Spatial;
 
-},{"three":231}],380:[function(require,module,exports){
+},{"three":240}],393:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -35040,27 +36646,34 @@ var THREE = require("three");
 var Transform = /** @class */ (function () {
     /**
      * Create a new transform instance.
-     * @param {Node} apiNavImIm - Node properties.
-     * @param {HTMLImageElement} image - Node image.
-     * @param {Array<number>} translation - Node translation vector in three dimensions.
-     */
-    function Transform(node, image, translation) {
-        this._orientation = this._getValue(node.orientation, 1);
+     * @param {number} orientation - Image orientation.
+     * @param {number} width - Image height.
+     * @param {number} height - Image width.
+     * @param {number} focal - Focal length.
+     * @param {number} scale - Atomic scale.
+     * @param {IGPano} gpano - Panorama properties.
+     * @param {Array<number>} rotation - Rotation vector in three dimensions.
+     * @param {Array<number>} translation - Translation vector in three dimensions.
+     * @param {HTMLImageElement} image - Image for fallback size calculations.
+     */
+    function Transform(orientation, width, height, focal, scale, gpano, rotation, translation, image, textureScale) {
+        this._orientation = this._getValue(orientation, 1);
         var imageWidth = image != null ? image.width : 4;
         var imageHeight = image != null ? image.height : 3;
         var keepOrientation = this._orientation < 5;
-        this._width = this._getValue(node.width, keepOrientation ? imageWidth : imageHeight);
-        this._height = this._getValue(node.height, keepOrientation ? imageHeight : imageWidth);
+        this._width = this._getValue(width, keepOrientation ? imageWidth : imageHeight);
+        this._height = this._getValue(height, keepOrientation ? imageHeight : imageWidth);
         this._basicAspect = keepOrientation ?
             this._width / this._height :
             this._height / this._width;
-        this._basicWidth = keepOrientation ? node.width : node.height;
-        this._basicHeight = keepOrientation ? node.height : node.width;
-        this._focal = this._getValue(node.focal, 1);
-        this._scale = this._getValue(node.scale, 0);
-        this._gpano = node.gpano != null ? node.gpano : null;
-        this._rt = this._getRt(node.rotation, translation);
+        this._basicWidth = keepOrientation ? width : height;
+        this._basicHeight = keepOrientation ? height : width;
+        this._focal = this._getValue(focal, 1);
+        this._scale = this._getValue(scale, 0);
+        this._gpano = gpano != null ? gpano : null;
+        this._rt = this._getRt(rotation, translation);
         this._srt = this._getSrt(this._rt, this._scale);
+        this._textureScale = !!textureScale ? textureScale : [1, 1];
     }
     Object.defineProperty(Transform.prototype, "basicAspect", {
         /**
@@ -35536,8 +37149,10 @@ var Transform = /** @class */ (function () {
      */
     Transform.prototype._normalizedToTextureMatrix = function () {
         var size = Math.max(this._width, this._height);
-        var w = size / this._width;
-        var h = size / this._height;
+        var scaleX = this._orientation < 5 ? this._textureScale[0] : this._textureScale[1];
+        var scaleY = this._orientation < 5 ? this._textureScale[1] : this._textureScale[0];
+        var w = size / this._width * scaleX;
+        var h = size / this._height * scaleY;
         switch (this._orientation) {
             case 1:
                 return new THREE.Matrix4().set(w, 0, 0, 0.5, 0, -h, 0, 0.5, 0, 0, 1, 0, 0, 0, 0, 1);
@@ -35555,7 +37170,7 @@ var Transform = /** @class */ (function () {
 }());
 exports.Transform = Transform;
 
-},{"three":231}],381:[function(require,module,exports){
+},{"three":240}],394:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -35929,7 +37544,7 @@ var ViewportCoords = /** @class */ (function () {
 exports.ViewportCoords = ViewportCoords;
 exports.default = ViewportCoords;
 
-},{"three":231}],382:[function(require,module,exports){
+},{"three":240}],395:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 /**
@@ -36017,19 +37632,13 @@ var FilterCreator = /** @class */ (function () {
 exports.FilterCreator = FilterCreator;
 exports.default = FilterCreator;
 
-},{}],383:[function(require,module,exports){
+},{}],396:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
 var rbush = require("rbush");
 var Observable_1 = require("rxjs/Observable");
 var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/observable/from");
-require("rxjs/add/operator/catch");
-require("rxjs/add/operator/do");
-require("rxjs/add/operator/finally");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/publish");
 var Edge_1 = require("../Edge");
 var Error_1 = require("../Error");
 var Graph_1 = require("../Graph");
@@ -36100,6 +37709,92 @@ var Graph = /** @class */ (function () {
         enumerable: true,
         configurable: true
     });
+    /**
+     * Caches the full node data for all images within a bounding
+     * box.
+     *
+     * @description The node assets are not cached.
+     *
+     * @param {ILatLon} sw - South west corner of bounding box.
+     * @param {ILatLon} ne - North east corner of bounding box.
+     * @returns {Observable<Graph>} Observable emitting the full
+     * nodes in the bounding box.
+     */
+    Graph.prototype.cacheBoundingBox$ = function (sw, ne) {
+        var _this = this;
+        var cacheTiles$ = this._graphCalculator.encodeHsFromBoundingBox(sw, ne)
+            .filter(function (h) {
+            return !(h in _this._cachedTiles);
+        })
+            .map(function (h) {
+            return h in _this._cachingTiles$ ?
+                _this._cachingTiles$[h] :
+                _this._cacheTile$(h);
+        });
+        if (cacheTiles$.length === 0) {
+            cacheTiles$.push(Observable_1.Observable.of(this));
+        }
+        return Observable_1.Observable
+            .from(cacheTiles$)
+            .mergeAll()
+            .last()
+            .mergeMap(function (graph) {
+            var nodes = _this._nodeIndex
+                .search({
+                maxX: ne.lat,
+                maxY: ne.lon,
+                minX: sw.lat,
+                minY: sw.lon,
+            })
+                .map(function (item) {
+                return item.node;
+            });
+            var fullNodes = [];
+            var coreNodes = [];
+            for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
+                var node = nodes_1[_i];
+                if (node.full) {
+                    fullNodes.push(node);
+                }
+                else {
+                    coreNodes.push(node.key);
+                }
+            }
+            var coreNodeBatches = [];
+            var batchSize = 200;
+            while (coreNodes.length > 0) {
+                coreNodeBatches.push(coreNodes.splice(0, batchSize));
+            }
+            var fullNodes$ = Observable_1.Observable.of(fullNodes);
+            var fillNodes$ = coreNodeBatches
+                .map(function (batch) {
+                return _this._apiV3.imageByKeyFill$(batch)
+                    .map(function (imageByKeyFill) {
+                    var filledNodes = [];
+                    for (var fillKey in imageByKeyFill) {
+                        if (!imageByKeyFill.hasOwnProperty(fillKey)) {
+                            continue;
+                        }
+                        if (_this.hasNode(fillKey)) {
+                            var node = _this.getNode(fillKey);
+                            if (!node.full) {
+                                _this._makeFull(node, imageByKeyFill[fillKey]);
+                            }
+                            filledNodes.push(node);
+                        }
+                    }
+                    return filledNodes;
+                });
+            });
+            return Observable_1.Observable
+                .merge(fullNodes$, Observable_1.Observable
+                .from(fillNodes$)
+                .mergeAll());
+        })
+            .reduce(function (acc, value) {
+            return acc.concat(value);
+        });
+    };
     /**
      * Retrieve and cache node fill properties.
      *
@@ -36171,8 +37866,8 @@ var Graph = /** @class */ (function () {
                 }
             }
             else {
-                if (fn.sequence == null || fn.sequence.key == null) {
-                    throw new Error_1.GraphMapillaryError("Node has no sequence (" + key + ").");
+                if (fn.sequence_key == null) {
+                    throw new Error_1.GraphMapillaryError("Node has no sequence key (" + key + ").");
                 }
                 var node = new Graph_1.Node(fn);
                 _this._makeFull(node, fn);
@@ -36268,22 +37963,11 @@ var Graph = /** @class */ (function () {
         }
         var batches = [];
         var keys = sequence.keys.slice();
-        if (!!referenceNodeKey) {
+        var referenceBatchSize = 50;
+        if (!!referenceNodeKey && keys.length > referenceBatchSize) {
             var referenceIndex = keys.indexOf(referenceNodeKey);
-            if (referenceIndex !== -1) {
-                for (var _i = 0, _a = [20, 40]; _i < _a.length; _i++) {
-                    var referenceBatchSize = _a[_i];
-                    if (referenceIndex < keys.length - 1) {
-                        batches.push(keys.splice(referenceIndex, referenceBatchSize));
-                    }
-                    if (referenceIndex > 0) {
-                        var shift = referenceIndex === keys.length - 1 ? 1 : 0;
-                        var batch = keys.splice(Math.max(0, referenceIndex + shift - referenceBatchSize), referenceBatchSize);
-                        batches.push(batch);
-                        referenceIndex -= batch.length;
-                    }
-                }
-            }
+            var startIndex = Math.max(0, Math.min(referenceIndex - referenceBatchSize / 2, keys.length - referenceBatchSize));
+            batches.push(keys.splice(startIndex, referenceBatchSize));
         }
         var batchSize = 200;
         while (keys.length > 0) {
@@ -36307,8 +37991,8 @@ var Graph = /** @class */ (function () {
                         }
                     }
                     else {
-                        if (fn.sequence == null || fn.sequence.key == null) {
-                            console.warn("Sequence missing, discarding (" + fn.key + ")");
+                        if (fn.sequence_key == null) {
+                            console.warn("Sequence missing, discarding node (" + fn.key + ")");
                         }
                         var node = new Graph_1.Node(fn);
                         _this._makeFull(node, fn);
@@ -36472,8 +38156,8 @@ var Graph = /** @class */ (function () {
      * Retrieve and cache geohash tiles for a node.
      *
      * @param {string} key - Key of node for which to retrieve tiles.
-     * @returns {Observable<Graph>} Observable emitting the graph
-     * when the tiles required for the node has been cached.
+     * @returns {Array<Observable<Graph>>} Array of observables emitting
+     * the graph for each tile required for the node has been cached.
      * @throws {GraphMapillaryError} When the operation is not valid on the
      * current graph.
      */
@@ -36501,73 +38185,9 @@ var Graph = /** @class */ (function () {
         nodeTiles.cache = [];
         var cacheTiles$ = [];
         var _loop_2 = function (h) {
-            var cacheTile$ = null;
-            if (h in this_2._cachingTiles$) {
-                cacheTile$ = this_2._cachingTiles$[h];
-            }
-            else {
-                cacheTile$ = this_2._apiV3.imagesByH$([h])
-                    .do(function (imagesByH) {
-                    var coreNodes = imagesByH[h];
-                    if (h in _this._cachedTiles) {
-                        return;
-                    }
-                    _this._nodeIndexTiles[h] = [];
-                    _this._cachedTiles[h] = { accessed: new Date().getTime(), nodes: [] };
-                    var hCache = _this._cachedTiles[h].nodes;
-                    var preStored = _this._removeFromPreStore(h);
-                    for (var index in coreNodes) {
-                        if (!coreNodes.hasOwnProperty(index)) {
-                            continue;
-                        }
-                        var coreNode = coreNodes[index];
-                        if (coreNode == null) {
-                            break;
-                        }
-                        if (coreNode.sequence == null ||
-                            coreNode.sequence.key == null) {
-                            console.warn("Sequence missing, discarding (" + coreNode.key + ")");
-                            continue;
-                        }
-                        if (preStored != null && coreNode.key in preStored) {
-                            var preStoredNode = preStored[coreNode.key];
-                            delete preStored[coreNode.key];
-                            hCache.push(preStoredNode);
-                            var preStoredNodeIndexItem = {
-                                lat: preStoredNode.latLon.lat,
-                                lon: preStoredNode.latLon.lon,
-                                node: preStoredNode,
-                            };
-                            _this._nodeIndex.insert(preStoredNodeIndexItem);
-                            _this._nodeIndexTiles[h].push(preStoredNodeIndexItem);
-                            _this._nodeToTile[preStoredNode.key] = h;
-                            continue;
-                        }
-                        var node = new Graph_1.Node(coreNode);
-                        hCache.push(node);
-                        var nodeIndexItem = {
-                            lat: node.latLon.lat,
-                            lon: node.latLon.lon,
-                            node: node,
-                        };
-                        _this._nodeIndex.insert(nodeIndexItem);
-                        _this._nodeIndexTiles[h].push(nodeIndexItem);
-                        _this._nodeToTile[node.key] = h;
-                        _this._setNode(node);
-                    }
-                    delete _this._cachingTiles$[h];
-                })
-                    .map(function (imagesByH) {
-                    return _this;
-                })
-                    .catch(function (error) {
-                    delete _this._cachingTiles$[h];
-                    throw error;
-                })
-                    .publish()
-                    .refCount();
-                this_2._cachingTiles$[h] = cacheTile$;
-            }
+            var cacheTile$ = h in this_2._cachingTiles$ ?
+                this_2._cachingTiles$[h] :
+                this_2._cacheTile$(h);
             cacheTiles$.push(cacheTile$
                 .do(function (graph) {
                 var index = nodeTiles.caching.indexOf(h);
@@ -36898,8 +38518,8 @@ var Graph = /** @class */ (function () {
         this._nodes = {};
         this._nodeToTile = {};
         this._preStored = {};
-        for (var _c = 0, nodes_1 = nodes; _c < nodes_1.length; _c++) {
-            var node = nodes_1[_c];
+        for (var _c = 0, nodes_2 = nodes; _c < nodes_2.length; _c++) {
+            var node = nodes_2[_c];
             this._nodes[node.key] = node;
             var h = this._graphCalculator.encodeH(node.originalLatLon, this._tilePrecision);
             this._preStore(h, node);
@@ -37104,6 +38724,69 @@ var Graph = /** @class */ (function () {
             .refCount();
         return this._cachingSequences$[sequenceKey];
     };
+    Graph.prototype._cacheTile$ = function (h) {
+        var _this = this;
+        this._cachingTiles$[h] = this._apiV3.imagesByH$([h])
+            .do(function (imagesByH) {
+            var coreNodes = imagesByH[h];
+            if (h in _this._cachedTiles) {
+                return;
+            }
+            _this._nodeIndexTiles[h] = [];
+            _this._cachedTiles[h] = { accessed: new Date().getTime(), nodes: [] };
+            var hCache = _this._cachedTiles[h].nodes;
+            var preStored = _this._removeFromPreStore(h);
+            for (var index in coreNodes) {
+                if (!coreNodes.hasOwnProperty(index)) {
+                    continue;
+                }
+                var coreNode = coreNodes[index];
+                if (coreNode == null) {
+                    break;
+                }
+                if (coreNode.sequence_key == null) {
+                    console.warn("Sequence missing, discarding node (" + coreNode.key + ")");
+                    continue;
+                }
+                if (preStored != null && coreNode.key in preStored) {
+                    var preStoredNode = preStored[coreNode.key];
+                    delete preStored[coreNode.key];
+                    hCache.push(preStoredNode);
+                    var preStoredNodeIndexItem = {
+                        lat: preStoredNode.latLon.lat,
+                        lon: preStoredNode.latLon.lon,
+                        node: preStoredNode,
+                    };
+                    _this._nodeIndex.insert(preStoredNodeIndexItem);
+                    _this._nodeIndexTiles[h].push(preStoredNodeIndexItem);
+                    _this._nodeToTile[preStoredNode.key] = h;
+                    continue;
+                }
+                var node = new Graph_1.Node(coreNode);
+                hCache.push(node);
+                var nodeIndexItem = {
+                    lat: node.latLon.lat,
+                    lon: node.latLon.lon,
+                    node: node,
+                };
+                _this._nodeIndex.insert(nodeIndexItem);
+                _this._nodeIndexTiles[h].push(nodeIndexItem);
+                _this._nodeToTile[node.key] = h;
+                _this._setNode(node);
+            }
+            delete _this._cachingTiles$[h];
+        })
+            .map(function (imagesByH) {
+            return _this;
+        })
+            .catch(function (error) {
+            delete _this._cachingTiles$[h];
+            throw error;
+        })
+            .publish()
+            .refCount();
+        return this._cachingTiles$[h];
+    };
     Graph.prototype._makeFull = function (node, fillNode) {
         if (fillNode.calt == null) {
             fillNode.calt = this._defaultAlt;
@@ -37209,12 +38892,13 @@ var Graph = /** @class */ (function () {
 exports.Graph = Graph;
 exports.default = Graph;
 
-},{"../Edge":282,"../Error":283,"../Graph":285,"rbush":25,"rxjs/Observable":29,"rxjs/Subject":34,"rxjs/add/observable/from":41,"rxjs/add/operator/catch":52,"rxjs/add/operator/do":59,"rxjs/add/operator/finally":62,"rxjs/add/operator/map":65,"rxjs/add/operator/publish":71}],384:[function(require,module,exports){
+},{"../Edge":291,"../Error":292,"../Graph":294,"rbush":25,"rxjs/Observable":29,"rxjs/Subject":34}],397:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
 var geohash = require("latlon-geohash");
 var THREE = require("three");
+var Error_1 = require("../Error");
 var Geo_1 = require("../Geo");
 var GeoHashDirections = /** @class */ (function () {
     function GeoHashDirections() {
@@ -37311,6 +38995,32 @@ var GraphCalculator = /** @class */ (function () {
         }
         return hs;
     };
+    /**
+     * Encode the minimum set of geohash tiles containing a bounding box.
+     *
+     * @description The current algorithm does expect the bounding box
+     * to be sufficiently small to be contained in an area with the size
+     * of maximally four tiles. Up to nine adjacent tiles may be returned.
+     * The method currently uses the largest side as the threshold leading to
+     * more tiles being returned than needed in edge cases.
+     *
+     * @param {ILatLon} sw - South west corner of bounding box.
+     * @param {ILatLon} ne - North east corner of bounding box.
+     * @param {number} precision - Precision of the encoding.
+     *
+     * @returns {string} The geohash tiles containing the bounding box.
+     */
+    GraphCalculator.prototype.encodeHsFromBoundingBox = function (sw, ne, precision) {
+        if (precision === void 0) { precision = 7; }
+        if (ne.lat <= sw.lat || ne.lon <= sw.lon) {
+            throw new Error_1.GraphMapillaryError("North east needs to be top right of south west");
+        }
+        var centerLat = (sw.lat + ne.lat) / 2;
+        var centerLon = (sw.lon + ne.lon) / 2;
+        var enu = this._geoCoords.geodeticToEnu(ne.lat, ne.lon, 0, centerLat, centerLon, 0);
+        var threshold = Math.max(enu[0], enu[1]);
+        return this.encodeHs({ lat: centerLat, lon: centerLon }, precision, threshold);
+    };
     /**
      * Get the bounding box corners for a circle with radius of a threshold
      * with center in a geodetic position.
@@ -37371,7 +39081,7 @@ var GraphCalculator = /** @class */ (function () {
 exports.GraphCalculator = GraphCalculator;
 exports.default = GraphCalculator;
 
-},{"../Geo":284,"latlon-geohash":21,"three":231}],385:[function(require,module,exports){
+},{"../Error":292,"../Geo":293,"latlon-geohash":21,"three":240}],398:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 /**
@@ -37403,21 +39113,11 @@ var GraphMode;
 })(GraphMode = exports.GraphMode || (exports.GraphMode = {}));
 exports.default = GraphMode;
 
-},{}],386:[function(require,module,exports){
+},{}],399:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Observable_1 = require("rxjs/Observable");
 var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/operator/catch");
-require("rxjs/add/operator/concat");
-require("rxjs/add/operator/do");
-require("rxjs/add/operator/expand");
-require("rxjs/add/operator/finally");
-require("rxjs/add/operator/first");
-require("rxjs/add/operator/last");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/mergeMap");
-require("rxjs/add/operator/publishReplay");
 var Graph_1 = require("../Graph");
 /**
  * @class GraphService
@@ -37465,6 +39165,28 @@ var GraphService = /** @class */ (function () {
         enumerable: true,
         configurable: true
     });
+    /**
+     * Cache full nodes in a bounding box.
+     *
+     * @description When called, the full properties of
+     * the node are retrieved. The node cache is not initialized
+     * for any new nodes retrieved and the node assets are not
+     * retrieved, {@link cacheNode$} needs to be called for caching
+     * assets.
+     *
+     * @param {ILatLon} sw - South west corner of bounding box.
+     * @param {ILatLon} ne - North east corner of bounding box.
+     * @return {Observable<Array<Node>>} Observable emitting a single item,
+     * the nodes of the bounding box, when they have all been retrieved.
+     * @throws {Error} Propagates any IO node caching errors to the caller.
+     */
+    GraphService.prototype.cacheBoundingBox$ = function (sw, ne) {
+        return this._graph$
+            .first()
+            .mergeMap(function (graph) {
+            return graph.cacheBoundingBox$(sw, ne);
+        });
+    };
     /**
      * Cache a node in the graph and retrieve it.
      *
@@ -37806,7 +39528,7 @@ var GraphService = /** @class */ (function () {
 exports.GraphService = GraphService;
 exports.default = GraphService;
 
-},{"../Graph":285,"rxjs/Observable":29,"rxjs/Subject":34,"rxjs/add/operator/catch":52,"rxjs/add/operator/concat":54,"rxjs/add/operator/do":59,"rxjs/add/operator/expand":60,"rxjs/add/operator/finally":62,"rxjs/add/operator/first":63,"rxjs/add/operator/last":64,"rxjs/add/operator/map":65,"rxjs/add/operator/mergeMap":68,"rxjs/add/operator/publishReplay":72}],387:[function(require,module,exports){
+},{"../Graph":294,"rxjs/Observable":29,"rxjs/Subject":34}],400:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -37860,7 +39582,7 @@ var ImageLoadingService = /** @class */ (function () {
 }());
 exports.ImageLoadingService = ImageLoadingService;
 
-},{"rxjs/Subject":34}],388:[function(require,module,exports){
+},{"rxjs/Subject":34}],401:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -37884,11 +39606,9 @@ var MeshReader = /** @class */ (function () {
 }());
 exports.MeshReader = MeshReader;
 
-},{"pbf":23}],389:[function(require,module,exports){
+},{"pbf":23}],402:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
-require("rxjs/add/observable/combineLatest");
-require("rxjs/add/operator/map");
 /**
  * @class Node
  *
@@ -37897,16 +39617,16 @@ require("rxjs/add/operator/map");
  * Explanation of position and bearing properties:
  *
  * When images are uploaded they will have GPS information in the EXIF, this is what
- * is called `originalLatLon`(@link Node#originalLatLon).
+ * is called `originalLatLon` {@link Node.originalLatLon}.
  *
  * When Structure from Motions has been run for a node a `computedLatLon` that
  * differs from the `originalLatLon` will be created. It is different because
  * GPS positions are not very exact and SfM aligns the camera positions according
- * to the 3D reconstruction (@link Node#computedLatLon).
+ * to the 3D reconstruction {@link Node.computedLatLon}.
  *
  * At last there exist a `latLon` property which evaluates to
  * the `computedLatLon` from SfM if it exists but falls back
- * to the `originalLatLon` from the EXIF GPS otherwise (@link Node#latlon).
+ * to the `originalLatLon` from the EXIF GPS otherwise {@link Node.latlon}.
  *
  * Everything that is done in in the Viewer is based on the SfM positions,
  * i.e. `computedLatLon`. That is why the smooth transitions go in the right
@@ -37996,6 +39716,22 @@ var Node = /** @class */ (function () {
         enumerable: true,
         configurable: true
     });
+    Object.defineProperty(Node.prototype, "cameraUuid", {
+        /**
+         * Get camera uuid.
+         *
+         * @description Will be undefined if the camera uuid was not
+         * recorded in the image exif information.
+         *
+         * @returns {string} Universally unique id for camera used
+         * when capturing image.
+         */
+        get: function () {
+            return this._fill.captured_with_camera_uuid;
+        },
+        enumerable: true,
+        configurable: true
+    });
     Object.defineProperty(Node.prototype, "computedCA", {
         /**
          * Get computedCA.
@@ -38113,6 +39849,19 @@ var Node = /** @class */ (function () {
         enumerable: true,
         configurable: true
     });
+    Object.defineProperty(Node.prototype, "image$", {
+        /**
+         * Get image$.
+         *
+         * @returns {Observable<HTMLImageElement>} Observable emitting
+         * the cached image when it is updated.
+         */
+        get: function () {
+            return this._cache.image$;
+        },
+        enumerable: true,
+        configurable: true
+    });
     Object.defineProperty(Node.prototype, "key", {
         /**
          * Get key.
@@ -38214,6 +39963,20 @@ var Node = /** @class */ (function () {
         enumerable: true,
         configurable: true
     });
+    Object.defineProperty(Node.prototype, "organizationKey", {
+        /**
+         * Get organizationKey.
+         *
+         * @returns {string} Unique key of the organization to which
+         * the node belongs. If the node does not belong to an
+         * organization the organization key will be undefined.
+         */
+        get: function () {
+            return this._fill.organization_key;
+        },
+        enumerable: true,
+        configurable: true
+    });
     Object.defineProperty(Node.prototype, "orientation", {
         /**
          * Get orientation.
@@ -38266,12 +40029,29 @@ var Node = /** @class */ (function () {
         enumerable: true,
         configurable: true
     });
+    Object.defineProperty(Node.prototype, "private", {
+        /**
+         * Get private.
+         *
+         * @returns {boolean} Value specifying if image is accessible to
+         * organization members only or to everyone.
+         */
+        get: function () {
+            return this._fill.private;
+        },
+        enumerable: true,
+        configurable: true
+    });
     Object.defineProperty(Node.prototype, "projectKey", {
         /**
          * Get projectKey.
          *
          * @returns {string} Unique key of the project to which
-         * the node belongs.
+         * the node belongs. If the node does not belong to a
+         * project the project key will be undefined.
+         *
+         * @deprecated This property will be deprecated in favor
+         * of the organization key and private properties.
          */
         get: function () {
             return this._fill.project != null ?
@@ -38317,7 +40097,7 @@ var Node = /** @class */ (function () {
          * the node belongs.
          */
         get: function () {
-            return this._core.sequence.key;
+            return this._core.sequence_key;
         },
         enumerable: true,
         configurable: true
@@ -38527,14 +40307,12 @@ var Node = /** @class */ (function () {
 exports.Node = Node;
 exports.default = Node;
 
-},{"rxjs/add/observable/combineLatest":38,"rxjs/add/operator/map":65}],390:[function(require,module,exports){
+},{}],403:[function(require,module,exports){
 (function (Buffer){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Subject_1 = require("rxjs/Subject");
 var Observable_1 = require("rxjs/Observable");
-require("rxjs/add/observable/combineLatest");
-require("rxjs/add/operator/publishReplay");
 var Graph_1 = require("../Graph");
 var Utils_1 = require("../Utils");
 /**
@@ -38553,6 +40331,12 @@ var NodeCache = /** @class */ (function () {
         this._mesh = null;
         this._sequenceEdges = { cached: false, edges: [] };
         this._spatialEdges = { cached: false, edges: [] };
+        this._imageChanged$ = new Subject_1.Subject();
+        this._image$ = this._imageChanged$
+            .startWith(null)
+            .publishReplay(1)
+            .refCount();
+        this._iamgeSubscription = this._image$.subscribe();
         this._sequenceEdgesChanged$ = new Subject_1.Subject();
         this._sequenceEdges$ = this._sequenceEdgesChanged$
             .startWith(this._sequenceEdges)
@@ -38582,6 +40366,19 @@ var NodeCache = /** @class */ (function () {
         enumerable: true,
         configurable: true
     });
+    Object.defineProperty(NodeCache.prototype, "image$", {
+        /**
+         * Get image$.
+         *
+         * @returns {Observable<HTMLImageElement>} Observable emitting
+         * the cached image when it is updated.
+         */
+        get: function () {
+            return this._image$;
+        },
+        enumerable: true,
+        configurable: true
+    });
     Object.defineProperty(NodeCache.prototype, "loadStatus", {
         /**
          * Get loadStatus.
@@ -38702,6 +40499,13 @@ var NodeCache = /** @class */ (function () {
         })
             .publishReplay(1)
             .refCount();
+        this._cachingAssets$
+            .first(function (nodeCache) {
+            return !!nodeCache._image;
+        })
+            .subscribe(function (nodeCache) {
+            _this._imageChanged$.next(_this._image);
+        }, function (error) { });
         return this._cachingAssets$;
     };
     /**
@@ -38719,7 +40523,7 @@ var NodeCache = /** @class */ (function () {
         if (this._image != null && imageSize <= Math.max(this._image.width, this._image.height)) {
             return Observable_1.Observable.of(this);
         }
-        return this._cacheImage$(key, imageSize)
+        var cacheImage$ = this._cacheImage$(key, imageSize)
             .first(function (status) {
             return status.object != null;
         })
@@ -38729,7 +40533,14 @@ var NodeCache = /** @class */ (function () {
         })
             .map(function (imageStatus) {
             return _this;
-        });
+        })
+            .publishReplay(1)
+            .refCount();
+        cacheImage$
+            .subscribe(function (nodeCache) {
+            _this._imageChanged$.next(_this._image);
+        }, function (error) { });
+        return cacheImage$;
     };
     /**
      * Cache the sequence edges.
@@ -38756,6 +40567,7 @@ var NodeCache = /** @class */ (function () {
      * all streams.
      */
     NodeCache.prototype.dispose = function () {
+        this._iamgeSubscription.unsubscribe();
         this._sequenceEdgesSubscription.unsubscribe();
         this._spatialEdgesSubscription.unsubscribe();
         this._disposeImage();
@@ -38764,6 +40576,7 @@ var NodeCache = /** @class */ (function () {
         this._loadStatus.total = 0;
         this._sequenceEdges = { cached: false, edges: [] };
         this._spatialEdges = { cached: false, edges: [] };
+        this._imageChanged$.next(null);
         this._sequenceEdgesChanged$.next(this._sequenceEdges);
         this._spatialEdgesChanged$.next(this._spatialEdges);
         this._disposed = true;
@@ -38801,7 +40614,7 @@ var NodeCache = /** @class */ (function () {
         var _this = this;
         return Observable_1.Observable.create(function (subscriber) {
             var xmlHTTP = new XMLHttpRequest();
-            xmlHTTP.open("GET", Utils_1.Urls.thumbnail(key, imageSize), true);
+            xmlHTTP.open("GET", Utils_1.Urls.thumbnail(key, imageSize, Utils_1.Urls.origin), true);
             xmlHTTP.responseType = "arraybuffer";
             xmlHTTP.timeout = 15000;
             xmlHTTP.onload = function (pe) {
@@ -38934,7 +40747,7 @@ exports.default = NodeCache;
 
 }).call(this,require("buffer").Buffer)
 
-},{"../Graph":285,"../Utils":291,"buffer":7,"rxjs/Observable":29,"rxjs/Subject":34,"rxjs/add/observable/combineLatest":38,"rxjs/add/operator/publishReplay":72}],391:[function(require,module,exports){
+},{"../Graph":294,"../Utils":300,"buffer":7,"rxjs/Observable":29,"rxjs/Subject":34}],404:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -39024,7 +40837,7 @@ var Sequence = /** @class */ (function () {
 exports.Sequence = Sequence;
 exports.default = Sequence;
 
-},{"underscore":233}],392:[function(require,module,exports){
+},{"underscore":242}],405:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -39181,8 +40994,7 @@ var EdgeCalculator = /** @class */ (function () {
             if (potentialEdge.sequenceKey == null) {
                 continue;
             }
-            if (potentialEdge.sameSequence ||
-                !potentialEdge.sameMergeCC) {
+            if (potentialEdge.sameSequence) {
                 continue;
             }
             if (nodeFullPano) {
@@ -39627,7 +41439,7 @@ var EdgeCalculator = /** @class */ (function () {
 exports.EdgeCalculator = EdgeCalculator;
 exports.default = EdgeCalculator;
 
-},{"../../Edge":282,"../../Error":283,"../../Geo":284,"three":231}],393:[function(require,module,exports){
+},{"../../Edge":291,"../../Error":292,"../../Geo":293,"three":240}],406:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var EdgeCalculatorCoefficients = /** @class */ (function () {
@@ -39653,7 +41465,7 @@ var EdgeCalculatorCoefficients = /** @class */ (function () {
 exports.EdgeCalculatorCoefficients = EdgeCalculatorCoefficients;
 exports.default = EdgeCalculatorCoefficients;
 
-},{}],394:[function(require,module,exports){
+},{}],407:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Edge_1 = require("../../Edge");
@@ -39726,7 +41538,7 @@ var EdgeCalculatorDirections = /** @class */ (function () {
 }());
 exports.EdgeCalculatorDirections = EdgeCalculatorDirections;
 
-},{"../../Edge":282}],395:[function(require,module,exports){
+},{"../../Edge":291}],408:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var EdgeCalculatorSettings = /** @class */ (function () {
@@ -39763,7 +41575,7 @@ var EdgeCalculatorSettings = /** @class */ (function () {
 exports.EdgeCalculatorSettings = EdgeCalculatorSettings;
 exports.default = EdgeCalculatorSettings;
 
-},{}],396:[function(require,module,exports){
+},{}],409:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 /**
@@ -39821,19 +41633,13 @@ var EdgeDirection;
     EdgeDirection[EdgeDirection["Similar"] = 10] = "Similar";
 })(EdgeDirection = exports.EdgeDirection || (exports.EdgeDirection = {}));
 
-},{}],397:[function(require,module,exports){
+},{}],410:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
 var _ = require("underscore");
 var vd = require("virtual-dom");
 var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/operator/combineLatest");
-require("rxjs/add/operator/distinctUntilChanged");
-require("rxjs/add/operator/filter");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/pluck");
-require("rxjs/add/operator/scan");
 var Render_1 = require("../Render");
 var DOMRenderer = /** @class */ (function () {
     function DOMRenderer(element, renderService, currentFrame$) {
@@ -40009,7 +41815,7 @@ var DOMRenderer = /** @class */ (function () {
 exports.DOMRenderer = DOMRenderer;
 exports.default = DOMRenderer;
 
-},{"../Render":287,"rxjs/Subject":34,"rxjs/add/operator/combineLatest":53,"rxjs/add/operator/distinctUntilChanged":58,"rxjs/add/operator/filter":61,"rxjs/add/operator/map":65,"rxjs/add/operator/pluck":70,"rxjs/add/operator/scan":75,"underscore":233,"virtual-dom":237}],398:[function(require,module,exports){
+},{"../Render":296,"rxjs/Subject":34,"underscore":242,"virtual-dom":246}],411:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var GLRenderStage;
@@ -40019,23 +41825,13 @@ var GLRenderStage;
 })(GLRenderStage = exports.GLRenderStage || (exports.GLRenderStage = {}));
 exports.default = GLRenderStage;
 
-},{}],399:[function(require,module,exports){
+},{}],412:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
 var THREE = require("three");
 var Observable_1 = require("rxjs/Observable");
 var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/observable/combineLatest");
-require("rxjs/add/operator/distinctUntilChanged");
-require("rxjs/add/operator/filter");
-require("rxjs/add/operator/first");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/merge");
-require("rxjs/add/operator/mergeMap");
-require("rxjs/add/operator/scan");
-require("rxjs/add/operator/share");
-require("rxjs/add/operator/startWith");
 var Render_1 = require("../Render");
 var Utils_1 = require("../Utils");
 var GLRenderer = /** @class */ (function () {
@@ -40053,7 +41849,10 @@ var GLRenderer = /** @class */ (function () {
         this._renderer$ = this._rendererOperation$
             .scan(function (renderer, operation) {
             return operation(renderer);
-        }, { needsRender: false, renderer: null });
+        }, { needsRender: false, renderer: null })
+            .filter(function (renderer) {
+            return !!renderer.renderer;
+        });
         this._renderCollection$ = this._renderOperation$
             .scan(function (hashes, operation) {
             return operation(hashes);
@@ -40271,7 +42070,7 @@ var GLRenderer = /** @class */ (function () {
 exports.GLRenderer = GLRenderer;
 exports.default = GLRenderer;
 
-},{"../Render":287,"../Utils":291,"rxjs/Observable":29,"rxjs/Subject":34,"rxjs/add/observable/combineLatest":38,"rxjs/add/operator/distinctUntilChanged":58,"rxjs/add/operator/filter":61,"rxjs/add/operator/first":63,"rxjs/add/operator/map":65,"rxjs/add/operator/merge":66,"rxjs/add/operator/mergeMap":68,"rxjs/add/operator/scan":75,"rxjs/add/operator/share":76,"rxjs/add/operator/startWith":80,"three":231}],400:[function(require,module,exports){
+},{"../Render":296,"../Utils":300,"rxjs/Observable":29,"rxjs/Subject":34,"three":240}],413:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -40397,7 +42196,7 @@ var RenderCamera = /** @class */ (function () {
 exports.RenderCamera = RenderCamera;
 exports.default = RenderCamera;
 
-},{"../Geo":284,"../Render":287,"three":231}],401:[function(require,module,exports){
+},{"../Geo":293,"../Render":296,"three":240}],414:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 /**
@@ -40433,21 +42232,12 @@ var RenderMode;
 })(RenderMode = exports.RenderMode || (exports.RenderMode = {}));
 exports.default = RenderMode;
 
-},{}],402:[function(require,module,exports){
+},{}],415:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
 var Subject_1 = require("rxjs/Subject");
 var BehaviorSubject_1 = require("rxjs/BehaviorSubject");
-require("rxjs/add/observable/combineLatest");
-require("rxjs/add/operator/do");
-require("rxjs/add/operator/filter");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/publishReplay");
-require("rxjs/add/operator/scan");
-require("rxjs/add/operator/skip");
-require("rxjs/add/operator/startWith");
-require("rxjs/add/operator/withLatestFrom");
 var Geo_1 = require("../Geo");
 var Render_1 = require("../Render");
 var RenderService = /** @class */ (function () {
@@ -40609,29 +42399,94 @@ var RenderService = /** @class */ (function () {
 exports.RenderService = RenderService;
 exports.default = RenderService;
 
-},{"../Geo":284,"../Render":287,"rxjs/BehaviorSubject":26,"rxjs/Subject":34,"rxjs/add/observable/combineLatest":38,"rxjs/add/operator/do":59,"rxjs/add/operator/filter":61,"rxjs/add/operator/map":65,"rxjs/add/operator/publishReplay":72,"rxjs/add/operator/scan":75,"rxjs/add/operator/skip":77,"rxjs/add/operator/startWith":80,"rxjs/add/operator/withLatestFrom":87}],403:[function(require,module,exports){
+},{"../Geo":293,"../Render":296,"rxjs/BehaviorSubject":26,"rxjs/Subject":34}],416:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var RotationDelta = /** @class */ (function () {
+    function RotationDelta(phi, theta) {
+        this._phi = phi;
+        this._theta = theta;
+    }
+    Object.defineProperty(RotationDelta.prototype, "phi", {
+        get: function () {
+            return this._phi;
+        },
+        set: function (value) {
+            this._phi = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(RotationDelta.prototype, "theta", {
+        get: function () {
+            return this._theta;
+        },
+        set: function (value) {
+            this._theta = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(RotationDelta.prototype, "isZero", {
+        get: function () {
+            return this._phi === 0 && this._theta === 0;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    RotationDelta.prototype.copy = function (delta) {
+        this._phi = delta.phi;
+        this._theta = delta.theta;
+    };
+    RotationDelta.prototype.lerp = function (other, alpha) {
+        this._phi = (1 - alpha) * this._phi + alpha * other.phi;
+        this._theta = (1 - alpha) * this._theta + alpha * other.theta;
+    };
+    RotationDelta.prototype.multiply = function (value) {
+        this._phi *= value;
+        this._theta *= value;
+    };
+    RotationDelta.prototype.threshold = function (value) {
+        this._phi = Math.abs(this._phi) > value ? this._phi : 0;
+        this._theta = Math.abs(this._theta) > value ? this._theta : 0;
+    };
+    RotationDelta.prototype.lengthSquared = function () {
+        return this._phi * this._phi + this._theta * this._theta;
+    };
+    RotationDelta.prototype.reset = function () {
+        this._phi = 0;
+        this._theta = 0;
+    };
+    return RotationDelta;
+}());
+exports.RotationDelta = RotationDelta;
+exports.default = RotationDelta;
+
+},{}],417:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var State;
 (function (State) {
     State[State["Traversing"] = 0] = "Traversing";
     State[State["Waiting"] = 1] = "Waiting";
+    State[State["WaitingInteractively"] = 2] = "WaitingInteractively";
 })(State = exports.State || (exports.State = {}));
 exports.default = State;
 
-},{}],404:[function(require,module,exports){
+},{}],418:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var State_1 = require("../State");
 var Geo_1 = require("../Geo");
 var StateContext = /** @class */ (function () {
-    function StateContext() {
+    function StateContext(transitionMode) {
         this._state = new State_1.TraversingState({
             alpha: 1,
             camera: new Geo_1.Camera(),
             currentIndex: -1,
             reference: { alt: 0, lat: 0, lon: 0 },
             trajectory: [],
+            transitionMode: transitionMode == null ? State_1.TransitionMode.Default : transitionMode,
             zoom: 0,
         });
     }
@@ -40641,6 +42496,9 @@ var StateContext = /** @class */ (function () {
     StateContext.prototype.wait = function () {
         this._state = this._state.wait();
     };
+    StateContext.prototype.waitInteractively = function () {
+        this._state = this._state.waitInteractively();
+    };
     Object.defineProperty(StateContext.prototype, "state", {
         get: function () {
             if (this._state instanceof State_1.TraversingState) {
@@ -40649,6 +42507,9 @@ var StateContext = /** @class */ (function () {
             else if (this._state instanceof State_1.WaitingState) {
                 return State_1.State.Waiting;
             }
+            else if (this._state instanceof State_1.InteractiveWaitingState) {
+                return State_1.State.WaitingInteractively;
+            }
             throw new Error("Invalid state");
         },
         enumerable: true,
@@ -40812,31 +42673,22 @@ var StateContext = /** @class */ (function () {
     StateContext.prototype.setSpeed = function (speed) {
         this._state.setSpeed(speed);
     };
+    StateContext.prototype.setTransitionMode = function (mode) {
+        this._state.setTransitionMode(mode);
+    };
     return StateContext;
 }());
 exports.StateContext = StateContext;
 
-},{"../Geo":284,"../State":288}],405:[function(require,module,exports){
+},{"../Geo":293,"../State":297}],419:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var BehaviorSubject_1 = require("rxjs/BehaviorSubject");
 var Subject_1 = require("rxjs/Subject");
 var AnimationFrame_1 = require("rxjs/util/AnimationFrame");
-require("rxjs/add/operator/bufferCount");
-require("rxjs/add/operator/distinctUntilChanged");
-require("rxjs/add/operator/do");
-require("rxjs/add/operator/filter");
-require("rxjs/add/operator/first");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/pairwise");
-require("rxjs/add/operator/publishReplay");
-require("rxjs/add/operator/scan");
-require("rxjs/add/operator/startWith");
-require("rxjs/add/operator/switchMap");
-require("rxjs/add/operator/withLatestFrom");
 var State_1 = require("../State");
 var StateService = /** @class */ (function () {
-    function StateService() {
+    function StateService(transitionMode) {
         var _this = this;
         this._appendNode$ = new Subject_1.Subject();
         this._start$ = new Subject_1.Subject();
@@ -40848,7 +42700,7 @@ var StateService = /** @class */ (function () {
         this._context$ = this._contextOperation$
             .scan(function (context, operation) {
             return operation(context);
-        }, new State_1.StateContext())
+        }, new State_1.StateContext(transitionMode))
             .publishReplay(1)
             .refCount();
         this._state$ = this._context$
@@ -41111,6 +42963,9 @@ var StateService = /** @class */ (function () {
     StateService.prototype.wait = function () {
         this._invokeContextOperation(function (context) { context.wait(); });
     };
+    StateService.prototype.waitInteractively = function () {
+        this._invokeContextOperation(function (context) { context.waitInteractively(); });
+    };
     StateService.prototype.appendNodes = function (nodes) {
         this._invokeContextOperation(function (context) { context.append(nodes); });
     };
@@ -41123,117 +42978,622 @@ var StateService = /** @class */ (function () {
     StateService.prototype.clearNodes = function () {
         this._invokeContextOperation(function (context) { context.clear(); });
     };
-    StateService.prototype.clearPriorNodes = function () {
-        this._invokeContextOperation(function (context) { context.clearPrior(); });
+    StateService.prototype.clearPriorNodes = function () {
+        this._invokeContextOperation(function (context) { context.clearPrior(); });
+    };
+    StateService.prototype.cutNodes = function () {
+        this._invokeContextOperation(function (context) { context.cut(); });
+    };
+    StateService.prototype.setNodes = function (nodes) {
+        this._invokeContextOperation(function (context) { context.set(nodes); });
+    };
+    StateService.prototype.rotate = function (delta) {
+        this._inMotionOperation$.next(true);
+        this._invokeContextOperation(function (context) { context.rotate(delta); });
+    };
+    StateService.prototype.rotateBasic = function (basicRotation) {
+        this._inMotionOperation$.next(true);
+        this._invokeContextOperation(function (context) { context.rotateBasic(basicRotation); });
+    };
+    StateService.prototype.rotateBasicUnbounded = function (basicRotation) {
+        this._inMotionOperation$.next(true);
+        this._invokeContextOperation(function (context) { context.rotateBasicUnbounded(basicRotation); });
+    };
+    StateService.prototype.rotateBasicWithoutInertia = function (basicRotation) {
+        this._inMotionOperation$.next(true);
+        this._invokeContextOperation(function (context) { context.rotateBasicWithoutInertia(basicRotation); });
+    };
+    StateService.prototype.rotateToBasic = function (basic) {
+        this._inMotionOperation$.next(true);
+        this._invokeContextOperation(function (context) { context.rotateToBasic(basic); });
+    };
+    StateService.prototype.move = function (delta) {
+        this._inMotionOperation$.next(true);
+        this._invokeContextOperation(function (context) { context.move(delta); });
+    };
+    StateService.prototype.moveTo = function (position) {
+        this._inMotionOperation$.next(true);
+        this._invokeContextOperation(function (context) { context.moveTo(position); });
+    };
+    /**
+     * Change zoom level while keeping the reference point position approximately static.
+     *
+     * @parameter {number} delta - Change in zoom level.
+     * @parameter {Array<number>} reference - Reference point in basic coordinates.
+     */
+    StateService.prototype.zoomIn = function (delta, reference) {
+        this._inMotionOperation$.next(true);
+        this._invokeContextOperation(function (context) { context.zoomIn(delta, reference); });
+    };
+    StateService.prototype.getCenter = function () {
+        return this._lastState$
+            .first()
+            .map(function (frame) {
+            return frame.state.getCenter();
+        });
+    };
+    StateService.prototype.getZoom = function () {
+        return this._lastState$
+            .first()
+            .map(function (frame) {
+            return frame.state.zoom;
+        });
+    };
+    StateService.prototype.setCenter = function (center) {
+        this._inMotionOperation$.next(true);
+        this._invokeContextOperation(function (context) { context.setCenter(center); });
+    };
+    StateService.prototype.setSpeed = function (speed) {
+        this._invokeContextOperation(function (context) { context.setSpeed(speed); });
+    };
+    StateService.prototype.setTransitionMode = function (mode) {
+        this._invokeContextOperation(function (context) { context.setTransitionMode(mode); });
+    };
+    StateService.prototype.setZoom = function (zoom) {
+        this._inMotionOperation$.next(true);
+        this._invokeContextOperation(function (context) { context.setZoom(zoom); });
+    };
+    StateService.prototype.start = function () {
+        if (this._frameId == null) {
+            this._start$.next(null);
+            this._frameId = this._frameGenerator.requestAnimationFrame(this._frame.bind(this));
+            this._frame$.next(this._frameId);
+        }
+    };
+    StateService.prototype.stop = function () {
+        if (this._frameId != null) {
+            this._frameGenerator.cancelAnimationFrame(this._frameId);
+            this._frameId = null;
+        }
+    };
+    StateService.prototype._invokeContextOperation = function (action) {
+        this._contextOperation$
+            .next(function (context) {
+            action(context);
+            return context;
+        });
+    };
+    StateService.prototype._frame = function (time) {
+        this._frameId = this._frameGenerator.requestAnimationFrame(this._frame.bind(this));
+        this._frame$.next(this._frameId);
+    };
+    return StateService;
+}());
+exports.StateService = StateService;
+
+},{"../State":297,"rxjs/BehaviorSubject":26,"rxjs/Subject":34,"rxjs/util/AnimationFrame":217}],420:[function(require,module,exports){
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+/**
+ * Enumeration for transition mode
+ * @enum {number}
+ * @readonly
+ * @description Modes for specifying how transitions
+ * between nodes are performed.
+ */
+var TransitionMode;
+(function (TransitionMode) {
+    /**
+     * Default transitions.
+     *
+     * @description The viewer dynamically determines
+     * whether transitions should be performed with or
+     * without motion and blending for each transition
+     * based on the underlying data.
+     */
+    TransitionMode[TransitionMode["Default"] = 0] = "Default";
+    /**
+     * Instantaneous transitions.
+     *
+     * @description All transitions are performed
+     * without motion or blending.
+     */
+    TransitionMode[TransitionMode["Instantaneous"] = 1] = "Instantaneous";
+})(TransitionMode = exports.TransitionMode || (exports.TransitionMode = {}));
+exports.default = TransitionMode;
+
+},{}],421:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var THREE = require("three");
+var State_1 = require("../../State");
+var InteractiveStateBase = /** @class */ (function (_super) {
+    __extends(InteractiveStateBase, _super);
+    function InteractiveStateBase(state) {
+        var _this = _super.call(this, state) || this;
+        _this._animationSpeed = 1 / 40;
+        _this._rotationDelta = new State_1.RotationDelta(0, 0);
+        _this._requestedRotationDelta = null;
+        _this._basicRotation = [0, 0];
+        _this._requestedBasicRotation = null;
+        _this._requestedBasicRotationUnbounded = null;
+        _this._rotationAcceleration = 0.86;
+        _this._rotationIncreaseAlpha = 0.97;
+        _this._rotationDecreaseAlpha = 0.9;
+        _this._rotationThreshold = 1e-3;
+        _this._unboundedRotationAlpha = 0.8;
+        _this._desiredZoom = state.zoom;
+        _this._minZoom = 0;
+        _this._maxZoom = 3;
+        _this._lookatDepth = 10;
+        _this._desiredLookat = null;
+        _this._desiredCenter = null;
+        return _this;
+    }
+    InteractiveStateBase.prototype.rotate = function (rotationDelta) {
+        if (this._currentNode == null) {
+            return;
+        }
+        this._desiredZoom = this._zoom;
+        this._desiredLookat = null;
+        this._requestedBasicRotation = null;
+        if (this._requestedRotationDelta != null) {
+            this._requestedRotationDelta.phi = this._requestedRotationDelta.phi + rotationDelta.phi;
+            this._requestedRotationDelta.theta = this._requestedRotationDelta.theta + rotationDelta.theta;
+        }
+        else {
+            this._requestedRotationDelta = new State_1.RotationDelta(rotationDelta.phi, rotationDelta.theta);
+        }
+    };
+    InteractiveStateBase.prototype.rotateBasic = function (basicRotation) {
+        if (this._currentNode == null) {
+            return;
+        }
+        this._desiredZoom = this._zoom;
+        this._desiredLookat = null;
+        this._requestedRotationDelta = null;
+        if (this._requestedBasicRotation != null) {
+            this._requestedBasicRotation[0] += basicRotation[0];
+            this._requestedBasicRotation[1] += basicRotation[1];
+            var threshold = 0.05 / Math.pow(2, this._zoom);
+            this._requestedBasicRotation[0] =
+                this._spatial.clamp(this._requestedBasicRotation[0], -threshold, threshold);
+            this._requestedBasicRotation[1] =
+                this._spatial.clamp(this._requestedBasicRotation[1], -threshold, threshold);
+        }
+        else {
+            this._requestedBasicRotation = basicRotation.slice();
+        }
+    };
+    InteractiveStateBase.prototype.rotateBasicUnbounded = function (basicRotation) {
+        if (this._currentNode == null) {
+            return;
+        }
+        if (this._requestedBasicRotationUnbounded != null) {
+            this._requestedBasicRotationUnbounded[0] += basicRotation[0];
+            this._requestedBasicRotationUnbounded[1] += basicRotation[1];
+        }
+        else {
+            this._requestedBasicRotationUnbounded = basicRotation.slice();
+        }
+    };
+    InteractiveStateBase.prototype.rotateBasicWithoutInertia = function (basic) {
+        if (this._currentNode == null) {
+            return;
+        }
+        this._desiredZoom = this._zoom;
+        this._desiredLookat = null;
+        this._requestedRotationDelta = null;
+        this._requestedBasicRotation = null;
+        var threshold = 0.05 / Math.pow(2, this._zoom);
+        var basicRotation = basic.slice();
+        basicRotation[0] = this._spatial.clamp(basicRotation[0], -threshold, threshold);
+        basicRotation[1] = this._spatial.clamp(basicRotation[1], -threshold, threshold);
+        this._applyRotationBasic(basicRotation);
+    };
+    InteractiveStateBase.prototype.rotateToBasic = function (basic) {
+        if (this._currentNode == null) {
+            return;
+        }
+        this._desiredZoom = this._zoom;
+        this._desiredLookat = null;
+        basic[0] = this._spatial.clamp(basic[0], 0, 1);
+        basic[1] = this._spatial.clamp(basic[1], 0, 1);
+        var lookat = this.currentTransform.unprojectBasic(basic, this._lookatDepth);
+        this._currentCamera.lookat.fromArray(lookat);
+    };
+    InteractiveStateBase.prototype.zoomIn = function (delta, reference) {
+        if (this._currentNode == null) {
+            return;
+        }
+        this._desiredZoom = Math.max(this._minZoom, Math.min(this._maxZoom, this._desiredZoom + delta));
+        var currentCenter = this.currentTransform.projectBasic(this._currentCamera.lookat.toArray());
+        var currentCenterX = currentCenter[0];
+        var currentCenterY = currentCenter[1];
+        var zoom0 = Math.pow(2, this._zoom);
+        var zoom1 = Math.pow(2, this._desiredZoom);
+        var refX = reference[0];
+        var refY = reference[1];
+        if (this.currentTransform.gpano != null &&
+            this.currentTransform.gpano.CroppedAreaImageWidthPixels === this.currentTransform.gpano.FullPanoWidthPixels) {
+            if (refX - currentCenterX > 0.5) {
+                refX = refX - 1;
+            }
+            else if (currentCenterX - refX > 0.5) {
+                refX = 1 + refX;
+            }
+        }
+        var newCenterX = refX - zoom0 / zoom1 * (refX - currentCenterX);
+        var newCenterY = refY - zoom0 / zoom1 * (refY - currentCenterY);
+        var gpano = this.currentTransform.gpano;
+        if (this._currentNode.fullPano) {
+            newCenterX = this._spatial.wrap(newCenterX + this._basicRotation[0], 0, 1);
+            newCenterY = this._spatial.clamp(newCenterY + this._basicRotation[1], 0.05, 0.95);
+        }
+        else if (gpano != null &&
+            this.currentTransform.gpano.CroppedAreaImageWidthPixels === this.currentTransform.gpano.FullPanoWidthPixels) {
+            newCenterX = this._spatial.wrap(newCenterX + this._basicRotation[0], 0, 1);
+            newCenterY = this._spatial.clamp(newCenterY + this._basicRotation[1], 0, 1);
+        }
+        else {
+            newCenterX = this._spatial.clamp(newCenterX, 0, 1);
+            newCenterY = this._spatial.clamp(newCenterY, 0, 1);
+        }
+        this._desiredLookat = new THREE.Vector3()
+            .fromArray(this.currentTransform.unprojectBasic([newCenterX, newCenterY], this._lookatDepth));
+    };
+    InteractiveStateBase.prototype.setCenter = function (center) {
+        this._desiredLookat = null;
+        this._requestedRotationDelta = null;
+        this._requestedBasicRotation = null;
+        this._desiredZoom = this._zoom;
+        var clamped = [
+            this._spatial.clamp(center[0], 0, 1),
+            this._spatial.clamp(center[1], 0, 1),
+        ];
+        if (this._currentNode == null) {
+            this._desiredCenter = clamped;
+            return;
+        }
+        this._desiredCenter = null;
+        var currentLookat = new THREE.Vector3()
+            .fromArray(this.currentTransform.unprojectBasic(clamped, this._lookatDepth));
+        var previousTransform = this.previousTransform != null ?
+            this.previousTransform :
+            this.currentTransform;
+        var previousLookat = new THREE.Vector3()
+            .fromArray(previousTransform.unprojectBasic(clamped, this._lookatDepth));
+        this._currentCamera.lookat.copy(currentLookat);
+        this._previousCamera.lookat.copy(previousLookat);
+    };
+    InteractiveStateBase.prototype.setZoom = function (zoom) {
+        this._desiredLookat = null;
+        this._requestedRotationDelta = null;
+        this._requestedBasicRotation = null;
+        this._zoom = this._spatial.clamp(zoom, this._minZoom, this._maxZoom);
+        this._desiredZoom = this._zoom;
+    };
+    InteractiveStateBase.prototype._applyRotation = function (camera) {
+        if (camera == null) {
+            return;
+        }
+        var q = new THREE.Quaternion().setFromUnitVectors(camera.up, new THREE.Vector3(0, 0, 1));
+        var qInverse = q.clone().inverse();
+        var offset = new THREE.Vector3();
+        offset.copy(camera.lookat).sub(camera.position);
+        offset.applyQuaternion(q);
+        var length = offset.length();
+        var phi = Math.atan2(offset.y, offset.x);
+        phi += this._rotationDelta.phi;
+        var theta = Math.atan2(Math.sqrt(offset.x * offset.x + offset.y * offset.y), offset.z);
+        theta += this._rotationDelta.theta;
+        theta = Math.max(0.1, Math.min(Math.PI - 0.1, theta));
+        offset.x = Math.sin(theta) * Math.cos(phi);
+        offset.y = Math.sin(theta) * Math.sin(phi);
+        offset.z = Math.cos(theta);
+        offset.applyQuaternion(qInverse);
+        camera.lookat.copy(camera.position).add(offset.multiplyScalar(length));
+    };
+    InteractiveStateBase.prototype._applyRotationBasic = function (basicRotation) {
+        var currentNode = this._currentNode;
+        var previousNode = this._previousNode != null ?
+            this.previousNode :
+            this.currentNode;
+        var currentCamera = this._currentCamera;
+        var previousCamera = this._previousCamera;
+        var currentTransform = this.currentTransform;
+        var previousTransform = this.previousTransform != null ?
+            this.previousTransform :
+            this.currentTransform;
+        var currentBasic = currentTransform.projectBasic(currentCamera.lookat.toArray());
+        var previousBasic = previousTransform.projectBasic(previousCamera.lookat.toArray());
+        var currentGPano = currentTransform.gpano;
+        var previousGPano = previousTransform.gpano;
+        if (currentNode.fullPano) {
+            currentBasic[0] = this._spatial.wrap(currentBasic[0] + basicRotation[0], 0, 1);
+            currentBasic[1] = this._spatial.clamp(currentBasic[1] + basicRotation[1], 0.05, 0.95);
+        }
+        else if (currentGPano != null &&
+            currentTransform.gpano.CroppedAreaImageWidthPixels === currentTransform.gpano.FullPanoWidthPixels) {
+            currentBasic[0] = this._spatial.wrap(currentBasic[0] + basicRotation[0], 0, 1);
+            currentBasic[1] = this._spatial.clamp(currentBasic[1] + basicRotation[1], 0, 1);
+        }
+        else {
+            currentBasic[0] = this._spatial.clamp(currentBasic[0] + basicRotation[0], 0, 1);
+            currentBasic[1] = this._spatial.clamp(currentBasic[1] + basicRotation[1], 0, 1);
+        }
+        if (previousNode.fullPano) {
+            previousBasic[0] = this._spatial.wrap(previousBasic[0] + basicRotation[0], 0, 1);
+            previousBasic[1] = this._spatial.clamp(previousBasic[1] + basicRotation[1], 0.05, 0.95);
+        }
+        else if (previousGPano != null &&
+            previousTransform.gpano.CroppedAreaImageWidthPixels === previousTransform.gpano.FullPanoWidthPixels) {
+            previousBasic[0] = this._spatial.wrap(previousBasic[0] + basicRotation[0], 0, 1);
+            previousBasic[1] = this._spatial.clamp(previousBasic[1] + basicRotation[1], 0, 1);
+        }
+        else {
+            previousBasic[0] = this._spatial.clamp(previousBasic[0] + basicRotation[0], 0, 1);
+            previousBasic[1] = this._spatial.clamp(currentBasic[1] + basicRotation[1], 0, 1);
+        }
+        var currentLookat = currentTransform.unprojectBasic(currentBasic, this._lookatDepth);
+        currentCamera.lookat.fromArray(currentLookat);
+        var previousLookat = previousTransform.unprojectBasic(previousBasic, this._lookatDepth);
+        previousCamera.lookat.fromArray(previousLookat);
     };
-    StateService.prototype.cutNodes = function () {
-        this._invokeContextOperation(function (context) { context.cut(); });
+    InteractiveStateBase.prototype._updateZoom = function (animationSpeed) {
+        var diff = this._desiredZoom - this._zoom;
+        var sign = diff > 0 ? 1 : diff < 0 ? -1 : 0;
+        if (diff === 0) {
+            return;
+        }
+        else if (Math.abs(diff) < 2e-3) {
+            this._zoom = this._desiredZoom;
+            if (this._desiredLookat != null) {
+                this._desiredLookat = null;
+            }
+        }
+        else {
+            this._zoom += sign * Math.max(Math.abs(5 * animationSpeed * diff), 2e-3);
+        }
     };
-    StateService.prototype.setNodes = function (nodes) {
-        this._invokeContextOperation(function (context) { context.set(nodes); });
+    InteractiveStateBase.prototype._updateLookat = function (animationSpeed) {
+        if (this._desiredLookat === null) {
+            return;
+        }
+        var diff = this._desiredLookat.distanceToSquared(this._currentCamera.lookat);
+        if (Math.abs(diff) < 1e-6) {
+            this._currentCamera.lookat.copy(this._desiredLookat);
+            this._desiredLookat = null;
+        }
+        else {
+            this._currentCamera.lookat.lerp(this._desiredLookat, 5 * animationSpeed);
+        }
     };
-    StateService.prototype.rotate = function (delta) {
-        this._inMotionOperation$.next(true);
-        this._invokeContextOperation(function (context) { context.rotate(delta); });
+    InteractiveStateBase.prototype._updateRotation = function () {
+        if (this._requestedRotationDelta != null) {
+            var length_1 = this._rotationDelta.lengthSquared();
+            var requestedLength = this._requestedRotationDelta.lengthSquared();
+            if (requestedLength > length_1) {
+                this._rotationDelta.lerp(this._requestedRotationDelta, this._rotationIncreaseAlpha);
+            }
+            else {
+                this._rotationDelta.lerp(this._requestedRotationDelta, this._rotationDecreaseAlpha);
+            }
+            this._requestedRotationDelta = null;
+            return;
+        }
+        if (this._rotationDelta.isZero) {
+            return;
+        }
+        this._rotationDelta.multiply(this._rotationAcceleration);
+        this._rotationDelta.threshold(this._rotationThreshold);
     };
-    StateService.prototype.rotateBasic = function (basicRotation) {
-        this._inMotionOperation$.next(true);
-        this._invokeContextOperation(function (context) { context.rotateBasic(basicRotation); });
+    InteractiveStateBase.prototype._updateRotationBasic = function () {
+        if (this._requestedBasicRotation != null) {
+            var x = this._basicRotation[0];
+            var y = this._basicRotation[1];
+            var reqX = this._requestedBasicRotation[0];
+            var reqY = this._requestedBasicRotation[1];
+            if (Math.abs(reqX) > Math.abs(x)) {
+                this._basicRotation[0] = (1 - this._rotationIncreaseAlpha) * x + this._rotationIncreaseAlpha * reqX;
+            }
+            else {
+                this._basicRotation[0] = (1 - this._rotationDecreaseAlpha) * x + this._rotationDecreaseAlpha * reqX;
+            }
+            if (Math.abs(reqY) > Math.abs(y)) {
+                this._basicRotation[1] = (1 - this._rotationIncreaseAlpha) * y + this._rotationIncreaseAlpha * reqY;
+            }
+            else {
+                this._basicRotation[1] = (1 - this._rotationDecreaseAlpha) * y + this._rotationDecreaseAlpha * reqY;
+            }
+            this._requestedBasicRotation = null;
+            return;
+        }
+        if (this._requestedBasicRotationUnbounded != null) {
+            var reqX = this._requestedBasicRotationUnbounded[0];
+            var reqY = this._requestedBasicRotationUnbounded[1];
+            if (Math.abs(reqX) > 0) {
+                this._basicRotation[0] = (1 - this._unboundedRotationAlpha) * this._basicRotation[0] + this._unboundedRotationAlpha * reqX;
+            }
+            if (Math.abs(reqY) > 0) {
+                this._basicRotation[1] = (1 - this._unboundedRotationAlpha) * this._basicRotation[1] + this._unboundedRotationAlpha * reqY;
+            }
+            if (this._desiredLookat != null) {
+                var desiredBasicLookat = this.currentTransform.projectBasic(this._desiredLookat.toArray());
+                desiredBasicLookat[0] += reqX;
+                desiredBasicLookat[1] += reqY;
+                this._desiredLookat = new THREE.Vector3()
+                    .fromArray(this.currentTransform.unprojectBasic(desiredBasicLookat, this._lookatDepth));
+            }
+            this._requestedBasicRotationUnbounded = null;
+        }
+        if (this._basicRotation[0] === 0 && this._basicRotation[1] === 0) {
+            return;
+        }
+        this._basicRotation[0] = this._rotationAcceleration * this._basicRotation[0];
+        this._basicRotation[1] = this._rotationAcceleration * this._basicRotation[1];
+        if (Math.abs(this._basicRotation[0]) < this._rotationThreshold / Math.pow(2, this._zoom) &&
+            Math.abs(this._basicRotation[1]) < this._rotationThreshold / Math.pow(2, this._zoom)) {
+            this._basicRotation = [0, 0];
+        }
     };
-    StateService.prototype.rotateBasicUnbounded = function (basicRotation) {
-        this._inMotionOperation$.next(true);
-        this._invokeContextOperation(function (context) { context.rotateBasicUnbounded(basicRotation); });
+    InteractiveStateBase.prototype._clearRotation = function () {
+        if (this._currentNode.fullPano) {
+            return;
+        }
+        if (this._requestedRotationDelta != null) {
+            this._requestedRotationDelta = null;
+        }
+        if (!this._rotationDelta.isZero) {
+            this._rotationDelta.reset();
+        }
+        if (this._requestedBasicRotation != null) {
+            this._requestedBasicRotation = null;
+        }
+        if (this._basicRotation[0] > 0 || this._basicRotation[1] > 0) {
+            this._basicRotation = [0, 0];
+        }
     };
-    StateService.prototype.rotateBasicWithoutInertia = function (basicRotation) {
-        this._inMotionOperation$.next(true);
-        this._invokeContextOperation(function (context) { context.rotateBasicWithoutInertia(basicRotation); });
+    InteractiveStateBase.prototype._setDesiredCenter = function () {
+        if (this._desiredCenter == null) {
+            return;
+        }
+        var lookatDirection = new THREE.Vector3()
+            .fromArray(this.currentTransform.unprojectBasic(this._desiredCenter, this._lookatDepth))
+            .sub(this._currentCamera.position);
+        this._currentCamera.lookat.copy(this._currentCamera.position.clone().add(lookatDirection));
+        this._previousCamera.lookat.copy(this._previousCamera.position.clone().add(lookatDirection));
+        this._desiredCenter = null;
     };
-    StateService.prototype.rotateToBasic = function (basic) {
-        this._inMotionOperation$.next(true);
-        this._invokeContextOperation(function (context) { context.rotateToBasic(basic); });
+    InteractiveStateBase.prototype._setDesiredZoom = function () {
+        this._desiredZoom =
+            this._currentNode.fullPano || this._previousNode == null ?
+                this._zoom : 0;
     };
-    StateService.prototype.move = function (delta) {
-        this._inMotionOperation$.next(true);
-        this._invokeContextOperation(function (context) { context.move(delta); });
+    return InteractiveStateBase;
+}(State_1.StateBase));
+exports.InteractiveStateBase = InteractiveStateBase;
+exports.default = InteractiveStateBase;
+
+},{"../../State":297,"three":240}],422:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
     };
-    StateService.prototype.moveTo = function (position) {
-        this._inMotionOperation$.next(true);
-        this._invokeContextOperation(function (context) { context.moveTo(position); });
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+var State_1 = require("../../State");
+var InteractiveWaitingState = /** @class */ (function (_super) {
+    __extends(InteractiveWaitingState, _super);
+    function InteractiveWaitingState(state) {
+        var _this = _super.call(this, state) || this;
+        _this._adjustCameras();
+        _this._motionless = _this._motionlessTransition();
+        return _this;
+    }
+    InteractiveWaitingState.prototype.traverse = function () {
+        return new State_1.TraversingState(this);
     };
-    /**
-     * Change zoom level while keeping the reference point position approximately static.
-     *
-     * @parameter {number} delta - Change in zoom level.
-     * @parameter {Array<number>} reference - Reference point in basic coordinates.
-     */
-    StateService.prototype.zoomIn = function (delta, reference) {
-        this._inMotionOperation$.next(true);
-        this._invokeContextOperation(function (context) { context.zoomIn(delta, reference); });
+    InteractiveWaitingState.prototype.wait = function () {
+        return new State_1.WaitingState(this);
     };
-    StateService.prototype.getCenter = function () {
-        return this._lastState$
-            .first()
-            .map(function (frame) {
-            return frame.state.getCenter();
-        });
+    InteractiveWaitingState.prototype.waitInteractively = function () {
+        throw new Error("Not implemented");
     };
-    StateService.prototype.getZoom = function () {
-        return this._lastState$
-            .first()
-            .map(function (frame) {
-            return frame.state.zoom;
-        });
+    InteractiveWaitingState.prototype.prepend = function (nodes) {
+        _super.prototype.prepend.call(this, nodes);
+        this._motionless = this._motionlessTransition();
     };
-    StateService.prototype.setCenter = function (center) {
-        this._inMotionOperation$.next(true);
-        this._invokeContextOperation(function (context) { context.setCenter(center); });
+    InteractiveWaitingState.prototype.set = function (nodes) {
+        _super.prototype.set.call(this, nodes);
+        this._motionless = this._motionlessTransition();
     };
-    StateService.prototype.setSpeed = function (speed) {
-        this._invokeContextOperation(function (context) { context.setSpeed(speed); });
+    InteractiveWaitingState.prototype.setSpeed = function (speed) { return; };
+    InteractiveWaitingState.prototype.move = function (delta) {
+        this._alpha = Math.max(0, Math.min(1, this._alpha + delta));
     };
-    StateService.prototype.setZoom = function (zoom) {
-        this._inMotionOperation$.next(true);
-        this._invokeContextOperation(function (context) { context.setZoom(zoom); });
+    InteractiveWaitingState.prototype.moveTo = function (position) {
+        this._alpha = Math.max(0, Math.min(1, position));
     };
-    StateService.prototype.start = function () {
-        if (this._frameId == null) {
-            this._start$.next(null);
-            this._frameId = this._frameGenerator.requestAnimationFrame(this._frame.bind(this));
-            this._frame$.next(this._frameId);
+    InteractiveWaitingState.prototype.update = function (fps) {
+        this._updateRotation();
+        if (!this._rotationDelta.isZero) {
+            this._applyRotation(this._previousCamera);
+            this._applyRotation(this._currentCamera);
         }
-    };
-    StateService.prototype.stop = function () {
-        if (this._frameId != null) {
-            this._frameGenerator.cancelAnimationFrame(this._frameId);
-            this._frameId = null;
+        this._updateRotationBasic();
+        if (this._basicRotation[0] !== 0 || this._basicRotation[1] !== 0) {
+            this._applyRotationBasic(this._basicRotation);
         }
+        var animationSpeed = this._animationSpeed * (60 / fps);
+        this._updateZoom(animationSpeed);
+        this._updateLookat(animationSpeed);
+        this._camera.lerpCameras(this._previousCamera, this._currentCamera, this.alpha);
     };
-    StateService.prototype._invokeContextOperation = function (action) {
-        this._contextOperation$
-            .next(function (context) {
-            action(context);
-            return context;
-        });
+    InteractiveWaitingState.prototype._getAlpha = function () {
+        return this._motionless ? Math.round(this._alpha) : this._alpha;
     };
-    StateService.prototype._frame = function (time) {
-        this._frameId = this._frameGenerator.requestAnimationFrame(this._frame.bind(this));
-        this._frame$.next(this._frameId);
+    InteractiveWaitingState.prototype._setCurrentCamera = function () {
+        _super.prototype._setCurrentCamera.call(this);
+        this._adjustCameras();
     };
-    return StateService;
-}());
-exports.StateService = StateService;
+    InteractiveWaitingState.prototype._adjustCameras = function () {
+        if (this._previousNode == null) {
+            return;
+        }
+        if (this._currentNode.fullPano) {
+            var lookat = this._camera.lookat.clone().sub(this._camera.position);
+            this._currentCamera.lookat.copy(lookat.clone().add(this._currentCamera.position));
+        }
+        if (this._previousNode.fullPano) {
+            var lookat = this._currentCamera.lookat.clone().sub(this._currentCamera.position);
+            this._previousCamera.lookat.copy(lookat.clone().add(this._previousCamera.position));
+        }
+    };
+    return InteractiveWaitingState;
+}(State_1.InteractiveStateBase));
+exports.InteractiveWaitingState = InteractiveWaitingState;
+exports.default = InteractiveWaitingState;
 
-},{"../State":288,"rxjs/BehaviorSubject":26,"rxjs/Subject":34,"rxjs/add/operator/bufferCount":50,"rxjs/add/operator/distinctUntilChanged":58,"rxjs/add/operator/do":59,"rxjs/add/operator/filter":61,"rxjs/add/operator/first":63,"rxjs/add/operator/map":65,"rxjs/add/operator/pairwise":69,"rxjs/add/operator/publishReplay":72,"rxjs/add/operator/scan":75,"rxjs/add/operator/startWith":80,"rxjs/add/operator/switchMap":81,"rxjs/add/operator/withLatestFrom":87,"rxjs/util/AnimationFrame":208}],406:[function(require,module,exports){
+},{"../../State":297}],423:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
 var Error_1 = require("../../Error");
 var Geo_1 = require("../../Geo");
+var State_1 = require("../../State");
 var StateBase = /** @class */ (function () {
     function StateBase(state) {
         this._spatial = new Geo_1.Spatial();
         this._geoCoords = new Geo_1.GeoCoords();
         this._referenceThreshold = 0.01;
+        this._transitionMode = state.transitionMode;
         this._reference = state.reference;
         this._alpha = state.alpha;
         this._camera = state.camera.clone();
@@ -41245,7 +43605,7 @@ var StateBase = /** @class */ (function () {
         for (var _i = 0, _a = this._trajectory; _i < _a.length; _i++) {
             var node = _a[_i];
             var translation = this._nodeToTranslation(node);
-            var transform = new Geo_1.Transform(node, node.image, translation);
+            var transform = new Geo_1.Transform(node.orientation, node.width, node.height, node.focal, node.scale, node.gpano, node.rotation, translation, node.image);
             this._trajectoryTransforms.push(transform);
             this._trajectoryCameras.push(new Geo_1.Camera(transform));
         }
@@ -41348,6 +43708,13 @@ var StateBase = /** @class */ (function () {
         enumerable: true,
         configurable: true
     });
+    Object.defineProperty(StateBase.prototype, "transitionMode", {
+        get: function () {
+            return this._transitionMode;
+        },
+        enumerable: true,
+        configurable: true
+    });
     StateBase.prototype.append = function (nodes) {
         if (nodes.length < 1) {
             throw Error("Trajectory can not be empty");
@@ -41421,6 +43788,9 @@ var StateBase = /** @class */ (function () {
             this.currentTransform.projectBasic(this._camera.lookat.toArray()) :
             [0.5, 0.5];
     };
+    StateBase.prototype.setTransitionMode = function (mode) {
+        this._transitionMode = mode;
+    };
     StateBase.prototype._setCurrent = function () {
         this._setCurrentNode();
         var referenceReset = this._setReference(this._currentNode);
@@ -41437,10 +43807,10 @@ var StateBase = /** @class */ (function () {
     };
     StateBase.prototype._motionlessTransition = function () {
         var nodesSet = this._currentNode != null && this._previousNode != null;
-        return nodesSet && !(this._currentNode.merged &&
+        return nodesSet && (this._transitionMode === State_1.TransitionMode.Instantaneous || !(this._currentNode.merged &&
             this._previousNode.merged &&
             this._withinOriginalDistance() &&
-            this._sameConnectedComponent());
+            this._sameConnectedComponent()));
     };
     StateBase.prototype._setReference = function (node) {
         // do not reset reference if node is within threshold distance
@@ -41490,7 +43860,7 @@ var StateBase = /** @class */ (function () {
                 throw new Error_1.ArgumentMapillaryError("Assets must be cached when node is added to trajectory");
             }
             var translation = this._nodeToTranslation(node);
-            var transform = new Geo_1.Transform(node, node.image, translation);
+            var transform = new Geo_1.Transform(node.orientation, node.width, node.height, node.focal, node.scale, node.gpano, node.rotation, translation, node.image);
             this._trajectoryTransforms.push(transform);
             this._trajectoryCameras.push(new Geo_1.Camera(transform));
         }
@@ -41502,7 +43872,7 @@ var StateBase = /** @class */ (function () {
                 throw new Error_1.ArgumentMapillaryError("Assets must be cached when added to trajectory");
             }
             var translation = this._nodeToTranslation(node);
-            var transform = new Geo_1.Transform(node, node.image, translation);
+            var transform = new Geo_1.Transform(node.orientation, node.width, node.height, node.focal, node.scale, node.gpano, node.rotation, translation, node.image);
             this._trajectoryTransforms.unshift(transform);
             this._trajectoryCameras.unshift(new Geo_1.Camera(transform));
         }
@@ -41515,13 +43885,8 @@ var StateBase = /** @class */ (function () {
     StateBase.prototype._sameConnectedComponent = function () {
         var current = this._currentNode;
         var previous = this._previousNode;
-        if (!current ||
-            !current.mergeCC ||
-            !previous ||
-            !previous.mergeCC) {
-            return true;
-        }
-        return current.mergeCC === previous.mergeCC;
+        return !!current && !!previous &&
+            current.mergeCC === previous.mergeCC;
     };
     StateBase.prototype._withinOriginalDistance = function () {
         var current = this._currentNode;
@@ -41537,7 +43902,7 @@ var StateBase = /** @class */ (function () {
 }());
 exports.StateBase = StateBase;
 
-},{"../../Error":283,"../../Geo":284}],407:[function(require,module,exports){
+},{"../../Error":292,"../../Geo":293,"../../State":297}],424:[function(require,module,exports){
 "use strict";
 /// <reference path="../../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -41551,66 +43916,8 @@ var __extends = (this && this.__extends) || (function () {
     };
 })();
 Object.defineProperty(exports, "__esModule", { value: true });
-var THREE = require("three");
 var UnitBezier = require("@mapbox/unitbezier");
 var State_1 = require("../../State");
-var RotationDelta = /** @class */ (function () {
-    function RotationDelta(phi, theta) {
-        this._phi = phi;
-        this._theta = theta;
-    }
-    Object.defineProperty(RotationDelta.prototype, "phi", {
-        get: function () {
-            return this._phi;
-        },
-        set: function (value) {
-            this._phi = value;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    Object.defineProperty(RotationDelta.prototype, "theta", {
-        get: function () {
-            return this._theta;
-        },
-        set: function (value) {
-            this._theta = value;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    Object.defineProperty(RotationDelta.prototype, "isZero", {
-        get: function () {
-            return this._phi === 0 && this._theta === 0;
-        },
-        enumerable: true,
-        configurable: true
-    });
-    RotationDelta.prototype.copy = function (delta) {
-        this._phi = delta.phi;
-        this._theta = delta.theta;
-    };
-    RotationDelta.prototype.lerp = function (other, alpha) {
-        this._phi = (1 - alpha) * this._phi + alpha * other.phi;
-        this._theta = (1 - alpha) * this._theta + alpha * other.theta;
-    };
-    RotationDelta.prototype.multiply = function (value) {
-        this._phi *= value;
-        this._theta *= value;
-    };
-    RotationDelta.prototype.threshold = function (value) {
-        this._phi = Math.abs(this._phi) > value ? this._phi : 0;
-        this._theta = Math.abs(this._theta) > value ? this._theta : 0;
-    };
-    RotationDelta.prototype.lengthSquared = function () {
-        return this._phi * this._phi + this._theta * this._theta;
-    };
-    RotationDelta.prototype.reset = function () {
-        this._phi = 0;
-        this._theta = 0;
-    };
-    return RotationDelta;
-}());
 var TraversingState = /** @class */ (function (_super) {
     __extends(TraversingState, _super);
     function TraversingState(state) {
@@ -41618,26 +43925,9 @@ var TraversingState = /** @class */ (function (_super) {
         _this._adjustCameras();
         _this._motionless = _this._motionlessTransition();
         _this._baseAlpha = _this._alpha;
-        _this._animationSpeed = 1 / 40;
         _this._speedCoefficient = 1;
         _this._unitBezier = new UnitBezier(0.74, 0.67, 0.38, 0.96);
         _this._useBezier = false;
-        _this._rotationDelta = new RotationDelta(0, 0);
-        _this._requestedRotationDelta = null;
-        _this._basicRotation = [0, 0];
-        _this._requestedBasicRotation = null;
-        _this._requestedBasicRotationUnbounded = null;
-        _this._rotationAcceleration = 0.86;
-        _this._rotationIncreaseAlpha = 0.97;
-        _this._rotationDecreaseAlpha = 0.9;
-        _this._rotationThreshold = 1e-3;
-        _this._unboundedRotationAlpha = 0.8;
-        _this._desiredZoom = state.zoom;
-        _this._minZoom = 0;
-        _this._maxZoom = 3;
-        _this._lookatDepth = 10;
-        _this._desiredLookat = null;
-        _this._desiredCenter = null;
         return _this;
     }
     TraversingState.prototype.traverse = function () {
@@ -41646,6 +43936,9 @@ var TraversingState = /** @class */ (function (_super) {
     TraversingState.prototype.wait = function () {
         return new State_1.WaitingState(this);
     };
+    TraversingState.prototype.waitInteractively = function () {
+        return new State_1.InteractiveWaitingState(this);
+    };
     TraversingState.prototype.append = function (nodes) {
         var emptyTrajectory = this._trajectory.length === 0;
         if (emptyTrajectory) {
@@ -41685,152 +43978,9 @@ var TraversingState = /** @class */ (function (_super) {
     TraversingState.prototype.moveTo = function (delta) {
         throw new Error("Not implemented");
     };
-    TraversingState.prototype.rotate = function (rotationDelta) {
-        if (this._currentNode == null) {
-            return;
-        }
-        this._desiredZoom = this._zoom;
-        this._desiredLookat = null;
-        this._requestedBasicRotation = null;
-        if (this._requestedRotationDelta != null) {
-            this._requestedRotationDelta.phi = this._requestedRotationDelta.phi + rotationDelta.phi;
-            this._requestedRotationDelta.theta = this._requestedRotationDelta.theta + rotationDelta.theta;
-        }
-        else {
-            this._requestedRotationDelta = new RotationDelta(rotationDelta.phi, rotationDelta.theta);
-        }
-    };
-    TraversingState.prototype.rotateBasic = function (basicRotation) {
-        if (this._currentNode == null) {
-            return;
-        }
-        this._desiredZoom = this._zoom;
-        this._desiredLookat = null;
-        this._requestedRotationDelta = null;
-        if (this._requestedBasicRotation != null) {
-            this._requestedBasicRotation[0] += basicRotation[0];
-            this._requestedBasicRotation[1] += basicRotation[1];
-            var threshold = 0.05 / Math.pow(2, this._zoom);
-            this._requestedBasicRotation[0] =
-                this._spatial.clamp(this._requestedBasicRotation[0], -threshold, threshold);
-            this._requestedBasicRotation[1] =
-                this._spatial.clamp(this._requestedBasicRotation[1], -threshold, threshold);
-        }
-        else {
-            this._requestedBasicRotation = basicRotation.slice();
-        }
-    };
-    TraversingState.prototype.rotateBasicUnbounded = function (basicRotation) {
-        if (this._currentNode == null) {
-            return;
-        }
-        if (this._requestedBasicRotationUnbounded != null) {
-            this._requestedBasicRotationUnbounded[0] += basicRotation[0];
-            this._requestedBasicRotationUnbounded[1] += basicRotation[1];
-        }
-        else {
-            this._requestedBasicRotationUnbounded = basicRotation.slice();
-        }
-    };
-    TraversingState.prototype.rotateBasicWithoutInertia = function (basic) {
-        if (this._currentNode == null) {
-            return;
-        }
-        this._desiredZoom = this._zoom;
-        this._desiredLookat = null;
-        this._requestedRotationDelta = null;
-        this._requestedBasicRotation = null;
-        var threshold = 0.05 / Math.pow(2, this._zoom);
-        var basicRotation = basic.slice();
-        basicRotation[0] = this._spatial.clamp(basicRotation[0], -threshold, threshold);
-        basicRotation[1] = this._spatial.clamp(basicRotation[1], -threshold, threshold);
-        this._applyRotationBasic(basicRotation);
-    };
-    TraversingState.prototype.rotateToBasic = function (basic) {
-        if (this._currentNode == null) {
-            return;
-        }
-        this._desiredZoom = this._zoom;
-        this._desiredLookat = null;
-        basic[0] = this._spatial.clamp(basic[0], 0, 1);
-        basic[1] = this._spatial.clamp(basic[1], 0, 1);
-        var lookat = this.currentTransform.unprojectBasic(basic, this._lookatDepth);
-        this._currentCamera.lookat.fromArray(lookat);
-    };
     TraversingState.prototype.setSpeed = function (speed) {
         this._speedCoefficient = this._spatial.clamp(speed, 0, 10);
     };
-    TraversingState.prototype.zoomIn = function (delta, reference) {
-        if (this._currentNode == null) {
-            return;
-        }
-        this._desiredZoom = Math.max(this._minZoom, Math.min(this._maxZoom, this._desiredZoom + delta));
-        var currentCenter = this.currentTransform.projectBasic(this._currentCamera.lookat.toArray());
-        var currentCenterX = currentCenter[0];
-        var currentCenterY = currentCenter[1];
-        var zoom0 = Math.pow(2, this._zoom);
-        var zoom1 = Math.pow(2, this._desiredZoom);
-        var refX = reference[0];
-        var refY = reference[1];
-        if (this.currentTransform.gpano != null &&
-            this.currentTransform.gpano.CroppedAreaImageWidthPixels === this.currentTransform.gpano.FullPanoWidthPixels) {
-            if (refX - currentCenterX > 0.5) {
-                refX = refX - 1;
-            }
-            else if (currentCenterX - refX > 0.5) {
-                refX = 1 + refX;
-            }
-        }
-        var newCenterX = refX - zoom0 / zoom1 * (refX - currentCenterX);
-        var newCenterY = refY - zoom0 / zoom1 * (refY - currentCenterY);
-        var gpano = this.currentTransform.gpano;
-        if (this._currentNode.fullPano) {
-            newCenterX = this._spatial.wrap(newCenterX + this._basicRotation[0], 0, 1);
-            newCenterY = this._spatial.clamp(newCenterY + this._basicRotation[1], 0.05, 0.95);
-        }
-        else if (gpano != null &&
-            this.currentTransform.gpano.CroppedAreaImageWidthPixels === this.currentTransform.gpano.FullPanoWidthPixels) {
-            newCenterX = this._spatial.wrap(newCenterX + this._basicRotation[0], 0, 1);
-            newCenterY = this._spatial.clamp(newCenterY + this._basicRotation[1], 0, 1);
-        }
-        else {
-            newCenterX = this._spatial.clamp(newCenterX, 0, 1);
-            newCenterY = this._spatial.clamp(newCenterY, 0, 1);
-        }
-        this._desiredLookat = new THREE.Vector3()
-            .fromArray(this.currentTransform.unprojectBasic([newCenterX, newCenterY], this._lookatDepth));
-    };
-    TraversingState.prototype.setCenter = function (center) {
-        this._desiredLookat = null;
-        this._requestedRotationDelta = null;
-        this._requestedBasicRotation = null;
-        this._desiredZoom = this._zoom;
-        var clamped = [
-            this._spatial.clamp(center[0], 0, 1),
-            this._spatial.clamp(center[1], 0, 1),
-        ];
-        if (this._currentNode == null) {
-            this._desiredCenter = clamped;
-            return;
-        }
-        this._desiredCenter = null;
-        var currentLookat = new THREE.Vector3()
-            .fromArray(this.currentTransform.unprojectBasic(clamped, this._lookatDepth));
-        var previousTransform = this.previousTransform != null ?
-            this.previousTransform :
-            this.currentTransform;
-        var previousLookat = new THREE.Vector3()
-            .fromArray(previousTransform.unprojectBasic(clamped, this._lookatDepth));
-        this._currentCamera.lookat.copy(currentLookat);
-        this._previousCamera.lookat.copy(previousLookat);
-    };
-    TraversingState.prototype.setZoom = function (zoom) {
-        this._desiredLookat = null;
-        this._requestedRotationDelta = null;
-        this._requestedBasicRotation = null;
-        this._zoom = this._spatial.clamp(zoom, this._minZoom, this._maxZoom);
-        this._desiredZoom = this._zoom;
-    };
     TraversingState.prototype.update = function (fps) {
         if (this._alpha === 1 && this._currentIndex + this._alpha < this._trajectory.length) {
             this._currentIndex += 1;
@@ -41885,208 +44035,12 @@ var TraversingState = /** @class */ (function (_super) {
         this._baseAlpha = 0;
         this._motionless = this._motionlessTransition();
     };
-    TraversingState.prototype._applyRotation = function (camera) {
-        if (camera == null) {
-            return;
-        }
-        var q = new THREE.Quaternion().setFromUnitVectors(camera.up, new THREE.Vector3(0, 0, 1));
-        var qInverse = q.clone().inverse();
-        var offset = new THREE.Vector3();
-        offset.copy(camera.lookat).sub(camera.position);
-        offset.applyQuaternion(q);
-        var length = offset.length();
-        var phi = Math.atan2(offset.y, offset.x);
-        phi += this._rotationDelta.phi;
-        var theta = Math.atan2(Math.sqrt(offset.x * offset.x + offset.y * offset.y), offset.z);
-        theta += this._rotationDelta.theta;
-        theta = Math.max(0.1, Math.min(Math.PI - 0.1, theta));
-        offset.x = Math.sin(theta) * Math.cos(phi);
-        offset.y = Math.sin(theta) * Math.sin(phi);
-        offset.z = Math.cos(theta);
-        offset.applyQuaternion(qInverse);
-        camera.lookat.copy(camera.position).add(offset.multiplyScalar(length));
-    };
-    TraversingState.prototype._applyRotationBasic = function (basicRotation) {
-        var currentNode = this._currentNode;
-        var previousNode = this._previousNode != null ?
-            this.previousNode :
-            this.currentNode;
-        var currentCamera = this._currentCamera;
-        var previousCamera = this._previousCamera;
-        var currentTransform = this.currentTransform;
-        var previousTransform = this.previousTransform != null ?
-            this.previousTransform :
-            this.currentTransform;
-        var currentBasic = currentTransform.projectBasic(currentCamera.lookat.toArray());
-        var previousBasic = previousTransform.projectBasic(previousCamera.lookat.toArray());
-        var currentGPano = currentTransform.gpano;
-        var previousGPano = previousTransform.gpano;
-        if (currentNode.fullPano) {
-            currentBasic[0] = this._spatial.wrap(currentBasic[0] + basicRotation[0], 0, 1);
-            currentBasic[1] = this._spatial.clamp(currentBasic[1] + basicRotation[1], 0.05, 0.95);
-        }
-        else if (currentGPano != null &&
-            currentTransform.gpano.CroppedAreaImageWidthPixels === currentTransform.gpano.FullPanoWidthPixels) {
-            currentBasic[0] = this._spatial.wrap(currentBasic[0] + basicRotation[0], 0, 1);
-            currentBasic[1] = this._spatial.clamp(currentBasic[1] + basicRotation[1], 0, 1);
-        }
-        else {
-            currentBasic[0] = this._spatial.clamp(currentBasic[0] + basicRotation[0], 0, 1);
-            currentBasic[1] = this._spatial.clamp(currentBasic[1] + basicRotation[1], 0, 1);
-        }
-        if (previousNode.fullPano) {
-            previousBasic[0] = this._spatial.wrap(previousBasic[0] + basicRotation[0], 0, 1);
-            previousBasic[1] = this._spatial.clamp(previousBasic[1] + basicRotation[1], 0.05, 0.95);
-        }
-        else if (previousGPano != null &&
-            previousTransform.gpano.CroppedAreaImageWidthPixels === previousTransform.gpano.FullPanoWidthPixels) {
-            previousBasic[0] = this._spatial.wrap(previousBasic[0] + basicRotation[0], 0, 1);
-            previousBasic[1] = this._spatial.clamp(previousBasic[1] + basicRotation[1], 0, 1);
-        }
-        else {
-            previousBasic[0] = this._spatial.clamp(previousBasic[0] + basicRotation[0], 0, 1);
-            previousBasic[1] = this._spatial.clamp(currentBasic[1] + basicRotation[1], 0, 1);
-        }
-        var currentLookat = currentTransform.unprojectBasic(currentBasic, this._lookatDepth);
-        currentCamera.lookat.fromArray(currentLookat);
-        var previousLookat = previousTransform.unprojectBasic(previousBasic, this._lookatDepth);
-        previousCamera.lookat.fromArray(previousLookat);
-    };
-    TraversingState.prototype._updateZoom = function (animationSpeed) {
-        var diff = this._desiredZoom - this._zoom;
-        var sign = diff > 0 ? 1 : diff < 0 ? -1 : 0;
-        if (diff === 0) {
-            return;
-        }
-        else if (Math.abs(diff) < 2e-3) {
-            this._zoom = this._desiredZoom;
-            if (this._desiredLookat != null) {
-                this._desiredLookat = null;
-            }
-        }
-        else {
-            this._zoom += sign * Math.max(Math.abs(5 * animationSpeed * diff), 2e-3);
-        }
-    };
-    TraversingState.prototype._updateLookat = function (animationSpeed) {
-        if (this._desiredLookat === null) {
-            return;
-        }
-        var diff = this._desiredLookat.distanceToSquared(this._currentCamera.lookat);
-        if (Math.abs(diff) < 1e-6) {
-            this._currentCamera.lookat.copy(this._desiredLookat);
-            this._desiredLookat = null;
-        }
-        else {
-            this._currentCamera.lookat.lerp(this._desiredLookat, 5 * animationSpeed);
-        }
-    };
-    TraversingState.prototype._updateRotation = function () {
-        if (this._requestedRotationDelta != null) {
-            var length_1 = this._rotationDelta.lengthSquared();
-            var requestedLength = this._requestedRotationDelta.lengthSquared();
-            if (requestedLength > length_1) {
-                this._rotationDelta.lerp(this._requestedRotationDelta, this._rotationIncreaseAlpha);
-            }
-            else {
-                this._rotationDelta.lerp(this._requestedRotationDelta, this._rotationDecreaseAlpha);
-            }
-            this._requestedRotationDelta = null;
-            return;
-        }
-        if (this._rotationDelta.isZero) {
-            return;
-        }
-        this._rotationDelta.multiply(this._rotationAcceleration);
-        this._rotationDelta.threshold(this._rotationThreshold);
-    };
-    TraversingState.prototype._updateRotationBasic = function () {
-        if (this._requestedBasicRotation != null) {
-            var x = this._basicRotation[0];
-            var y = this._basicRotation[1];
-            var reqX = this._requestedBasicRotation[0];
-            var reqY = this._requestedBasicRotation[1];
-            if (Math.abs(reqX) > Math.abs(x)) {
-                this._basicRotation[0] = (1 - this._rotationIncreaseAlpha) * x + this._rotationIncreaseAlpha * reqX;
-            }
-            else {
-                this._basicRotation[0] = (1 - this._rotationDecreaseAlpha) * x + this._rotationDecreaseAlpha * reqX;
-            }
-            if (Math.abs(reqY) > Math.abs(y)) {
-                this._basicRotation[1] = (1 - this._rotationIncreaseAlpha) * y + this._rotationIncreaseAlpha * reqY;
-            }
-            else {
-                this._basicRotation[1] = (1 - this._rotationDecreaseAlpha) * y + this._rotationDecreaseAlpha * reqY;
-            }
-            this._requestedBasicRotation = null;
-            return;
-        }
-        if (this._requestedBasicRotationUnbounded != null) {
-            var reqX = this._requestedBasicRotationUnbounded[0];
-            var reqY = this._requestedBasicRotationUnbounded[1];
-            if (Math.abs(reqX) > 0) {
-                this._basicRotation[0] = (1 - this._unboundedRotationAlpha) * this._basicRotation[0] + this._unboundedRotationAlpha * reqX;
-            }
-            if (Math.abs(reqY) > 0) {
-                this._basicRotation[1] = (1 - this._unboundedRotationAlpha) * this._basicRotation[1] + this._unboundedRotationAlpha * reqY;
-            }
-            if (this._desiredLookat != null) {
-                var desiredBasicLookat = this.currentTransform.projectBasic(this._desiredLookat.toArray());
-                desiredBasicLookat[0] += reqX;
-                desiredBasicLookat[1] += reqY;
-                this._desiredLookat = new THREE.Vector3()
-                    .fromArray(this.currentTransform.unprojectBasic(desiredBasicLookat, this._lookatDepth));
-            }
-            this._requestedBasicRotationUnbounded = null;
-        }
-        if (this._basicRotation[0] === 0 && this._basicRotation[1] === 0) {
-            return;
-        }
-        this._basicRotation[0] = this._rotationAcceleration * this._basicRotation[0];
-        this._basicRotation[1] = this._rotationAcceleration * this._basicRotation[1];
-        if (Math.abs(this._basicRotation[0]) < this._rotationThreshold / Math.pow(2, this._zoom) &&
-            Math.abs(this._basicRotation[1]) < this._rotationThreshold / Math.pow(2, this._zoom)) {
-            this._basicRotation = [0, 0];
-        }
-    };
-    TraversingState.prototype._clearRotation = function () {
-        if (this._currentNode.fullPano) {
-            return;
-        }
-        if (this._requestedRotationDelta != null) {
-            this._requestedRotationDelta = null;
-        }
-        if (!this._rotationDelta.isZero) {
-            this._rotationDelta.reset();
-        }
-        if (this._requestedBasicRotation != null) {
-            this._requestedBasicRotation = null;
-        }
-        if (this._basicRotation[0] > 0 || this._basicRotation[1] > 0) {
-            this._basicRotation = [0, 0];
-        }
-    };
-    TraversingState.prototype._setDesiredCenter = function () {
-        if (this._desiredCenter == null) {
-            return;
-        }
-        var lookatDirection = new THREE.Vector3()
-            .fromArray(this.currentTransform.unprojectBasic(this._desiredCenter, this._lookatDepth))
-            .sub(this._currentCamera.position);
-        this._currentCamera.lookat.copy(this._currentCamera.position.clone().add(lookatDirection));
-        this._previousCamera.lookat.copy(this._previousCamera.position.clone().add(lookatDirection));
-        this._desiredCenter = null;
-    };
-    TraversingState.prototype._setDesiredZoom = function () {
-        this._desiredZoom =
-            this._currentNode.fullPano || this._previousNode == null ?
-                this._zoom : 0;
-    };
     return TraversingState;
-}(State_1.StateBase));
+}(State_1.InteractiveStateBase));
 exports.TraversingState = TraversingState;
+exports.default = TraversingState;
 
-},{"../../State":288,"@mapbox/unitbezier":2,"three":231}],408:[function(require,module,exports){
+},{"../../State":297,"@mapbox/unitbezier":2}],425:[function(require,module,exports){
 "use strict";
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
@@ -42115,6 +44069,9 @@ var WaitingState = /** @class */ (function (_super) {
     WaitingState.prototype.wait = function () {
         throw new Error("Not implemented");
     };
+    WaitingState.prototype.waitInteractively = function () {
+        return new State_1.InteractiveWaitingState(this);
+    };
     WaitingState.prototype.prepend = function (nodes) {
         _super.prototype.prepend.call(this, nodes);
         this._motionless = this._motionlessTransition();
@@ -42164,8 +44121,9 @@ var WaitingState = /** @class */ (function (_super) {
     return WaitingState;
 }(State_1.StateBase));
 exports.WaitingState = WaitingState;
+exports.default = WaitingState;
 
-},{"../../State":288}],409:[function(require,module,exports){
+},{"../../State":297}],426:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Observable_1 = require("rxjs/Observable");
@@ -42257,7 +44215,7 @@ var ImageTileLoader = /** @class */ (function () {
 exports.ImageTileLoader = ImageTileLoader;
 exports.default = ImageTileLoader;
 
-},{"rxjs/Observable":29}],410:[function(require,module,exports){
+},{"rxjs/Observable":29}],427:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 /**
@@ -42325,7 +44283,7 @@ var ImageTileStore = /** @class */ (function () {
 exports.ImageTileStore = ImageTileStore;
 exports.default = ImageTileStore;
 
-},{}],411:[function(require,module,exports){
+},{}],428:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -42466,7 +44424,7 @@ var RegionOfInterestCalculator = /** @class */ (function () {
 exports.RegionOfInterestCalculator = RegionOfInterestCalculator;
 exports.default = RegionOfInterestCalculator;
 
-},{"../Geo":284}],412:[function(require,module,exports){
+},{"../Geo":293}],429:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -42947,7 +44905,7 @@ var TextureProvider = /** @class */ (function () {
 exports.TextureProvider = TextureProvider;
 exports.default = TextureProvider;
 
-},{"rxjs/Subject":34,"three":231}],413:[function(require,module,exports){
+},{"rxjs/Subject":34,"three":240}],430:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var DOM = /** @class */ (function () {
@@ -42976,7 +44934,7 @@ var DOM = /** @class */ (function () {
 exports.DOM = DOM;
 exports.default = DOM;
 
-},{}],414:[function(require,module,exports){
+},{}],431:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var EventEmitter = /** @class */ (function () {
@@ -43035,7 +44993,7 @@ var EventEmitter = /** @class */ (function () {
 exports.EventEmitter = EventEmitter;
 exports.default = EventEmitter;
 
-},{}],415:[function(require,module,exports){
+},{}],432:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Viewer_1 = require("../Viewer");
@@ -43079,7 +45037,7 @@ var Settings = /** @class */ (function () {
 exports.Settings = Settings;
 exports.default = Settings;
 
-},{"../Viewer":292}],416:[function(require,module,exports){
+},{"../Viewer":301}],433:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 function isBrowser() {
@@ -43107,6 +45065,10 @@ function isObjectSupported() {
         Object.assign);
 }
 exports.isObjectSupported = isObjectSupported;
+function isBlobSupported() {
+    return "Blob" in window && "URL" in window;
+}
+exports.isBlobSupported = isBlobSupported;
 var isWebGLSupportedCache = undefined;
 function isWebGLSupportedCached() {
     if (isWebGLSupportedCache === undefined) {
@@ -43145,48 +45107,92 @@ function isWebGLSupported() {
 }
 exports.isWebGLSupported = isWebGLSupported;
 
-},{}],417:[function(require,module,exports){
+},{}],434:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Urls = /** @class */ (function () {
     function Urls() {
     }
-    Object.defineProperty(Urls, "tileScheme", {
+    Object.defineProperty(Urls, "explore", {
         get: function () {
-            return "https";
+            return Urls._scheme + "://" + Urls._exploreHost;
         },
         enumerable: true,
         configurable: true
     });
-    Object.defineProperty(Urls, "tileDomain", {
+    Object.defineProperty(Urls, "origin", {
         get: function () {
-            return "d2qb1440i7l50o.cloudfront.net";
+            return Urls._origin;
         },
         enumerable: true,
         configurable: true
     });
-    Object.defineProperty(Urls, "origin", {
+    Object.defineProperty(Urls, "tileScheme", {
+        get: function () {
+            return Urls._scheme;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Urls, "tileDomain", {
         get: function () {
-            return "mapillary.webgl";
+            return Urls._imageTileHost;
         },
         enumerable: true,
         configurable: true
     });
-    Urls.thumbnail = function (key, size) {
-        return "https://d1cuyjsrcm0gby.cloudfront.net/" + key + "/thumb-" + size + ".jpg?origin=" + this.origin;
+    Urls.exporeImage = function (key) {
+        return Urls._scheme + "://" + Urls._exploreHost + "/app/?pKey=" + key + "&focus=photo";
+    };
+    Urls.exporeUser = function (username) {
+        return Urls._scheme + "://" + Urls._exploreHost + "/app/user/" + username;
     };
     Urls.falcorModel = function (clientId) {
-        return "https://a.mapillary.com/v3/model.json?client_id=" + clientId;
+        return Urls._scheme + "://" + Urls._apiHost + "/v3/model.json?client_id=" + clientId;
     };
     Urls.protoMesh = function (key) {
-        return "https://d1brzeo354iq2l.cloudfront.net/v2/mesh/" + key;
+        return Urls._scheme + "://" + Urls._meshHost + "/v2/mesh/" + key;
     };
+    Urls.thumbnail = function (key, size, origin) {
+        var query = !!origin ? "?origin=" + origin : "";
+        return Urls._scheme + "://" + Urls._imageHost + "/" + key + "/thumb-" + size + ".jpg" + query;
+    };
+    Urls.setOptions = function (options) {
+        if (!options) {
+            return;
+        }
+        if (!!options.apiHost) {
+            Urls._apiHost = options.apiHost;
+        }
+        if (!!options.exploreHost) {
+            Urls._exploreHost = options.exploreHost;
+        }
+        if (!!options.imageHost) {
+            Urls._imageHost = options.imageHost;
+        }
+        if (!!options.imageTileHost) {
+            Urls._imageTileHost = options.imageTileHost;
+        }
+        if (!!options.meshHost) {
+            Urls._meshHost = options.meshHost;
+        }
+        if (!!options.scheme) {
+            Urls._scheme = options.scheme;
+        }
+    };
+    Urls._apiHost = "a.mapillary.com";
+    Urls._exploreHost = "www.mapillary.com";
+    Urls._imageHost = "d1cuyjsrcm0gby.cloudfront.net";
+    Urls._imageTileHost = "d2qb1440i7l50o.cloudfront.net";
+    Urls._meshHost = "d1brzeo354iq2l.cloudfront.net";
+    Urls._origin = "mapillary.webgl";
+    Urls._scheme = "https";
     return Urls;
 }());
 exports.Urls = Urls;
 exports.default = Urls;
 
-},{}],418:[function(require,module,exports){
+},{}],435:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 /**
@@ -43235,16 +45241,10 @@ var Alignment;
 })(Alignment = exports.Alignment || (exports.Alignment = {}));
 exports.default = Alignment;
 
-},{}],419:[function(require,module,exports){
+},{}],436:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Observable_1 = require("rxjs/Observable");
-require("rxjs/add/operator/bufferCount");
-require("rxjs/add/operator/delay");
-require("rxjs/add/operator/distinctUntilChanged");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/switchMap");
-require("rxjs/add/operator/timeout");
 var Graph_1 = require("../Graph");
 var CacheService = /** @class */ (function () {
     function CacheService(graphService, stateService) {
@@ -43338,7 +45338,7 @@ var CacheService = /** @class */ (function () {
 exports.CacheService = CacheService;
 exports.default = CacheService;
 
-},{"../Graph":285,"rxjs/Observable":29,"rxjs/add/operator/bufferCount":50,"rxjs/add/operator/delay":56,"rxjs/add/operator/distinctUntilChanged":58,"rxjs/add/operator/map":65,"rxjs/add/operator/switchMap":81,"rxjs/add/operator/timeout":86}],420:[function(require,module,exports){
+},{"../Graph":294,"rxjs/Observable":29}],437:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Component_1 = require("../Component");
@@ -43422,6 +45422,7 @@ var ComponentController = /** @class */ (function () {
         this._uTrue(options.mouse, "mouse");
         this._uTrue(options.sequence, "sequence");
         this._uTrue(options.stats, "stats");
+        this._uTrue(options.zoom, "zoom");
     };
     ComponentController.prototype._initilizeCoverComponent = function () {
         var options = this._options;
@@ -43516,7 +45517,7 @@ var ComponentController = /** @class */ (function () {
 }());
 exports.ComponentController = ComponentController;
 
-},{"../Component":281}],421:[function(require,module,exports){
+},{"../Component":290}],438:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Render_1 = require("../Render");
@@ -43567,7 +45568,7 @@ var Container = /** @class */ (function () {
 exports.Container = Container;
 exports.default = Container;
 
-},{"../Render":287,"../Utils":291,"../Viewer":292}],422:[function(require,module,exports){
+},{"../Render":296,"../Utils":300,"../Viewer":301}],439:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 /**
@@ -43596,7 +45597,7 @@ var ImageSize;
     ImageSize[ImageSize["Size2048"] = 2048] = "Size2048";
 })(ImageSize = exports.ImageSize || (exports.ImageSize = {}));
 
-},{}],423:[function(require,module,exports){
+},{}],440:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Observable_1 = require("rxjs/Observable");
@@ -43616,18 +45617,12 @@ var KeyboardService = /** @class */ (function () {
 exports.KeyboardService = KeyboardService;
 exports.default = KeyboardService;
 
-},{"rxjs/Observable":29}],424:[function(require,module,exports){
+},{"rxjs/Observable":29}],441:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
 var _ = require("underscore");
 var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/operator/debounceTime");
-require("rxjs/add/operator/distinctUntilChanged");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/publishReplay");
-require("rxjs/add/operator/scan");
-require("rxjs/add/operator/startWith");
 var LoadingService = /** @class */ (function () {
     function LoadingService() {
         this._loadersSubject$ = new Subject_1.Subject();
@@ -43675,22 +45670,12 @@ var LoadingService = /** @class */ (function () {
 exports.LoadingService = LoadingService;
 exports.default = LoadingService;
 
-},{"rxjs/Subject":34,"rxjs/add/operator/debounceTime":55,"rxjs/add/operator/distinctUntilChanged":58,"rxjs/add/operator/map":65,"rxjs/add/operator/publishReplay":72,"rxjs/add/operator/scan":75,"rxjs/add/operator/startWith":80,"underscore":233}],425:[function(require,module,exports){
+},{"rxjs/Subject":34,"underscore":242}],442:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var BehaviorSubject_1 = require("rxjs/BehaviorSubject");
 var Observable_1 = require("rxjs/Observable");
 var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/observable/fromEvent");
-require("rxjs/add/operator/distinctUntilChanged");
-require("rxjs/add/operator/filter");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/merge");
-require("rxjs/add/operator/mergeMap");
-require("rxjs/add/operator/publishReplay");
-require("rxjs/add/operator/scan");
-require("rxjs/add/operator/switchMap");
-require("rxjs/add/operator/withLatestFrom");
 var Geo_1 = require("../Geo");
 var MouseService = /** @class */ (function () {
     function MouseService(container, canvasContainer, domContainer, doc, viewportCoords) {
@@ -44127,26 +46112,21 @@ var MouseService = /** @class */ (function () {
 exports.MouseService = MouseService;
 exports.default = MouseService;
 
-},{"../Geo":284,"rxjs/BehaviorSubject":26,"rxjs/Observable":29,"rxjs/Subject":34,"rxjs/add/observable/fromEvent":42,"rxjs/add/operator/distinctUntilChanged":58,"rxjs/add/operator/filter":61,"rxjs/add/operator/map":65,"rxjs/add/operator/merge":66,"rxjs/add/operator/mergeMap":68,"rxjs/add/operator/publishReplay":72,"rxjs/add/operator/scan":75,"rxjs/add/operator/switchMap":81,"rxjs/add/operator/withLatestFrom":87}],426:[function(require,module,exports){
+},{"../Geo":293,"rxjs/BehaviorSubject":26,"rxjs/Observable":29,"rxjs/Subject":34}],443:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
 var BehaviorSubject_1 = require("rxjs/BehaviorSubject");
 var Observable_1 = require("rxjs/Observable");
 var ReplaySubject_1 = require("rxjs/ReplaySubject");
-require("rxjs/add/observable/throw");
-require("rxjs/add/operator/do");
-require("rxjs/add/operator/finally");
-require("rxjs/add/operator/first");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/mergeMap");
 var API_1 = require("../API");
 var Graph_1 = require("../Graph");
 var Edge_1 = require("../Edge");
+var Error_1 = require("../Error");
 var State_1 = require("../State");
 var Viewer_1 = require("../Viewer");
 var Navigator = /** @class */ (function () {
-    function Navigator(clientId, token, apiV3, graphService, imageLoadingService, loadingService, stateService, cacheService, playService) {
+    function Navigator(clientId, options, token, apiV3, graphService, imageLoadingService, loadingService, stateService, cacheService, playService) {
         this._apiV3 = apiV3 != null ? apiV3 : new API_1.APIv3(clientId, token);
         this._imageLoadingService = imageLoadingService != null ? imageLoadingService : new Graph_1.ImageLoadingService();
         this._graphService = graphService != null ?
@@ -44154,7 +46134,7 @@ var Navigator = /** @class */ (function () {
             new Graph_1.GraphService(new Graph_1.Graph(this.apiV3), this._imageLoadingService);
         this._loadingService = loadingService != null ? loadingService : new Viewer_1.LoadingService();
         this._loadingName = "navigator";
-        this._stateService = stateService != null ? stateService : new State_1.StateService();
+        this._stateService = stateService != null ? stateService : new State_1.StateService(options.transitionMode);
         this._cacheService = cacheService != null ?
             cacheService :
             new Viewer_1.CacheService(this._graphService, this._stateService);
@@ -44355,23 +46335,28 @@ var Navigator = /** @class */ (function () {
             this._nodeRequestSubscription = null;
         }
         if (this._request$ != null) {
-            this._request$.error(new Error("Request aborted by a subsequent request " + reason + "."));
+            if (!(this._request$.isStopped || this._request$.hasError)) {
+                this._request$.error(new Error_1.AbortMapillaryError("Request aborted by a subsequent request " + reason + "."));
+            }
             this._request$ = null;
         }
     };
     Navigator.prototype._makeRequest$ = function (node$) {
         var _this = this;
-        this._request$ = new ReplaySubject_1.ReplaySubject(1);
-        this._requestSubscription = this._request$
+        var request$ = new ReplaySubject_1.ReplaySubject(1);
+        this._requestSubscription = request$
             .subscribe(undefined, function (e) { });
+        this._request$ = request$;
         this._nodeRequestSubscription = node$
             .subscribe(function (node) {
-            _this._request$.next(node);
-            _this._request$.complete();
+            request$.next(node);
+            request$.complete();
+            _this._request$ = null;
         }, function (error) {
-            _this._request$.error(error);
+            request$.error(error);
+            _this._request$ = null;
         });
-        return this._request$;
+        return request$;
     };
     Navigator.prototype._moveToKey$ = function (key) {
         var _this = this;
@@ -44400,15 +46385,11 @@ var Navigator = /** @class */ (function () {
 exports.Navigator = Navigator;
 exports.default = Navigator;
 
-},{"../API":280,"../Edge":282,"../Graph":285,"../State":288,"../Viewer":292,"rxjs/BehaviorSubject":26,"rxjs/Observable":29,"rxjs/ReplaySubject":32,"rxjs/add/observable/throw":46,"rxjs/add/operator/do":59,"rxjs/add/operator/finally":62,"rxjs/add/operator/first":63,"rxjs/add/operator/map":65,"rxjs/add/operator/mergeMap":68}],427:[function(require,module,exports){
+},{"../API":289,"../Edge":291,"../Error":292,"../Graph":294,"../State":297,"../Viewer":301,"rxjs/BehaviorSubject":26,"rxjs/Observable":29,"rxjs/ReplaySubject":32}],444:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Observable_1 = require("rxjs/Observable");
 var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/observable/combineLatest");
-require("rxjs/add/operator/distinctUntilChanged");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/throttleTime");
 var Viewer_1 = require("../Viewer");
 var Observer = /** @class */ (function () {
     function Observer(eventEmitter, navigator, container) {
@@ -44493,7 +46474,7 @@ var Observer = /** @class */ (function () {
             }
         });
         this._bearingSubscription = this._container.renderService.bearing$
-            .throttleTime(100)
+            .auditTime(100)
             .distinctUntilChanged(function (b1, b2) {
             return Math.abs(b2 - b1) < 1;
         })
@@ -44574,18 +46555,18 @@ var Observer = /** @class */ (function () {
 exports.Observer = Observer;
 exports.default = Observer;
 
-},{"../Viewer":292,"rxjs/Observable":29,"rxjs/Subject":34,"rxjs/add/observable/combineLatest":38,"rxjs/add/operator/distinctUntilChanged":58,"rxjs/add/operator/map":65,"rxjs/add/operator/throttleTime":85}],428:[function(require,module,exports){
+},{"../Viewer":301,"rxjs/Observable":29,"rxjs/Subject":34}],445:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var Observable_1 = require("rxjs/Observable");
 var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/operator/timeout");
 var Edge_1 = require("../Edge");
 var Graph_1 = require("../Graph");
 var PlayService = /** @class */ (function () {
-    function PlayService(graphService, stateService) {
+    function PlayService(graphService, stateService, graphCalculator) {
         this._graphService = graphService;
         this._stateService = stateService;
+        this._graphCalculator = !!graphCalculator ? graphCalculator : new Graph_1.GraphCalculator();
         this._directionSubject$ = new Subject_1.Subject();
         this._direction$ = this._directionSubject$
             .startWith(Edge_1.EdgeDirection.Next)
@@ -44607,6 +46588,7 @@ var PlayService = /** @class */ (function () {
             .refCount();
         this._speed$.subscribe();
         this._nodesAhead = this._mapNodesAhead(this._mapSpeed(this._speed));
+        this._bridging$ = null;
     }
     Object.defineProperty(PlayService.prototype, "playing", {
         get: function () {
@@ -44670,7 +46652,8 @@ var PlayService = /** @class */ (function () {
                 _this._graphService.cacheSequenceNodes$(sequenceKey, nodeKey) :
                 _this._graphService.cacheSequence$(sequenceKey))
                 .retry(3)
-                .catch(function () {
+                .catch(function (error) {
+                console.error(error);
                 return Observable_1.Observable.of(undefined);
             });
             return Observable_1.Observable
@@ -44723,15 +46706,28 @@ var PlayService = /** @class */ (function () {
             .filter(function (frame) {
             return frame.state.nodesAhead < _this._nodesAhead;
         })
-            .map(function (frame) {
-            return frame.state.lastNode;
+            .distinctUntilChanged(undefined, function (frame) {
+            return frame.state.lastNode.key;
         })
-            .distinctUntilChanged(undefined, function (lastNode) {
-            return lastNode.key;
+            .map(function (frame) {
+            var lastNode = frame.state.lastNode;
+            var trajectory = frame.state.trajectory;
+            var increasingTime = undefined;
+            for (var i = trajectory.length - 2; i >= 0; i--) {
+                var node = trajectory[i];
+                if (node.sequenceKey !== lastNode.sequenceKey) {
+                    break;
+                }
+                if (node.capturedAt !== lastNode.capturedAt) {
+                    increasingTime = node.capturedAt < lastNode.capturedAt;
+                    break;
+                }
+            }
+            return [frame.state.lastNode, increasingTime];
         })
             .withLatestFrom(this._direction$)
             .switchMap(function (_a) {
-            var node = _a[0], direction = _a[1];
+            var _b = _a[0], node = _b[0], increasingTime = _b[1], direction = _a[1];
             return ([Edge_1.EdgeDirection.Next, Edge_1.EdgeDirection.Prev].indexOf(direction) > -1 ?
                 node.sequenceEdges$ :
                 node.spatialEdges$)
@@ -44749,12 +46745,14 @@ var PlayService = /** @class */ (function () {
                     }
                 }
                 return null;
-            })
-                .filter(function (key) {
-                return key != null;
             })
                 .switchMap(function (key) {
-                return _this._graphService.cacheNode$(key);
+                return key != null ?
+                    _this._graphService.cacheNode$(key) :
+                    _this._bridge$(node, increasingTime)
+                        .filter(function (n) {
+                        return !!n;
+                    });
             });
         })
             .subscribe(function (node) {
@@ -44769,8 +46767,26 @@ var PlayService = /** @class */ (function () {
             _this._stateService.clearPriorNodes();
         });
         this._setPlaying(true);
+        var currentLastNodes$ = this._stateService.currentState$
+            .map(function (frame) {
+            return frame.state;
+        })
+            .distinctUntilChanged(function (_a, _b) {
+            var kc1 = _a[0], kl1 = _a[1];
+            var kc2 = _b[0], kl2 = _b[1];
+            return kc1 === kc2 && kl1 === kl2;
+        }, function (state) {
+            return [state.currentNode.key, state.lastNode.key];
+        })
+            .filter(function (state) {
+            return state.currentNode.key === state.lastNode.key &&
+                state.currentIndex === state.trajectory.length - 1;
+        })
+            .map(function (state) {
+            return state.currentNode;
+        });
         this._stopSubscription = Observable_1.Observable
-            .combineLatest(this._stateService.currentNode$, this._direction$)
+            .combineLatest(currentLastNodes$, this._direction$)
             .switchMap(function (_a) {
             var node = _a[0], direction = _a[1];
             var edgeStatus$ = ([Edge_1.EdgeDirection.Next, Edge_1.EdgeDirection.Prev].indexOf(direction) > -1 ?
@@ -44785,17 +46801,30 @@ var PlayService = /** @class */ (function () {
                 return Observable_1.Observable.of({ cached: false, edges: [] });
             });
             return Observable_1.Observable
-                .combineLatest(Observable_1.Observable.of(direction), edgeStatus$);
-        })
-            .map(function (_a) {
-            var direction = _a[0], edgeStatus = _a[1];
-            for (var _i = 0, _b = edgeStatus.edges; _i < _b.length; _i++) {
-                var edge = _b[_i];
-                if (edge.data.direction === direction) {
-                    return true;
+                .combineLatest(Observable_1.Observable.of(direction), edgeStatus$)
+                .map(function (_a) {
+                var d = _a[0], es = _a[1];
+                for (var _i = 0, _b = es.edges; _i < _b.length; _i++) {
+                    var edge = _b[_i];
+                    if (edge.data.direction === d) {
+                        return true;
+                    }
                 }
+                return false;
+            });
+        })
+            .mergeMap(function (hasEdge) {
+            if (hasEdge || !_this._bridging$) {
+                return Observable_1.Observable.of(hasEdge);
             }
-            return false;
+            return _this._bridging$
+                .map(function (node) {
+                return node != null;
+            })
+                .catch(function (error) {
+                console.error(error);
+                return Observable_1.Observable.of(false);
+            });
         })
             .first(function (hasEdge) {
             return !hasEdge;
@@ -44842,6 +46871,43 @@ var PlayService = /** @class */ (function () {
         this._graphService.setGraphMode(Graph_1.GraphMode.Spatial);
         this._setPlaying(false);
     };
+    PlayService.prototype._bridge$ = function (node, increasingTime) {
+        var _this = this;
+        if (increasingTime === undefined) {
+            return Observable_1.Observable.of(null);
+        }
+        var boundingBox = this._graphCalculator.boundingBoxCorners(node.latLon, 25);
+        this._bridging$ = this._graphService.cacheBoundingBox$(boundingBox[0], boundingBox[1])
+            .mergeMap(function (nodes) {
+            var nextNode = null;
+            for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
+                var n = nodes_1[_i];
+                if (n.sequenceKey === node.sequenceKey ||
+                    !n.cameraUuid ||
+                    n.cameraUuid !== node.cameraUuid ||
+                    n.capturedAt === node.capturedAt ||
+                    n.capturedAt > node.capturedAt !== increasingTime) {
+                    continue;
+                }
+                var delta = Math.abs(n.capturedAt - node.capturedAt);
+                if (delta > 15000) {
+                    continue;
+                }
+                if (!nextNode || delta < Math.abs(nextNode.capturedAt - node.capturedAt)) {
+                    nextNode = n;
+                }
+            }
+            return !!nextNode ?
+                _this._graphService.cacheNode$(nextNode.key) :
+                Observable_1.Observable.of(null);
+        })
+            .finally(function () {
+            _this._bridging$ = null;
+        })
+            .publish()
+            .refCount();
+        return this._bridging$;
+    };
     PlayService.prototype._mapSpeed = function (speed) {
         var x = 2 * speed - 1;
         return Math.pow(10, x) - 0.2 * x;
@@ -44864,7 +46930,7 @@ var PlayService = /** @class */ (function () {
 exports.PlayService = PlayService;
 exports.default = PlayService;
 
-},{"../Edge":282,"../Graph":285,"rxjs/Observable":29,"rxjs/Subject":34,"rxjs/add/operator/timeout":86}],429:[function(require,module,exports){
+},{"../Edge":291,"../Graph":294,"rxjs/Observable":29,"rxjs/Subject":34}],446:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
@@ -44923,16 +46989,13 @@ var Projection = /** @class */ (function () {
 exports.Projection = Projection;
 exports.default = Projection;
 
-},{"../Geo":284,"three":231}],430:[function(require,module,exports){
+},{"../Geo":293,"three":240}],447:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 Object.defineProperty(exports, "__esModule", { value: true });
 var THREE = require("three");
 var vd = require("virtual-dom");
 var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/operator/publishReplay");
-require("rxjs/add/operator/scan");
-require("rxjs/add/operator/startWith");
 var Viewer_1 = require("../Viewer");
 var SpriteAtlas = /** @class */ (function () {
     function SpriteAtlas() {
@@ -45122,19 +47185,12 @@ var SpriteService = /** @class */ (function () {
 exports.SpriteService = SpriteService;
 exports.default = SpriteService;
 
-},{"../Viewer":292,"rxjs/Subject":34,"rxjs/add/operator/publishReplay":72,"rxjs/add/operator/scan":75,"rxjs/add/operator/startWith":80,"three":231,"virtual-dom":237}],431:[function(require,module,exports){
+},{"../Viewer":301,"rxjs/Subject":34,"three":240,"virtual-dom":246}],448:[function(require,module,exports){
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 var BehaviorSubject_1 = require("rxjs/BehaviorSubject");
 var Observable_1 = require("rxjs/Observable");
 var Subject_1 = require("rxjs/Subject");
-require("rxjs/add/observable/timer");
-require("rxjs/add/operator/bufferWhen");
-require("rxjs/add/operator/filter");
-require("rxjs/add/operator/map");
-require("rxjs/add/operator/merge");
-require("rxjs/add/operator/scan");
-require("rxjs/add/operator/switchMap");
 var TouchService = /** @class */ (function () {
     function TouchService(canvasContainer, domContainer) {
         var _this = this;
@@ -45395,7 +47451,7 @@ var TouchService = /** @class */ (function () {
 }());
 exports.TouchService = TouchService;
 
-},{"rxjs/BehaviorSubject":26,"rxjs/Observable":29,"rxjs/Subject":34,"rxjs/add/observable/timer":47,"rxjs/add/operator/bufferWhen":51,"rxjs/add/operator/filter":61,"rxjs/add/operator/map":65,"rxjs/add/operator/merge":66,"rxjs/add/operator/scan":75,"rxjs/add/operator/switchMap":81}],432:[function(require,module,exports){
+},{"rxjs/BehaviorSubject":26,"rxjs/Observable":29,"rxjs/Subject":34}],449:[function(require,module,exports){
 "use strict";
 /// <reference path="../../typings/index.d.ts" />
 var __extends = (this && this.__extends) || (function () {
@@ -45410,6 +47466,60 @@ var __extends = (this && this.__extends) || (function () {
 })();
 Object.defineProperty(exports, "__esModule", { value: true });
 var when = require("when");
+require("rxjs/add/observable/combineLatest");
+require("rxjs/add/observable/concat");
+require("rxjs/add/observable/defer");
+require("rxjs/add/observable/empty");
+require("rxjs/add/observable/merge");
+require("rxjs/add/observable/from");
+require("rxjs/add/observable/fromEvent");
+require("rxjs/add/observable/fromPromise");
+require("rxjs/add/observable/of");
+require("rxjs/add/observable/throw");
+require("rxjs/add/observable/timer");
+require("rxjs/add/observable/zip");
+require("rxjs/add/operator/auditTime");
+require("rxjs/add/operator/buffer");
+require("rxjs/add/operator/bufferCount");
+require("rxjs/add/operator/bufferWhen");
+require("rxjs/add/operator/catch");
+require("rxjs/add/operator/combineLatest");
+require("rxjs/add/operator/concat");
+require("rxjs/add/operator/count");
+require("rxjs/add/operator/debounceTime");
+require("rxjs/add/operator/delay");
+require("rxjs/add/operator/distinct");
+require("rxjs/add/operator/distinctUntilChanged");
+require("rxjs/add/operator/do");
+require("rxjs/add/operator/expand");
+require("rxjs/add/operator/filter");
+require("rxjs/add/operator/finally");
+require("rxjs/add/operator/first");
+require("rxjs/add/operator/last");
+require("rxjs/add/operator/map");
+require("rxjs/add/operator/merge");
+require("rxjs/add/operator/mergeMap");
+require("rxjs/add/operator/mergeAll");
+require("rxjs/add/operator/pairwise");
+require("rxjs/add/operator/pluck");
+require("rxjs/add/operator/publish");
+require("rxjs/add/operator/publishReplay");
+require("rxjs/add/operator/reduce");
+require("rxjs/add/operator/retry");
+require("rxjs/add/operator/sample");
+require("rxjs/add/operator/scan");
+require("rxjs/add/operator/share");
+require("rxjs/add/operator/skip");
+require("rxjs/add/operator/skipUntil");
+require("rxjs/add/operator/skipWhile");
+require("rxjs/add/operator/startWith");
+require("rxjs/add/operator/switchMap");
+require("rxjs/add/operator/take");
+require("rxjs/add/operator/takeUntil");
+require("rxjs/add/operator/takeWhile");
+require("rxjs/add/operator/timeout");
+require("rxjs/add/operator/withLatestFrom");
+require("rxjs/add/operator/zip");
 var Observable_1 = require("rxjs/Observable");
 var Viewer_1 = require("../Viewer");
 var Utils_1 = require("../Utils");
@@ -45470,14 +47580,21 @@ var Viewer = /** @class */ (function (_super) {
      * @description It is possible to initialize the viewer with or
      * without a key.
      *
+     * When you want to show a specific image in the viewer from
+     * the start you should initialize it with a key.
+     *
+     * When you do not know the first image key at implementation
+     * time, e.g. in a map-viewer application you should initialize
+     * the viewer without a key and call `moveToKey` instead.
+     *
      * When initializing with a key the viewer is bound to that key
-     * until the node/image for that key has been successfully loaded.
+     * until the node for that key has been successfully loaded.
      * Also, a cover with the image of the key will be shown.
      * If the data for that key can not be loaded because the key is
      * faulty or other errors occur it is not possible to navigate
      * to another key because the viewer is not navigable. The viewer
-     * becomes navigable when the data for the has been loaded and
-     * the image is shown in the viewer. This wayof initializing
+     * becomes navigable when the data for the key has been loaded and
+     * the image is shown in the viewer. This way of initializing
      * the viewer is mostly for embedding in blog posts and similar
      * where one wants to show a specific image initially.
      *
@@ -45514,7 +47631,8 @@ var Viewer = /** @class */ (function (_super) {
         var _this = _super.call(this) || this;
         options = options != null ? options : {};
         Utils_1.Settings.setOptions(options);
-        _this._navigator = new Viewer_1.Navigator(clientId, token);
+        Utils_1.Urls.setOptions(options.url);
+        _this._navigator = new Viewer_1.Navigator(clientId, options, token);
         _this._container = new Viewer_1.Container(id, _this._navigator.stateService, options);
         _this._observer = new Viewer_1.Observer(_this, _this._navigator, _this._container);
         _this._componentController = new Viewer_1.ComponentController(_this._container, _this._navigator, _this._observer, key, options.component);
@@ -45525,11 +47643,12 @@ var Viewer = /** @class */ (function (_super) {
          * Return a boolean indicating if the viewer is in a navigable state.
          *
          * @description The navigable state indicates if the viewer supports
-         * moving, i.e. calling the `moveToKey`, `moveDir` and `moveCloseTo`
-         * methods. The viewer will not be in a navigable state if the cover
-         * is activated and the viewer has been supplied a key. When the cover
-         * is deactivated or activated without being supplied a key it will
-         * be navigable.
+         * moving, i.e. calling the {@link moveToKey}, {@link moveDir`}
+         * and {@link moveCloseTo} methods or changing the authentication state,
+         * i.e. calling {@link setAuthToken}. The viewer will not be in a navigable
+         * state if the cover is activated and the viewer has been supplied a key.
+         * When the cover is deactivated or the viewer is activated without being
+         * supplied a key it will be navigable.
          *
          * @returns {boolean} Boolean indicating whether the viewer is navigable.
          */
@@ -45693,6 +47812,8 @@ var Viewer = /** @class */ (function (_super) {
      * longitude.
      * @throws {Error} Propagates any IO errors to the caller.
      * @throws {Error} When viewer is not navigable.
+     * @throws {AbortMapillaryError} When a subsequent move request is made
+     * before the move close to call has completed.
      *
      * @example
      * ```
@@ -45724,6 +47845,8 @@ var Viewer = /** @class */ (function (_super) {
      * or the edges has not yet been cached.
      * @throws {Error} Propagates any IO errors to the caller.
      * @throws {Error} When viewer is not navigable.
+     * @throws {AbortMapillaryError} When a subsequent move request is made
+     * before the move dir call has completed.
      *
      * @example
      * ```
@@ -45751,6 +47874,8 @@ var Viewer = /** @class */ (function (_super) {
      * @returns {Promise<Node>} Promise to the node that was navigated to.
      * @throws {Error} Propagates any IO errors to the caller.
      * @throws {Error} When viewer is not navigable.
+     * @throws {AbortMapillaryError} When a subsequent move request is made
+     * before the move to key call has completed.
      *
      * @example
      * ```
@@ -45779,7 +47904,7 @@ var Viewer = /** @class */ (function (_super) {
      * pixel point that lies in the visible area of the viewer container.
      *
      * @param {Array<number>} basicPoint - Basic images coordinates to project.
-     * @returns {Promise<ILatLon>} Promise to the pixel coordinates corresponding
+     * @returns {Promise<Array<number>>} Promise to the pixel coordinates corresponding
      * to the basic image point.
      *
      * @example
@@ -45823,8 +47948,8 @@ var Viewer = /** @class */ (function (_super) {
      * viewer will make unauthenticated requests.
      *
      * Calling setAuthToken aborts all outstanding move requests.
-     * The promises of those move requests will be rejected and
-     * the rejections need to be caught.
+     * The promises of those move requests will be rejected with a
+     * {@link AbortMapillaryError} the rejections need to be caught.
      *
      * Calling setAuthToken also resets the complete viewer cache
      * so it should not be called repeatedly.
@@ -45904,8 +48029,9 @@ var Viewer = /** @class */ (function (_super) {
      *
      * `["all", f0, ..., fn]` logical `AND`: `f0 ∧ ... ∧ fn`
      *
-     * A key must be a string that identifies a node property name. A value must be
-     * a string, number, or boolean. Strictly-typed comparisons are used. The values
+     * A key must be a string that identifies a property name of a
+     * simple {@link Node} property. A value must be a string, number, or
+     * boolean. Strictly-typed comparisons are used. The values
      * `f0, ..., fn` of the combining filter must be filter expressions.
      *
      * Clear the filter by setting it to null or empty array.
@@ -45942,6 +48068,19 @@ var Viewer = /** @class */ (function (_super) {
     Viewer.prototype.setRenderMode = function (renderMode) {
         this._container.renderService.renderMode$.next(renderMode);
     };
+    /**
+     * Set the viewer's transition mode.
+     *
+     * @param {TransitionMode} transitionMode - Transition mode.
+     *
+     * @example
+     * ```
+     * viewer.setTransitionMode(Mapillary.TransitionMode.Instantaneous);
+     * ```
+     */
+    Viewer.prototype.setTransitionMode = function (transitionMode) {
+        this._navigator.stateService.setTransitionMode(transitionMode);
+    };
     /**
      * Set the image's current zoom level.
      *
@@ -46018,6 +48157,11 @@ var Viewer = /** @class */ (function (_super) {
     };
     /**
      * Fired when the viewing direction of the camera changes.
+     *
+     * @description Related to the computed compass angle
+     * ({@link Node.computedCa}) from SfM, not the original EXIF compass
+     * angle.
+     *
      * @event
      * @type {number} bearing - Value indicating the current bearing
      * measured in degrees clockwise with respect to north.
@@ -46129,6 +48273,6 @@ var Viewer = /** @class */ (function (_super) {
 }(Utils_1.EventEmitter));
 exports.Viewer = Viewer;
 
-},{"../Utils":291,"../Viewer":292,"rxjs/Observable":29,"when":278}]},{},[286])(286)
+},{"../Utils":300,"../Viewer":301,"rxjs/Observable":29,"rxjs/add/observable/combineLatest":38,"rxjs/add/observable/concat":39,"rxjs/add/observable/defer":40,"rxjs/add/observable/empty":41,"rxjs/add/observable/from":42,"rxjs/add/observable/fromEvent":43,"rxjs/add/observable/fromPromise":44,"rxjs/add/observable/merge":45,"rxjs/add/observable/of":46,"rxjs/add/observable/throw":47,"rxjs/add/observable/timer":48,"rxjs/add/observable/zip":49,"rxjs/add/operator/auditTime":50,"rxjs/add/operator/buffer":51,"rxjs/add/operator/bufferCount":52,"rxjs/add/operator/bufferWhen":53,"rxjs/add/operator/catch":54,"rxjs/add/operator/combineLatest":55,"rxjs/add/operator/concat":56,"rxjs/add/operator/count":57,"rxjs/add/operator/debounceTime":58,"rxjs/add/operator/delay":59,"rxjs/add/operator/distinct":60,"rxjs/add/operator/distinctUntilChanged":61,"rxjs/add/operator/do":62,"rxjs/add/operator/expand":63,"rxjs/add/operator/filter":64,"rxjs/add/operator/finally":65,"rxjs/add/operator/first":66,"rxjs/add/operator/last":67,"rxjs/add/operator/map":68,"rxjs/add/operator/merge":69,"rxjs/add/operator/mergeAll":70,"rxjs/add/operator/mergeMap":71,"rxjs/add/operator/pairwise":72,"rxjs/add/operator/pluck":73,"rxjs/add/operator/publish":74,"rxjs/add/operator/publishReplay":75,"rxjs/add/operator/reduce":76,"rxjs/add/operator/retry":77,"rxjs/add/operator/sample":78,"rxjs/add/operator/scan":79,"rxjs/add/operator/share":80,"rxjs/add/operator/skip":81,"rxjs/add/operator/skipUntil":82,"rxjs/add/operator/skipWhile":83,"rxjs/add/operator/startWith":84,"rxjs/add/operator/switchMap":85,"rxjs/add/operator/take":86,"rxjs/add/operator/takeUntil":87,"rxjs/add/operator/takeWhile":88,"rxjs/add/operator/timeout":89,"rxjs/add/operator/withLatestFrom":90,"rxjs/add/operator/zip":91,"when":287}]},{},[295])(295)
 });
 //# sourceMappingURL=mapillary.js.map