import CartographicGeocoderService from"../../Core/CartographicGeocoderService.js";import defaultValue from"../../Core/defaultValue.js";import defined from"../../Core/defined.js";import DeveloperError from"../../Core/DeveloperError.js";import Event from"../../Core/Event.js";import GeocodeType from"../../Core/GeocodeType.js";import IonGeocoderService from"../../Core/IonGeocoderService.js";import CesiumMath from"../../Core/Math.js";import Matrix4 from"../../Core/Matrix4.js";import Rectangle from"../../Core/Rectangle.js";import sampleTerrainMostDetailed from"../../Core/sampleTerrainMostDetailed.js";import computeFlyToLocationForRectangle from"../../Scene/computeFlyToLocationForRectangle.js";import knockout from"../../ThirdParty/knockout.js";import createCommand from"../createCommand.js";import getElement from"../getElement.js";const DEFAULT_HEIGHT=1e3;function GeocoderViewModel(e){if(!defined(e)||!defined(e.scene))throw new DeveloperError("options.scene is required.");defined(e.geocoderServices)?this._geocoderServices=e.geocoderServices:this._geocoderServices=[new CartographicGeocoderService,new IonGeocoderService({scene:e.scene})],this._viewContainer=e.container,this._scene=e.scene,this._flightDuration=e.flightDuration,this._searchText="",this._isSearchInProgress=!1,this._geocodePromise=void 0,this._complete=new Event,this._suggestions=[],this._selectedSuggestion=void 0,this._showSuggestions=!0,this._handleArrowDown=handleArrowDown,this._handleArrowUp=handleArrowUp;const o=this;this._suggestionsVisible=knockout.pureComputed((function(){const e=knockout.getObservable(o,"_suggestions"),t=e().length>0,n=knockout.getObservable(o,"_showSuggestions")();return t&&n})),this._searchCommand=createCommand((function(e){if(e=defaultValue(e,GeocodeType.SEARCH),o._focusTextbox=!1,defined(o._selectedSuggestion))return o.activateSuggestion(o._selectedSuggestion),!1;o.hideSuggestions(),o.isSearchInProgress?cancelGeocode(o):geocode(o,o._geocoderServices,e)})),this.deselectSuggestion=function(){o._selectedSuggestion=void 0},this.handleKeyDown=function(e,o){const t="ArrowDown"===o.key||"Down"===o.key||40===o.keyCode,n="ArrowUp"===o.key||"Up"===o.key||38===o.keyCode;return(t||n)&&o.preventDefault(),!0},this.handleKeyUp=function(e,t){const n="ArrowDown"===t.key||"Down"===t.key||40===t.keyCode,i="ArrowUp"===t.key||"Up"===t.key||38===t.keyCode,s="Enter"===t.key||13===t.keyCode;return i?handleArrowUp(o):n?handleArrowDown(o):s&&o._searchCommand(),!0},this.activateSuggestion=function(e){o.hideSuggestions(),o._searchText=e.displayName;const t=e.destination;clearSuggestions(o),o.destinationFound(o,t)},this.hideSuggestions=function(){o._showSuggestions=!1,o._selectedSuggestion=void 0},this.showSuggestions=function(){o._showSuggestions=!0},this.handleMouseover=function(e,t){e!==o._selectedSuggestion&&(o._selectedSuggestion=e)},this.keepExpanded=!1,this.autoComplete=defaultValue(e.autocomplete,!0),this.destinationFound=defaultValue(e.destinationFound,GeocoderViewModel.flyToDestination),this._focusTextbox=!1,knockout.track(this,["_searchText","_isSearchInProgress","keepExpanded","_suggestions","_selectedSuggestion","_showSuggestions","_focusTextbox"]);const t=knockout.getObservable(this,"_searchText");t.extend({rateLimit:{timeout:500}}),this._suggestionSubscription=t.subscribe((function(){GeocoderViewModel._updateSearchSuggestions(o)})),this.isSearchInProgress=void 0,knockout.defineProperty(this,"isSearchInProgress",{get:function(){return this._isSearchInProgress}}),this.searchText=void 0,knockout.defineProperty(this,"searchText",{get:function(){return this.isSearchInProgress?"Searching...":this._searchText},set:function(e){if("string"!==typeof e)throw new DeveloperError("value must be a valid string.");this._searchText=e}}),this.flightDuration=void 0,knockout.defineProperty(this,"flightDuration",{get:function(){return this._flightDuration},set:function(e){if(defined(e)&&e<0)throw new DeveloperError("value must be positive.");this._flightDuration=e}})}function handleArrowUp(e){if(0===e._suggestions.length)return;const o=e._suggestions.indexOf(e._selectedSuggestion);if(-1===o||0===o)return void(e._selectedSuggestion=void 0);const t=o-1;e._selectedSuggestion=e._suggestions[t],GeocoderViewModel._adjustSuggestionsScroll(e,t)}function handleArrowDown(e){if(0===e._suggestions.length)return;const o=e._suggestions.length,t=e._suggestions.indexOf(e._selectedSuggestion),n=(t+1)%o;e._selectedSuggestion=e._suggestions[n],GeocoderViewModel._adjustSuggestionsScroll(e,n)}function computeFlyToLocationForCartographic(e,o){const t=defined(o)?o.availability:void 0;return defined(t)?sampleTerrainMostDetailed(o,[e]).then((function(o){return e=o[0],e.height+=DEFAULT_HEIGHT,e})):(e.height+=DEFAULT_HEIGHT,Promise.resolve(e))}function flyToDestination(e,o){const t=e._scene,n=t.mapProjection,i=n.ellipsoid,s=t.camera,r=t.terrainProvider;let c,u=o;return o instanceof Rectangle?CesiumMath.equalsEpsilon(o.south,o.north,CesiumMath.EPSILON7)&&CesiumMath.equalsEpsilon(o.east,o.west,CesiumMath.EPSILON7)?o=Rectangle.center(o):c=computeFlyToLocationForRectangle(o,t):o=i.cartesianToCartographic(o),defined(c)||(c=computeFlyToLocationForCartographic(o,r)),c.then((function(e){u=i.cartographicToCartesian(e)})).finally((function(){s.flyTo({destination:u,complete:function(){e._complete.raiseEvent()},duration:e._flightDuration,endTransform:Matrix4.IDENTITY})}))}function chainPromise(e,o,t,n){return e.then((function(e){if(defined(e)&&"fulfilled"===e.state&&e.value.length>0)return e;const i=o.geocode(t,n).then((function(e){return{state:"fulfilled",value:e}})).catch((function(e){return{state:"rejected",reason:e}}));return i}))}function geocode(e,o,t){const n=e._searchText;if(hasOnlyWhitespace(n))return void e.showSuggestions();e._isSearchInProgress=!0;let i=Promise.resolve();for(let s=0;s0)return e._searchText=t[0].displayName,void e.destinationFound(e,t[0].destination);e._searchText=`${n} (not found)`}))}function adjustSuggestionsScroll(e,o){const t=getElement(e._viewContainer),n=t.getElementsByClassName("search-results")[0],i=t.getElementsByTagName("li"),s=i[o];if(0===o)return void(n.scrollTop=0);const r=s.offsetTop;r+s.clientHeight>n.clientHeight?n.scrollTop=r+s.clientHeight:r=5?t:e.geocode(o,GeocodeType.AUTOCOMPLETE).then((function(e){return t=t.concat(e),t}))}))})),t.then((function(o){const t=e._suggestions;for(let e=0;e