-
Notifications
You must be signed in to change notification settings - Fork 0
/
main-es2015.1d1ea700449735343db6.js.map
1 lines (1 loc) · 294 KB
/
main-es2015.1d1ea700449735343db6.js.map
1
{"version":3,"sources":["webpack:///src/app/components/side-bar/tag-images/form-generator/form-fields/form-dropdown/form-dropdown.component.html","webpack:///src/app/components/side-bar/select-image/select-image.component.html","webpack:///src/app/components/modal-file-browser/modal-file-browser.component.html","webpack:///src/app/components/side-bar/tag-images/form-generator/form-fields/form-file/form-file.component.scss","webpack:///src/app/components/side-bar/tag-images/form-generator/form-fields/form-file/form-file.component.html","webpack:///src/app/components/notfound/notfound.component.scss","webpack:///src/app/components/modal-download-selector/modal-download-selector.component.html","webpack:///src/app/components/main/main.component.scss","webpack:///src/app/components/main/main.component.html","webpack:///src/app/components/notfound/notfound.component.html","webpack:///src/app/components/modal-download-selector/modal-download-selector.component.scss","webpack:///src/app/components/side-bar/tag-images/form-generator/form-fields/form-color/form-color.component.scss","webpack:///src/app/components/side-bar/select-group/select-group.component.scss","webpack:///src/app/components/side-bar/side-bar.component.scss","webpack:///src/app/components/side-bar/tag-generator/tag-generator.component.html","webpack:///src/app/components/image-gallery/image-gallery.component.scss","webpack:///src/app/components/modal-share-project/modal-share-project.component.html","webpack:///src/app/components/image-gallery/image-gallery.component.html","webpack:///src/app/components/side-bar/tag-images/form-generator/form-fields/form-fields.component.html","webpack:///src/app/components/side-bar/select-image/select-image.component.scss","webpack:///src/app/app.component.html","webpack:///src/app/components/callback/callback.component.html","webpack:///src/app/components/image-box/image-box.component.html","webpack:///src/app/components/side-bar/side-bar.component.html","webpack:///src/$_lazy_route_resource lazy namespace object","webpack:///src/app/components/side-bar/tag-generator/tag-generator.component.scss","webpack:///src/app/components/side-bar/tag-images/form-generator/form-fields/form-textbox/form-textbox.component.html","webpack:///src/app/components/modal-share-project/modal-share-project.component.scss","webpack:///src/app/components/map/map.component.html","webpack:///src/app/components/side-bar/tag-images/form-generator/form-fields/form-radio/form-radio.component.html","webpack:///src/app/components/modal-create-project/modal-create-project.component.scss","webpack:///src/app/components/image-box/image-box.component.scss","webpack:///src/app/components/side-bar/tag-images/form-generator/form-generator.component.scss","webpack:///src/app/components/side-bar/tag-images/form-generator/form-fields/form-color/form-color.component.html","webpack:///src/app/components/modal-current-project/modal-current-project.component.html","webpack:///src/app/components/modal-create-project/modal-create-project.component.html","webpack:///src/app/components/map/map.component.scss","webpack:///src/app/components/side-bar/tag-images/tag-images.component.scss","webpack:///src/app/components/side-bar/select-group/select-group.component.html","webpack:///src/app/components/modal-current-project/modal-current-project.component.scss","webpack:///src/app/components/callback/callback.component.scss","webpack:///src/app/components/modal-file-browser/modal-file-browser.component.scss","webpack:///src/app/components/control-bar/control-bar.component.scss","webpack:///src/app/components/control-bar/control-bar.component.html","webpack:///src/app/components/side-bar/tag-images/form-generator/form-fields/form-checkbox/form-checkbox.component.html","webpack:///src/app/app.component.scss","webpack:///src/app/components/notfound/notfound.component.ts","webpack:///src/app/models/models.ts","webpack:///src/environments/environmentType.ts","webpack:///src/environments/environment.ts","webpack:///src/app/services/authentication.service.ts","webpack:///src/app/services/notifications.service.ts","webpack:///src/app/services/scroll.service.ts","webpack:///src/app/services/geo-data.service.ts","webpack:///src/app/utils/randomColor.ts","webpack:///src/app/components/main/main.component.ts","webpack:///src/app/components/callback/callback.component.ts","webpack:///src/app/services/forms.service.ts","webpack:///src/app/services/groups.service.ts","webpack:///src/app/services/projects.service.ts","webpack:///src/app/components/side-bar/tag-generator/tag-generator.component.ts","webpack:///src/app/components/side-bar/tag-images/tag-images.component.ts","webpack:///src/app/app-routing.module.ts","webpack:///src/app/app.component.ts","webpack:///src/app/utils/leafletUtils.ts","webpack:///src/app/components/map/map.component.ts","webpack:///src/app/services/agave-systems.service.ts","webpack:///src/app/services/tapis-files.service.ts","webpack:///src/app/components/modal-file-browser/modal-file-browser.component.ts","webpack:///src/app/components/modal-download-selector/modal-download-selector.component.ts","webpack:///src/app/components/modal-create-project/modal-create-project.component.ts","webpack:///src/app/components/modal-share-project/modal-share-project.component.ts","webpack:///src/app/components/modal-current-project/modal-current-project.component.ts","webpack:///src/app/services/feature.service.ts","webpack:///src/app/components/control-bar/control-bar.component.ts","webpack:///src/app/app.interceptors.ts","webpack:///src/app/components/image-gallery/image-gallery.component.ts","webpack:///src/app/components/image-box/image-box.component.ts","webpack:///src/app/components/side-bar/tag-images/form-generator/form-generator.component.ts","webpack:///src/app/components/side-bar/side-bar.component.ts","webpack:///src/app/utils/groups.ts","webpack:///src/app/components/side-bar/select-group/select-group.component.ts","webpack:///src/app/components/side-bar/select-image/select-image.component.ts","webpack:///src/app/components/side-bar/tag-images/form-generator/form-fields/form-fields.component.ts","webpack:///src/app/components/side-bar/tag-images/form-generator/form-fields/form-checkbox/form-checkbox.component.ts","webpack:///src/app/components/side-bar/tag-images/form-generator/form-fields/form-dropdown/form-dropdown.component.ts","webpack:///src/app/components/side-bar/tag-images/form-generator/form-fields/form-file/form-file.component.ts","webpack:///src/app/components/side-bar/tag-images/form-generator/form-fields/form-radio/form-radio.component.ts","webpack:///src/app/components/side-bar/tag-images/form-generator/form-fields/form-textbox/form-textbox.component.ts","webpack:///src/app/components/side-bar/tag-images/form-generator/form-fields/form-color/form-color.component.ts","webpack:///src/app/app.module.ts","webpack:///src/main.ts","webpack:///src/app/components/side-bar/tag-images/tag-images.component.html","webpack:///src/app/components/side-bar/tag-images/form-generator/form-generator.component.html"],"names":["__webpack_require__","r","__webpack_exports__","default","webpackEmptyAsyncContext","req","Promise","resolve","then","e","Error","code","keys","module","exports","id","NotFoundComponent","[object Object]","tslib_es6","a","Object","core","n","selector","template","b","GroupForm","AssetFilters","this","bbox","assetType","Set","has","delete","add","Project","ProjectRequest","AuthToken","token","expires","Date","expires_in","getTime","Feature","f","geometry","properties","taggit","groups","tags","type","assets","styles","project_id","length","initialAsset","asset_type","display_path","path","toString","exec","slice","EnvironmentType","Production","Staging","Local","environment","production","apiUrl","clientId","baseHref","backend","AuthenticatedUser","username","email","authentication_service_AuthService","http","router","_currentUser","ReplaySubject","currentUser","asObservable","LS_TOKEN_KEY","LS_USER_KEY","tokenStr","localStorage","getItem","JSON","parse","userToken","isExpired","logout","redirectToauthenticaor","getUserInfo","AUTH_URL","location","origin","Math","random","window","href","removeItem","fromExpiresIn","setItem","stringify","navigate","userStr","user","next","get","subscribe","resp","u","name","fesm2015_http","fesm2015_router","C","providedIn","notifications_service_NotificationsService","toastr","authService","TIMEOUT","_notifications","notifications","isLoggedIn","interval","getRecent","baseUrl","now","toISOString","notes","forEach","note","status","showSuccessToast","message","showErrorToast","success","error","ngx_toastr","ScrollService","scrollRestored","scrollPosition","change","document","documentElement","scrollTop","scroll","top","geo_data_service_GeoDataService","notificationsService","scrollService","_pointClouds","BehaviorSubject","pointClouds","_loaded","loaded","_loadingGallery","loadingGallery","_activeGroupId","activeGroupId","_activeGroup","activeGroup","_tagFeaturesQueue","tagFeaturesQueue","_loadingFeatureProperties","loadingFeatureProperties","_activeGroupFeature","activeGroupFeature","_groups","_groupsFeatures","groupsFeatures","_features","features","features$","_activeFeature","_mapMouseLocation","_basemap","_overlays","_activeOverlay","projectId","feature","fc","map","feat","getGroups","featureId","pipe","first","setFeatures","value","find","updateFeatureProperty","resetTagFeaturesQueue","query","restoreScroll","qstring","querystring","toJson","setScrollRestored","getFeatures","group","groupFeatures","some","gf","setActiveGroupFeature","updatedTag","tagFeatures","t","includes","push","take","current","title","conversionParams","payload","description","conversion_parameters","post","getPointClouds","groupData","setFeatureProperties","setFeatureStyles","pc","file","form","FormData","append","console","log","files","tmp","system","fileList","showImportErrorToast","remoteFile","system_id","response","importImage","downloadLink","createElement","blob","Blob","URL","createObjectURL","setAttribute","body","appendChild","click","removeChild","feats","addFeature","getValue","activeFeature","ovs","label","minLat","maxLat","minLon","maxLon","toFixed","getOverlays","featureList","Map","filter","set","setActiveGroup","groupName","grp","style","groupProp","getGroupFeatures","uuid","v4","myRandColor","color","i","floor","icon","faIcon","createGroupFeatures","createGroup","deleteGroup","updateGroup","renamedGroup","assign","updateGroupFeatures","reiconedGroup","reiconedStyle","overlays","activeOverlay","ov","mapMouseLocation","loc","basemap","bmap","MainComponent","geoDataService","bsModalService","ngx_foundation","c","CallbackComponent","route","auth","frag","snapshot","fragment","params","URLSearchParams","setToken","forms_service_FormsService","featureGroups","taggedGroup","forms","targetForm","newName","selectedColor","activeProject","tagValue","tagProp","tag","newValues","tagValueObj","featTag","groups_service_GroupsService","_selectedImages","selectedImages","_showTagger","showTagger","_showTagGenerator","showTagGenerator","_groupToAdd","undefined","groupToAdd","currentFeatures","newFeatures","imageSelected","projects_service_ProjectsService","_projects","projects","_activeProject","_projectUsers","projectUsers$","data","proj","deletable","setActiveProject","put","project","getProjects","tap","users","uname","getProjectUsers","TagGeneratorComponent","formsService","groupsService","dialog","projectsService","formOptions","optionColorFilter","openOption","enabledControls","showSubitem","formType","formName","formLabel","formValue","formRequired","event","target","formColor","opt","option","selectedGroup","open","toLowerCase","optionFilter","labelFilter","clearLabel","clearOptionColor","clearOption","formItem","options","myOpts","createForm","setShowTagGenerator","clear","esm2015_dialog","tag_images_component_TagImagesComponent","formList","tagName","tagValues","newTagValue","combineLatest","grpFts","grps","deleteForm","renameForm","closeAll","Activate","authSvc","state","login","routes","component","canActivate","children","canActivateChild","AppRoutingModule","K","imports","forRoot","onSameUrlNavigation","providers","AppComponent","createMarker","latlng","marker","featureType","ico","leaflet_src","divIcon","className","html","circleMarker","radius","fillColor","weight","opacity","fillOpacity","map_component_MapComponent","GeoDataService","mapType","FeatureGroup","featureClickHandler","bind","mouseEventHandler","center","zoom","baseOSM","tileLayer","maxZoom","attribution","satellite","addLayer","loadFeatures","on","ev","skip","addRemoveOverlay","turf_min","fitBounds","removeLayer","overlay","imageOverlay","getBounds","geojsonOptions","pointToLayer","collection","clearLayers","markers","markerClusterGroup","iconCreateFunction","cluster","getChildCount","d","geoJSON","layer","agave_systems_service_AgaveSystemsService","tapis","_systems","systems","systemsList","result","sys","startsWith","ng_tapis","tapis_files_service_TapisFilesService","popup","_listing","listing","IMPORTABLE_TYPES","ext","getFileExtension","split","pop","offset","limit","filesList","systemId","filePath","arr","replace","join","systemID","fileName","extension","snackbarConfig","duration","horizontalPosition","verticalPosition","fullURL","fileType","date","File","lastModified","valueOf","msg","sysStr","lastSystem","fileStr","lastFile","noPreviousSelections","snack_bar","modal_file_browser_component_ModalFileBrowserComponent","ModalFileBrowserComponent_1","tapisFilesService","dialogRef","agaveSystemsService","currentPath","w","allowedExtensions","inProgress","retrievalError","selectedFiles","onClose","Subject","list","myDataSystem","communityDataSystem","publishedDataSystem","selectedSystem","currentDirectory","init","browse","pth","selectedPath","getFiles","hasMoreFiles","listFiles","shift","getParentPath","unshift","newFile","allowedExt","index","concat","shiftKey","selectFilesShiftClick","checkIfSelectable","addSelectedFile","selectShift","firstFileIndex","saveState","Array","from","values","close","count","select","addRangeFiles","lastFileIndex","again","maxIndex","max","min","R","modal_download_selector_component_ModalDownloadSelectorComponent","ModalDownloadSelectorComponent_1","passbackData","fileExtension","downloadSelectForm","fesm2015_forms","Name","Extension","dirty","modal_create_project_component_ModalCreateProjectComponent","projCreateForm","projRqst","create","modal_share_project_component_ModalShareProjectComponent","projShareForm","activeProj","projectUsers","onlyOne","addUserToProject","deleteUserFromProject","modal_current_project_component_ModalCurrentProjectComponent","projData","confirm","p","update","B","args","feature_service_FeatureService","featureCollection","featListfeat","deleteFeature","delFeats","featListFeature","Number","featProp","saveFeature","control_bar_component_ControlBarComponent","cdr","filesService","featureService","LatLng","invalidNameError","existingNameError","foundFilePaths","getState","groupsExist","size","activeGroupFeatures","activeGroupFeaturesRotate","hasSuccessNotification","hasFailureNotification","selectedProject","item","substring","uploadNewFeature","createBlankFeature","lastProject","selectedLastProject","prj","getDataForProject","hazmapperLink","detectChanges","unselectAllImages","setGroupToAdd","afterClosed","importFileFromTapis","coordinates","saveFile","height","width","createNewGroup","setScrollPosition","initialGroupName","toggleTagger","featureShortPath","dir","exportFeatures","headerArray","ef","exportList","exportGroupObj","groupFeature","featureSource","featureObj","src","longitude","latitude","charAt","toUpperCase","v","isJSON","forExport","filename","content","export","download","csvFiles","exportItem","csvRows","headers","getCSVHeaders","header","zip","jszip_min","csv","generateAsync","url","navigator","userAgent","indexOf","visibility","revokeObjectURL","updateTagFeaturesQueue","k","app_interceptors_AuthInterceptor","request","handle","catchError","err","reload","statusText","throwError","app_interceptors_TokenInterceptor","clone","setHeaders","Authorization","X-JWT-Assertion-designsafe","jwt","image_gallery_component_ImageGalleryComponent","renderer","spinner","scrolling","imagesExist","scrollSum","projectsExist","featureListScroll","scrollStatus","hide","setTimeout","show","appendSum","Z","ngx_spinner","image_box_component_ImageBoxComponent","hasGroup","colors","featurePath","toggleImageSelect","deleteGroupFeatures","F","form_generator_component_FormGeneratorComponent","checked","colorArray","generateColors","itemCount","isOdd","incrementVal","temp","baseNum","SideBarComponent","groupIcons","unicode","select_group_component_SelectGroupComponent","iconList","selectedIcon","groups$","activeGroup$","reiconGroup","renameGroup","unsubscribe","SelectImageComponent","nextGroup","FormFieldsComponent","FormCheckBoxComponent","getTagValue","val","setTagFeaturesQueue","FormDropDownComponent","field","FormFileComponent","FormRadioComponent","String","FormTextBoxComponent","FormColorComponent","chosenColor","chosenTag","saveStyles","AppModule","declarations","progress_bar","rootUrl","platform_browser","animations","ngx_infinite_scroll","ngx_masonry","menu","toolbar","esm2015_button","tooltip","input","esm2015_checkbox","esm2015_select","esm2015_radio","j","dist","common","progress_spinner","tree","card","provide","multi","useClass","useValue","bootstrap","entryComponents","sb","platform_browser_dynamic","bootstrapModule","catch"],"mappings":"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","file":"main-es2015.1d1ea700449735343db6.js","sourcesContent":["export default \"<div>\\n <select\\n class=\\\"form-control\\\"\\n [(ngModel)]=\\\"value\\\"\\n id=\\\"field.name\\\"\\n name=\\\"field.name\\\"\\n (change)=\\\"updateCheckedTag()\\\"\\n >\\n <option *ngFor=\\\"let opt of field\\\" [value]=\\\"opt.label\\\">\\n {{ opt.label }}\\n </option>\\n </select>\\n</div>\\n\"","export default \"<div class=\\\"asset-list\\\">\\n <div class=\\\"subitem-title\\\" (click)=\\\"expandPanel()\\\">Image List</div>\\n\\n <div *ngIf=\\\"showSubitem\\\" class=\\\"subitem asset-subitem\\\">\\n <div\\n *ngFor=\\\"let feature of getActiveFeatures()\\\"\\n (click)=\\\"jumpToImage(feature)\\\"\\n class=\\\"asset-container\\\"\\n [ngClass]=\\\"{ highlight: isActiveFeature(feature) }\\\"\\n >\\n <div class=\\\"name-group\\\">\\n {{ getFeaturePath(feature) }}\\n </div>\\n\\n <div class=\\\"button-group\\\">\\n <div (click)=\\\"deleteFeature(feature)\\\">\\n <i\\n class=\\\"fas fa-minus\\\"\\n matTooltip=\\\"Delete\\\"\\n matTooltipPosition=\\\"above\\\"\\n >\\n </i>\\n </div>\\n </div>\\n </div>\\n </div>\\n</div>\\n\"","export default \"<h4>Select Files</h4>\\n<small\\n ><em>\\n Note: Only files are selectable, not folders. Double click on a folder to\\n navigate into it.\\n </em></small\\n>\\n<hr />\\n<select (ngModelChange)=\\\"selectSystem($event)\\\" [(ngModel)]=\\\"selectedSystem\\\">\\n <option [ngValue]=\\\"myDataSystem\\\">My Data</option>\\n <option [ngValue]=\\\"communityDataSystem\\\">Community Data</option>\\n <option [ngValue]=\\\"publishedDataSystem\\\">Published Data</option>\\n <optgroup label=\\\"My Projects\\\">\\n <option *ngFor=\\\"let project of projects\\\" [ngValue]=\\\"project\\\">\\n {{ project.description }}\\n </option>\\n </optgroup>\\n</select>\\n\\n<div\\n class=\\\"fileslisting\\\"\\n infiniteScroll\\n [infiniteScrollDistance]=\\\"2\\\"\\n [infiniteScrollThrottle]=\\\"100\\\"\\n [scrollWindow]=\\\"false\\\"\\n (scrolled)=\\\"getFiles()\\\"\\n>\\n <div class=\\\"clickable\\\" class=\\\"grid-x file-row\\\" (dblclick)=\\\"toRoot()\\\">\\n <i class=\\\"fas fa-folder\\\"></i>\\n <span> Home </span>\\n </div>\\n <div class=\\\"clickable\\\" class=\\\"grid-x file-row\\\">\\n <i class=\\\"fas fa-folder-open\\\"></i>\\n <span class=\\\"lineBreak\\\"> {{ selectedPath }} </span>\\n </div>\\n <div *ngIf=\\\"retrievalError\\\" class=\\\"grid-x file-row\\\" class=\\\"error\\\">\\n Error retrieving files\\n </div>\\n <div\\n class=\\\"grid-x file-row\\\"\\n *ngFor=\\\"let file of filesList; let fileIndex = index\\\"\\n [ngClass]=\\\"{ selected: selectedFiles.has(file.path) }\\\"\\n >\\n <div\\n class=\\\"clickable\\\"\\n (click)=\\\"select($event, file, fileIndex)\\\"\\n (dblclick)=\\\"browse(file)\\\"\\n >\\n <i class=\\\"fas fa-folder\\\" *ngIf=\\\"file.type === 'dir'\\\"></i>\\n <i class=\\\"far fa-file\\\" *ngIf=\\\"file.type !== 'dir'\\\"></i>\\n <span> {{ file.name }} </span>\\n </div>\\n <div class=\\\"size\\\">\\n {{ file.length | filesize }}\\n </div>\\n </div>\\n <div class=\\\"grid-x\\\" *ngIf=\\\"inProgress\\\">\\n <div class=\\\"cell medium-12\\\">\\n <i class=\\\"fas fa-spin fa-atom\\\"></i>\\n </div>\\n </div>\\n</div>\\n\\n<div class=\\\"button-group\\\">\\n <button mat-raised-button color=\\\"basic\\\" (click)=\\\"selectAll()\\\">\\n Select all\\n </button>\\n <button\\n mat-raised-button\\n color=\\\"warn\\\"\\n class=\\\"button warning\\\"\\n (click)=\\\"cancel()\\\"\\n >\\n Done\\n </button>\\n <button\\n mat-raised-button\\n color=\\\"primary\\\"\\n class=\\\"button\\\"\\n [disabled]=\\\"!selectedFiles.size\\\"\\n (click)=\\\"chooseFiles()\\\"\\n >\\n Import\\n </button>\\n</div>\\n\"","export default \":host .drop-container {\\n background: #fff;\\n border-radius: 6px;\\n height: 150px;\\n width: 100%;\\n box-shadow: 1px 2px 20px rgba(10, 10, 10, 0.1);\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n border: 2px dashed #c0c4c7;\\n}\\n:host p {\\n font-size: 16px;\\n font-weight: 400;\\n color: #c0c4c7;\\n}\\n:host .upload-button {\\n display: inline-block;\\n border: none;\\n outline: none;\\n cursor: pointer;\\n color: #5754a3;\\n}\\n:host .upload-button input {\\n display: none;\\n}\\n:host .dropzone {\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n flex-direction: column;\\n border-radius: 5px;\\n background: white;\\n margin: 10px 0;\\n}\\n:host .dropzone.hovering {\\n border: 2px solid #f16624;\\n color: #dadada !important;\\n}\\n:host progress::-webkit-progress-value {\\n transition: width 0.1s ease;\\n}\"","export default \"<div [formGroup]=\\\"form\\\">\\n <div\\n *ngIf=\\\"!field.value\\\"\\n class=\\\"drop-container dropzone\\\"\\n dropZone\\n (hovered)=\\\"toggleHover($event)\\\"\\n (dropped)=\\\"field.onUpload($event)\\\"\\n [class.hovering]=\\\"isHovering\\\"\\n >\\n <p class=\\\"m-0\\\">\\n Drag a file here or\\n <label class=\\\"upload-button\\\">\\n <input\\n type=\\\"file\\\"\\n multiple=\\\"\\\"\\n (change)=\\\"field.onUpload($event.target.files)\\\"\\n />\\n browse\\n </label>\\n to upload.\\n </p>\\n </div>\\n <div *ngIf=\\\"field.value\\\">\\n <!-- <button type=\\\"button\\\" class=\\\"btn btn-primary\\\">Change</button> -->\\n <div class=\\\"card\\\">\\n <img class=\\\"card-img-top\\\" [src]=\\\"field.value\\\" />\\n </div>\\n </div>\\n</div>\\n\"","export default \"\"","export default \"<h4>Select Files</h4>\\n<small\\n ><em>\\n If no folder is selected, the file will be saved in the root of your\\n selected system.\\n </em></small\\n>\\n<hr />\\n<select (ngModelChange)=\\\"selectSystem($event)\\\" [(ngModel)]=\\\"selectedSystem\\\">\\n <option [ngValue]=\\\"myDataSystem\\\">My Data</option>\\n <option [ngValue]=\\\"communityDataSystem\\\">Community Data</option>\\n <option [ngValue]=\\\"publishedDataSystem\\\">Published Data</option>\\n <optgroup label=\\\"My Galleries\\\">\\n <option *ngFor=\\\"let project of projects\\\" [ngValue]=\\\"project\\\">\\n {{ project.description }}\\n </option>\\n </optgroup>\\n</select>\\n<div\\n class=\\\"fileslisting\\\"\\n infiniteScroll\\n [infiniteScrollDistance]=\\\"2\\\"\\n [infiniteScrollThrottle]=\\\"100\\\"\\n [scrollWindow]=\\\"false\\\"\\n (scrolled)=\\\"getFiles()\\\"\\n>\\n <div\\n class=\\\"grid-x file-row\\\"\\n *ngFor=\\\"let file of filesList\\\"\\n [ngClass]=\\\"{ selected: selectedFiles.has(file.path) }\\\"\\n >\\n <div class=\\\"clickable\\\" (dblclick)=\\\"browse(file)\\\">\\n <i class=\\\"fas fa-folder\\\" *ngIf=\\\"file.type === 'dir'\\\"></i>\\n <i class=\\\"far fa-file\\\" *ngIf=\\\"file.type !== 'dir'\\\"></i>\\n <span> {{ file.name }} </span>\\n </div>\\n <div class=\\\"size\\\">\\n {{ file.length | filesize }}\\n </div>\\n </div>\\n <div class=\\\"grid-x\\\" *ngIf=\\\"inProgress\\\">\\n <div class=\\\"cell medium-12\\\">\\n <i class=\\\"fas fa-spin fa-atom\\\"></i>\\n </div>\\n </div>\\n</div>\\n\\n<form\\n [formGroup]=\\\"downloadSelectForm\\\"\\n (ngSubmit)=\\\"update()\\\"\\n id=\\\"current-project-form\\\"\\n>\\n <div>\\n <small\\n ><em>\\n If no filename is specified, it will default to the Gallery/Map ID number.\\n </em></small\\n >\\n </div>\\n\\n <mat-form-field>\\n <input\\n matInput\\n type=\\\"text\\\"\\n formControlName=\\\"Name\\\"\\n appearance=\\\"filled\\\"\\n required=\\\"false\\\"\\n />\\n </mat-form-field>\\n</form>\\n<span class=\\\"radio-box\\\">\\n <mat-radio-group [(ngModel)]=\\\"fileExtension\\\">\\n <mat-radio-button value=\\\".csv\\\">.csv</mat-radio-button>\\n <mat-radio-button value=\\\".json\\\">.json</mat-radio-button>\\n </mat-radio-group>\\n</span>\\n\\n<div class=\\\"button-group\\\">\\n <button\\n mat-raised-button\\n color=\\\"warn\\\"\\n class=\\\"button warning\\\"\\n (click)=\\\"cancel()\\\"\\n >\\n Cancel\\n </button>\\n <button\\n mat-raised-button\\n color=\\\"primary\\\"\\n class=\\\"button\\\"\\n (click)=\\\"chooseFiles()\\\"\\n >\\n Save\\n </button>\\n</div>\\n\"","export default \":host .top-bar {\\n height: 40px;\\n padding: 5px;\\n padding-left: 0.5em;\\n flex-wrap: nowrap;\\n position: fixed;\\n overflow: hidden;\\n width: 100%;\\n z-index: 999;\\n}\\n:host .top-bar-right .top-bar-left {\\n -webkit-box-flex: 0;\\n flex-wrap: nowrap;\\n flex: 0 1 auto;\\n max-width: 100%;\\n}\\n@media print, screen and (min-width: 40em) {\\n :host .top-bar {\\n flex-wrap: nowrap;\\n flex: 0 1 auto;\\n }\\n}\"","export default \"<!-- <div class=\\\"grid-x\\\"> -->\\n\\n<!-- <div class=\\\"top-bar\\\" style=\\\"background-color: black\\\" id=\\\"navbar\\\"> -->\\n\\n<!--\\t<div class=\\\"top-bar-left\\\"> -->\\n<!--\\t <img src=\\\"assets/logo.svg\\\" width=\\\"30PX\\\"> -->\\n<!--\\t <span style=\\\"color: white\\\">Taggit</span> -->\\n<!--\\t</div> -->\\n\\n<!--\\t<div class=\\\"top-bar-right\\\"> -->\\n<!--\\t <div class=\\\"light-blue\\\" *ngIf=\\\"currentUser\\\">{{ currentUser.username }}</div> -->\\n<!--\\t</div> -->\\n\\n<!-- </div> -->\\n\\n<!-- <\\\\!-- <div class=\\\"cell control-bar\\\"> -\\\\-> -->\\n<!-- <\\\\!--\\t<app-control-bar></app-control-bar> -\\\\-> -->\\n<!-- <\\\\!-- </div> -\\\\-> -->\\n<!-- </div> -->\\n\\n<app-control-bar></app-control-bar>\\n<!-- NOTE Router Outlet was here -->\\n<app-image-gallery></app-image-gallery>\\n\\n<!-- NOTE Leaflet was here -->\\n\"","export default \"<p>notfound works!</p>\\n\"","export default \":host {\\n min-height: 20em;\\n}\\n:host .fileslisting {\\n height: 20em;\\n overflow-y: scroll;\\n padding: 0px 20px;\\n}\\n:host .file-row {\\n display: flex;\\n background: #f9f9f9;\\n border: 1px solid transparent;\\n user-select: none;\\n -webkit-user-select: none;\\n -moz-user-select: none;\\n}\\n:host .clickable {\\n flex: 1;\\n max-width: 20em;\\n}\\n:host .size {\\n align-items: flex-end;\\n}\\n:host .file-row:hover {\\n border: 1px solid;\\n}\\n:host .file-row.selected {\\n background: #d3d3d3;\\n}\\n:host .mat-radio-button ~ .mat-radio-button {\\n margin-left: 16px;\\n}\\n:host .radio-box {\\n position: relative;\\n bottom: 45px;\\n left: 45%;\\n}\"","export default \"\"","export default \":host {\\n overflow-y: scroll;\\n}\\n:host .select-group {\\n overflow: hidden;\\n max-height: 20%;\\n}\\n:host .subitem-title {\\n text-align: left;\\n color: #555;\\n font-size: 14px;\\n padding: 10px;\\n background-color: #f1f1f1;\\n display: flex;\\n justify-content: space-between;\\n}\\n:host .subitem {\\n border-width: 0px 10px;\\n border-color: #f1f1f1;\\n border-style: solid;\\n overflow-y: scroll;\\n background-color: #ffffff;\\n height: 100%;\\n}\\n:host .group-subitem {\\n height: 100px;\\n}\\n:host .subitem-scroll {\\n border-width: 5px;\\n}\\n:host .boxed input[type=radio] {\\n display: none;\\n}\\n:host .boxed label {\\n background-color: #fff;\\n transition: all 0.3s;\\n}\\n:host .boxed input[type=radio]:checked + label {\\n background-color: #b3e5ff;\\n}\\n:host .group-container {\\n display: flex;\\n flex-direction: row;\\n margin: 0;\\n justify-content: space-between;\\n}\\n:host .name-group {\\n display: inline-block;\\n padding: 3px;\\n}\\n:host .button-group {\\n margin: 0;\\n display: flex;\\n flex-direction: row;\\n}\\n:host .button-group div {\\n padding: 3px;\\n}\\n:host .fa {\\n font-weight: 900;\\n display: inline-block;\\n font-style: normal;\\n font-variant: normal;\\n text-rendering: auto;\\n font-family: \\\"FontAwesome\\\";\\n line-height: 1;\\n}\\n:host .fa option {\\n font-weight: 900;\\n}\"","export default \":host {\\n background-color: #f1f1f1;\\n}\"","export default \"<div class=\\\"create-prompt\\\">\\n <div class=\\\"subitem-title\\\" (click)=\\\"expandPanel()\\\">\\n <span> Create Tag </span>\\n </div>\\n <!-- subitem-title -->\\n\\n <div *ngIf=\\\"showSubitem\\\" class=\\\"subitem\\\">\\n <form class=\\\"form-type-form\\\">\\n <div\\n *ngFor=\\\"let control of enabledControls; let idx = index\\\"\\n class=\\\"box form\\\"\\n >\\n <input\\n type=\\\"radio\\\"\\n [id]=\\\"control\\\"\\n value=\\\"control.toLowerCase()\\\"\\n name=\\\"form-type\\\"\\n [checked]=\\\"idx === 0\\\"\\n (change)=\\\"selectInputForm(control.toLowerCase())\\\"\\n />\\n <label\\n style=\\\"cursor: pointer; margin: 3px; padding: 3px; font-size: 10px\\\"\\n [for]=\\\"control\\\"\\n >{{ control }}</label\\n >\\n </div>\\n <!-- form-type-form -->\\n </form>\\n\\n <div class=\\\"form-name\\\">\\n <mat-form-field class=\\\"input-label-group\\\">\\n <mat-label>Label</mat-label>\\n <input\\n matInput\\n placeholder=\\\"Label\\\"\\n #labelValue\\n [(ngModel)]=\\\"labelFilter\\\"\\n (keyup)=\\\"inputFormLabel($event)\\\"\\n name=\\\"labelFilter\\\"\\n class=\\\"tiny\\\"\\n type=\\\"text\\\"\\n />\\n </mat-form-field>\\n\\n <ng-container *ngIf=\\\"formType != 'text'\\\">\\n <ng-container *ngIf=\\\"formType == 'color'\\\">\\n <mat-form-field class=\\\"input-label-group\\\">\\n <mat-label>Option Color</mat-label>\\n <input\\n matInput\\n #optionColorValue\\n placeholder=\\\"Option Color\\\"\\n #labelValue\\n [(ngModel)]=\\\"optionColorFilter\\\"\\n (change)=\\\"inputFormColor($event)\\\"\\n name=\\\"optionColorilter\\\"\\n class=\\\"tiny\\\"\\n type=\\\"color\\\"\\n />\\n </mat-form-field>\\n </ng-container>\\n\\n <mat-form-field class=\\\"input-label-group\\\">\\n <mat-label>Options</mat-label>\\n <div class=\\\"input-group\\\">\\n <input\\n matInput\\n #optionValue\\n class=\\\"input-group-field\\\"\\n placeholder=\\\"Option\\\"\\n type=\\\"text\\\"\\n [(ngModel)]=\\\"optionFilter\\\"\\n name=\\\"optionFilter\\\"\\n (keyup.enter)=\\\"\\n addOptionItem(optionValue.value);\\n optionValue.value = '';\\n optionColorValue.value = '';\\n clearOption();\\n clearOptionColor()\\n \\\"\\n />\\n </div>\\n <!-- input-group -->\\n </mat-form-field>\\n\\n <div class=\\\"input-group-button\\\">\\n <button\\n mat-button\\n color=\\\"accent\\\"\\n class=\\\"button\\\"\\n (click)=\\\"\\n addOptionItem(optionValue.value);\\n optionValue.value = '';\\n clearOption()\\n \\\"\\n >\\n <i class=\\\"fas fa-plus\\\"></i>\\n </button>\\n </div>\\n <!-- input-group-button -->\\n\\n <ul class=\\\"form-option-container\\\">\\n <li *ngFor=\\\"let opt of formOptions\\\" class=\\\"list-group\\\">\\n <div>\\n {{ opt.label }}\\n <ng-container *ngIf=\\\"formType == 'color'\\\">\\n <svg class=\\\"box\\\" width=\\\"10px\\\" height=\\\"10px\\\">\\n <rect width=\\\"10px\\\" height=\\\"10px\\\" style=\\\"fill: #ffffff\\\" />\\n <rect\\n width=\\\"8px\\\"\\n height=\\\"8px\\\"\\n x=\\\"1px\\\"\\n y=\\\"1px\\\"\\n [style.fill]=\\\"opt.color\\\"\\n />\\n </svg>\\n </ng-container>\\n </div>\\n <!-- showopt -->\\n <div class=\\\"button-group\\\">\\n <div (click)=\\\"deleteOption(opt)\\\">\\n <i\\n class=\\\"fas fa-minus\\\"\\n matTooltip=\\\"Delete\\\"\\n matTooltipPosition=\\\"above\\\"\\n style=\\\"cursor: pointer\\\"\\n >\\n </i>\\n </div>\\n <!-- delete opt -->\\n\\n <div (click)=\\\"openRenameOptionModal(renameOptionModal)\\\">\\n <i\\n class=\\\"fas fa-edit\\\"\\n style=\\\"cursor: pointer\\\"\\n matTooltip=\\\"Rename\\\"\\n matTooltipPosition=\\\"above\\\"\\n >\\n </i>\\n </div>\\n\\n <ng-template #renameOptionModal>\\n <input matInput #optionRename placeholder=\\\"Rename Option\\\" />\\n <br />\\n <br />\\n <div class=\\\"button-group\\\">\\n <button\\n matDialogClose\\n mat-raised-button\\n color=\\\"primary\\\"\\n (click)=\\\"renameOption(opt, optionRename.value)\\\"\\n >\\n Rename\\n </button>\\n <button matDialogClose mat-button>Cancel</button>\\n </div>\\n </ng-template>\\n </div>\\n <!-- button group -->\\n </li>\\n </ul>\\n </ng-container>\\n </div>\\n <!-- form-name -->\\n\\n <button mat-raised-button color=\\\"primary\\\" (click)=\\\"addFormItem()\\\">\\n Save\\n </button>\\n <button mat-button color=\\\"primary\\\" (click)=\\\"cancelCreate()\\\">Cancel</button>\\n </div>\\n <!-- subitem -->\\n</div>\\n<!-- create-group -->\\n\"","export default \":host .img-list-container {\\n display: grid;\\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\\n grid-gap: 1em;\\n height: 100%;\\n padding: 1em;\\n}\\n:host #no-img {\\n font-size: 32px;\\n display: flex;\\n justify-content: center;\\n align-items: center;\\n height: 70vh;\\n}\\n:host #no-proj {\\n font-size: 32px;\\n display: flex;\\n justify-content: center;\\n align-items: center;\\n height: 70vh;\\n}\\n:host #new-proj {\\n font-size: 32px;\\n display: flex;\\n height: 100vh;\\n justify-content: center;\\n align-items: center;\\n}\\n:host app-image-box {\\n height: 100%;\\n}\\n:host .masonry-item {\\n width: 200px;\\n}\\n:host img-spin {\\n position: relative;\\n bottom: 0px;\\n left: 0px;\\n width: 100%;\\n height: 100px;\\n background: #fff;\\n}\\n:host load-spin {\\n position: relative;\\n width: 100%;\\n height: 100px;\\n background: #fff;\\n}\\n:host .side-bar-container {\\n background-color: #f1f1f1;\\n position: fixed;\\n width: 25%;\\n margin-right: 0px;\\n height: calc(100vh - 50px);\\n right: 0;\\n}\\n:host .success {\\n margin-right: 20%;\\n}\\n:host .danger {\\n margin-right: 0%;\\n}\\n:host #gallery-container-container {\\n position: relative;\\n width: 100%;\\n height: auto;\\n text-align: center;\\n display: flex;\\n flex-direction: column;\\n margin-top: 0px;\\n}\\n:host #loading-load {\\n position: relative;\\n width: 100%;\\n height: auto;\\n text-align: center;\\n flex-direction: column;\\n margin-top: 50px;\\n}\\n:host #gallery-container {\\n position: relative;\\n width: 100%;\\n height: auto;\\n text-align: center;\\n display: flex;\\n flex-direction: column;\\n}\\n:host #gallery-container .gallery-image {\\n height: 100%;\\n display: inline-flex;\\n justify-content: center;\\n align-items: center;\\n}\\n:host #gallery-container .gallery-image img {\\n max-width: 100%;\\n max-height: 100%;\\n margin: 0 auto;\\n}\\n:host .imager {\\n width: 75%;\\n height: calc(100vh - 50px);\\n background-color: #fefefe;\\n}\\n:host .view-image {\\n max-width: 100%;\\n height: auto;\\n}\\n:host .gallery-btn {\\n width: 35px;\\n height: 35px;\\n background: #000;\\n color: #fff;\\n text-align: center;\\n line-height: 35px;\\n cursor: pointer;\\n transition: all 0.4s ease;\\n font-size: 20px;\\n box-sizing: border-box;\\n padding-left: 2px;\\n position: fixed;\\n bottom: 10px;\\n}\\n:host .gallery-btn:hover {\\n background: #222;\\n}\\n:host .gallery-close {\\n top: 10px;\\n}\\n:host .gallery-close .gallery-next {\\n right: 10px;\\n}\\n:host .gallery-prev {\\n right: 50px;\\n}\\n:host .gallery-prev .gallery-next {\\n bottom: 10px;\\n}\\n@media (min-width: 478px) {\\n :host .img-list-container img:nth-child(3n):not(last-of-type) {\\n grid-row-end: span 2;\\n }\\n}\\n@media (max-width: 768px) {\\n :host .img-list-container {\\n grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));\\n }\\n}\\n@media (max-width: 450px) {\\n :host .img-list-container {\\n grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));\\n }\\n}\"","export default \"<h4>Share this project</h4>\\n<small\\n ><em>\\n People you share your project with will have full ability to edit and delete\\n this project on Taggit and on HazMapper.\\n </em></small\\n>\\n\\n<form [formGroup]=\\\"projShareForm\\\" (ngSubmit)=\\\"submit()\\\" id=\\\"share-project-form\\\">\\n <mat-form-field>\\n <mat-label>Username:</mat-label>\\n <input matInput type=\\\"text\\\" formControlName=\\\"name\\\" required=\\\"true\\\" />\\n </mat-form-field>\\n\\n <div class=\\\"button-group small\\\">\\n <button\\n mat-raised-button\\n color=\\\"warn\\\"\\n class=\\\"button small warning\\\"\\n type=\\\"button\\\"\\n (click)=\\\"close()\\\"\\n >\\n Close\\n </button>\\n <button\\n mat-raised-button\\n color=\\\"primary\\\"\\n class=\\\"button small align-right\\\"\\n type=\\\"submit\\\"\\n [disabled]=\\\"!projShareForm.valid\\\"\\n >\\n Add Member\\n </button>\\n </div>\\n\\n <br />\\n <h5>Current Users</h5>\\n <div *ngFor=\\\"let user of projectUsers\\\">\\n <br />\\n <mat-card class=\\\"card-container\\\">\\n <span class=\\\"card-item\\\">\\n {{ user.username }}\\n </span>\\n <span class=\\\"card-buttons\\\">\\n <button\\n mat-raised-button\\n color=\\\"warn\\\"\\n class=\\\"button small warning\\\"\\n type=\\\"button\\\"\\n [disabled]=\\\"onlyOne\\\"\\n (click)=\\\"delete(user.username)\\\"\\n >\\n <i class=\\\"fas fa-trash\\\"></i>\\n </button>\\n </span>\\n </mat-card>\\n </div>\\n</form>\\n\"","export default \"<div *ngIf=\\\"loaded; else loader\\\" id=\\\"loading-load\\\">\\n <div *ngIf=\\\"projectsExist; else noProjWarn\\\" id=\\\"gallery-container\\\">\\n\\n <div *ngIf=\\\"loadingGallery; else galleryLoader\\\">\\n <div *ngIf=\\\"imagesExist; else noImgWarn\\\" id=\\\"gallery-container-container\\\">\\n <div\\n [ngClass]=\\\"scrollStatus\\\"\\n infiniteScroll\\n [infiniteScrollDistance]=\\\"1\\\"\\n [infiniteScrollThrottle]=\\\"1500\\\"\\n (scrolled)=\\\"onScroll()\\\"\\n class=\\\"img-list-container\\\"\\n *ngIf=\\\"!showTagger; else tagger\\\"\\n >\\n <app-image-box *ngFor=\\\"let feat of featureListScroll\\\" [feature]=\\\"feat\\\">\\n </app-image-box>\\n </div>\\n\\n <ngx-spinner\\n bdOpacity=\\\"0.9\\\"\\n bdColor=\\\"\\\"\\n size=\\\"default\\\"\\n color=\\\"#3ADB76\\\"\\n type=\\\"line-scale-pulse-out\\\"\\n id=\\\"img-spin\\\"\\n [fullScreen]=\\\"false\\\"\\n >\\n </ngx-spinner>\\n <ng-template #tagger>\\n <div>\\n <div class=\\\"imager\\\">\\n <img class=\\\"view-image\\\" [src]=\\\"getPath()\\\" />\\n </div>\\n </div>\\n </ng-template>\\n <div *ngIf=\\\"showTagger\\\" class=\\\"side-bar-container\\\">\\n <app-side-bar></app-side-bar>\\n </div>\\n </div>\\n </div>\\n\\n <ng-template #galleryLoader>\\n <div id=\\\"no-img\\\">\\n <i class=\\\"fas fa-circle-notch fa-spin\\\"></i>\\n </div>\\n </ng-template>\\n\\n <ng-template #noImgWarn>\\n <div id=\\\"no-img\\\">\\n No images have been imported!<br />Please import images through the\\n menu.\\n </div>\\n </ng-template>\\n </div>\\n\\n <ng-template #noProjWarn>\\n <div id=\\\"no-proj\\\">\\n No project has been created!<br />Please create a project through the\\n menu.\\n </div>\\n </ng-template>\\n</div>\\n\\n<ng-template #loader>\\n <div *ngIf=\\\"projectsExist; else createProj\\\" id=\\\"loader\\\">Loading...</div>\\n\\n <ng-template #createProj>\\n <div id=\\\"new-proj\\\" (click)=\\\"openCreateProjectModal()\\\">\\n Start a new project\\n </div>\\n </ng-template>\\n</ng-template>\\n\"","export default \"<div class=\\\"form-group row\\\" *ngFor=\\\"let tag of field\\\">\\n <label class=\\\"col-md-3 form-control-label\\\" [attr.for]=\\\"tag.label\\\">\\n {{ field.label }}\\n <strong class=\\\"text-danger\\\" *ngIf=\\\"tag.required\\\">*</strong>\\n </label>\\n <div class=\\\"col-md-9\\\" [ngSwitch]=\\\"tag.type\\\">\\n <app-form-color\\n *ngSwitchCase=\\\"'color'\\\"\\n [field]=\\\"field\\\"\\n [form]=\\\"form\\\"\\n ></app-form-color>\\n <app-form-textbox\\n *ngSwitchCase=\\\"'text'\\\"\\n [field]=\\\"field\\\"\\n [form]=\\\"form\\\"\\n ></app-form-textbox>\\n <app-form-dropdown\\n *ngSwitchCase=\\\"'dropdown'\\\"\\n [field]=\\\"field\\\"\\n [form]=\\\"form\\\"\\n ></app-form-dropdown>\\n <app-form-checkbox\\n *ngSwitchCase=\\\"'checkbox'\\\"\\n [field]=\\\"field\\\"\\n [form]=\\\"form\\\"\\n ></app-form-checkbox>\\n <app-form-radio\\n *ngSwitchCase=\\\"'radio'\\\"\\n [field]=\\\"field\\\"\\n [form]=\\\"form\\\"\\n ></app-form-radio>\\n </div>\\n</div>\\n\"","export default \":host .subitem-title {\\n text-align: left;\\n color: #555;\\n font-size: 14px;\\n padding: 10px;\\n background-color: #f1f1f1;\\n display: flex;\\n justify-content: space-between;\\n}\\n:host .subitem {\\n border-width: 0px 10px;\\n border-color: #f1f1f1;\\n border-style: solid;\\n overflow-y: scroll;\\n background-color: #ffffff;\\n height: 100%;\\n}\\n:host .subitem-scroll {\\n border-width: 5px;\\n}\\n:host .asset-list {\\n max-height: 20%;\\n overflow: hidden;\\n}\\n:host .asset-subitem {\\n height: 100px;\\n}\\n:host .asset-container {\\n display: flex;\\n flex-direction: row;\\n justify-content: space-between;\\n cursor: pointer;\\n}\\n:host .highlight {\\n background-color: #b3e5ff;\\n}\\n:host .name-group {\\n display: inline-block;\\n padding: 3px;\\n}\\n:host .button-group {\\n margin: 0;\\n display: flex;\\n flex-direction: row;\\n}\\n:host .button-group div {\\n padding: 3px;\\n padding-right: 5px;\\n}\"","export default \"<!--The content below is only a placeholder and can be replaced.-->\\n<router-outlet></router-outlet>\\n\"","export default \"<div id=\\\"callback\\\">\\n <div>\\n <i class=\\\"fas fa-spinner\\\"></i>\\n </div>\\n</div>\\n\"","export default \"<div class=\\\"img-container\\\">\\n <img\\n [ngClass]=\\\"imageSelected\\\"\\n [src]=\\\"featureSource\\\"\\n (click)=\\\"imageSelect()\\\"\\n class=\\\"img-responsive img-target\\\"\\n title=\\\"{{ featurePath }}\\\"\\n />\\n <div class=\\\"top-overlay\\\">\\n <div\\n class=\\\"image-option\\\"\\n matTooltip=\\\"Zoom\\\"\\n matTooltipPosition=\\\"below\\\"\\n (click)=\\\"imageZoom(diffSizes)\\\"\\n >\\n <i class=\\\"fas fa-search-plus\\\"></i>\\n </div>\\n\\n <ng-template #diffSizes>\\n <div class=\\\"zoom-content\\\">\\n <div class=\\\"img-container\\\">\\n <img [src]=\\\"featureSource\\\" title=\\\"{{ featurePath }}\\\" />\\n </div>\\n <div class=\\\"img-details\\\">\\n <div class=\\\"detail-container\\\">\\n <div class=\\\"title\\\">Coordinates</div>\\n <div class=\\\"detail-contents\\\">\\n <div class=\\\"detail-item\\\">{{ coordinates[0] }},</div>\\n <div class=\\\"detail-item\\\">\\n {{ coordinates[1] }}\\n </div>\\n </div>\\n </div>\\n <div class=\\\"detail-container\\\">\\n <div class=\\\"title\\\">Image Source</div>\\n <div class=\\\"detail-contents\\\">\\n <div class=\\\"detail-item\\\">\\n {{ featurePath }}\\n </div>\\n </div>\\n </div>\\n </div>\\n <button\\n mat-button\\n class=\\\"close-button\\\"\\n matDialogClose\\n aria-label=\\\"Close modal\\\"\\n type=\\\"button\\\"\\n >\\n <span aria-hidden=\\\"true\\\">×</span>\\n </button>\\n </div>\\n </ng-template>\\n\\n <div\\n class=\\\"image-option\\\"\\n matTooltip=\\\"Remove\\\"\\n matTooltipPosition=\\\"below\\\"\\n (click)=\\\"openPreserveScrollModal(deleteImage)\\\"\\n >\\n <i class=\\\"fas fa-trash\\\"></i>\\n </div>\\n\\n <ng-template #deleteImage>\\n <div *ngIf=\\\"selectedImages.length === 1\\\">\\n This image will be deleted from the current project. It will not be\\n deleted from the Data Depot.\\n </div>\\n\\n <div *ngIf=\\\"selectedImages.length > 1\\\">\\n {{ selectedImages.length }} images will be deleted from the current\\n project. They will not be deleted from the Data Depot.\\n </div>\\n\\n <button\\n mat-raised-button\\n color=\\\"primary\\\"\\n matDialogClose\\n (click)=\\\"imageDelete()\\\"\\n >\\n Delete Image\\n </button>\\n <button mat-button matDialogClose>Cancel</button>\\n </ng-template>\\n\\n <div\\n class=\\\"image-option\\\"\\n matTooltip=\\\"Add To Group\\\"\\n matTooltipPosition=\\\"below\\\"\\n (click)=\\\"openPreserveScrollModal(addMoreToGroup)\\\"\\n >\\n <i class=\\\"fas fa-plus\\\"></i>\\n </div>\\n\\n <ng-template #addMoreToGroup>\\n <mat-form-field appearance=\\\"fill\\\">\\n <mat-label>Groups</mat-label>\\n <mat-select\\n matNativeControl\\n required\\n [value]=\\\"groupToAdd\\\"\\n [compareWith]=\\\"compareGroup\\\"\\n (selectionChange)=\\\"changeGroupToAdd($event)\\\"\\n >\\n <mat-option\\n *ngFor=\\\"let group of groups | keyvalue\\\"\\n [value]=\\\"group.value\\\"\\n >\\n {{ group.key }}\\n </mat-option>\\n </mat-select>\\n </mat-form-field>\\n\\n <p>\\n <button\\n mat-raised-button\\n color=\\\"primary\\\"\\n matDialogClose\\n (click)=\\\"addGroup(groupToAdd)\\\"\\n [disabled]=\\\"!groupToAdd\\\"\\n >\\n Add To Group\\n </button>\\n <button mat-button color=\\\"secondary\\\" matDialogClose>Cancel</button>\\n </p>\\n </ng-template>\\n </div>\\n\\n <div class=\\\"bottom-overlay\\\">\\n <div\\n *ngIf=\\\"feature.properties.taggit.groups && feature.properties.taggit.groups.length > 0\\\"\\n >\\n <div\\n *ngIf=\\\"feature.properties.taggit.groups.length < 5; else dotdot\\\"\\n class=\\\"group-tags\\\"\\n >\\n <div\\n *ngFor=\\\"let group of feature.properties.taggit.groups\\\"\\n class=\\\"center\\\"\\n (mouseover)=\\\"(group.name)\\\"\\n [matTooltip]=\\\"group.name\\\"\\n matTooltipPosition=\\\"above\\\"\\n >\\n <svg\\n class=\\\"box\\\"\\n width=\\\"25px\\\"\\n height=\\\"75px\\\"\\n (click)=\\\"deleteFromGroup(feature, group)\\\"\\n >\\n <rect\\n width=\\\"15px\\\"\\n height=\\\"15px\\\"\\n x=\\\"5\\\"\\n y=\\\"30\\\"\\n [style.fill]=\\\"group.color\\\"\\n />\\n <rect\\n class=\\\"inner-del\\\"\\n width=\\\"25px\\\"\\n height=\\\"15px\\\"\\n rx=\\\"3\\\"\\n x=\\\"0\\\"\\n y=\\\"0\\\"\\n style=\\\"fill: #ffffff\\\"\\n />\\n <rect\\n class=\\\"inner-del\\\"\\n width=\\\"15px\\\"\\n height=\\\"5px\\\"\\n x=\\\"5\\\"\\n y=\\\"5\\\"\\n style=\\\"fill: #de6363\\\"\\n />\\n </svg>\\n </div>\\n </div>\\n\\n <ng-template #dotdot class=\\\"text\\\">\\n <div\\n class=\\\"image-option\\\"\\n (click)=\\\"openModal(moreGroupsModal)\\\"\\n >\\n <i class=\\\"fas fa-ellipsis-h\\\"></i>\\n </div>\\n </ng-template>\\n\\n <!-- TODO Should close modal once zero groups -->\\n <ng-template #moreGroupsModal>\\n <div\\n style=\\\"display: flex; justify-content: center; align-items: center\\\"\\n >\\n <div\\n *ngFor=\\\"let group of feature.properties.taggit.groups\\\"\\n class=\\\"center-temp\\\"\\n style=\\\"display: flex\\\"\\n (mouseover)=\\\"(group.name)\\\"\\n [matTooltip]=\\\"group.name\\\"\\n matTooltipPosition=\\\"right\\\"\\n >\\n <svg\\n style=\\\"padding: 1\\\"\\n (click)=\\\"deleteFromGroup(feature, group)\\\"\\n width=\\\"15px\\\"\\n height=\\\"15px\\\"\\n >\\n <rect width=\\\"15px\\\" height=\\\"15px\\\" [style.fill]=\\\"group.color\\\" />\\n <rect\\n class=\\\"inner-del-temp\\\"\\n width=\\\"8px\\\"\\n height=\\\"4px\\\"\\n x=\\\"3.3\\\"\\n y=\\\"5.5\\\"\\n style=\\\"fill: #000\\\"\\n />\\n </svg>\\n </div>\\n </div>\\n </ng-template>\\n </div>\\n </div>\\n</div>\\n\"","export default \"<ng-container *ngIf=\\\"!loadingFeatureProperties; else loading\\\">\\n <app-select-group></app-select-group>\\n <app-select-image></app-select-image>\\n\\n <app-tag-generator\\n *ngIf=\\\"showTagGenerator; else tagImages\\\"\\n ></app-tag-generator>\\n <ng-template #tagImages>\\n <app-tag-images></app-tag-images>\\n </ng-template>\\n</ng-container>\\n<ng-template #loading>\\n <div\\n style=\\\"\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n justify-content: center;\\n height: 100%;\\n \\\"\\n >\\n <span>\\n Updating Group Data\\n <i class=\\\"fas fa-circle-notch fa-spin\\\"></i>\\n </span>\\n </div>\\n</ng-template>\\n\"","function webpackEmptyAsyncContext(req) {\n\t// Here Promise.resolve().then() is used instead of new Promise() to prevent\n\t// uncaught exception popping up in devtools\n\treturn Promise.resolve().then(function() {\n\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t});\n}\nwebpackEmptyAsyncContext.keys = function() { return []; };\nwebpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;\nmodule.exports = webpackEmptyAsyncContext;\nwebpackEmptyAsyncContext.id = \"crnd\";","export default \":host {\\n display: block;\\n font-size: 0.8em;\\n height: calc(100vh - 50px);\\n}\\n:host .lat-lon-label {\\n font-size: 0.8em;\\n color: #4d4d4d;\\n}\\n:host .active-project {\\n background-color: #1aff8c;\\n}\\n:host .menu button.dropdown.button {\\n padding: 0.85em 1em;\\n}\\n:host .switch {\\n margin: 0;\\n}\\n:host .button.tiny {\\n margin: 0;\\n}\\n:host .create-prompt {\\n max-height: 500px;\\n height: 500px;\\n}\\n:host .select-group {\\n max-height: 20%;\\n height: 20%;\\n}\\n:host .subitem-title {\\n text-align: left;\\n color: #555;\\n font-size: 14px;\\n padding: 10px;\\n background-color: #f1f1f1;\\n display: flex;\\n justify-content: space-between;\\n}\\n:host .input-label-group {\\n padding: 10px;\\n display: block;\\n}\\n:host .input-group {\\n display: inline-block;\\n}\\n:host .form-name {\\n text-align: center;\\n}\\n:host .input-group-button {\\n display: inline-block;\\n}\\n:host .subitem {\\n border-width: 0px 10px;\\n border-color: #f1f1f1;\\n border-style: solid;\\n overflow-y: auto;\\n background-color: #ffffff;\\n height: 40vh;\\n padding: 20px;\\n}\\n:host .subitem-scroll {\\n border-width: 5px;\\n}\\n:host .preset-descriptions {\\n max-height: 20%;\\n height: 20%;\\n}\\n:host .boxed input[type=radio] {\\n display: none;\\n}\\n:host .boxed label {\\n background-color: #fff;\\n transition: all 0.3s;\\n}\\n:host .boxed input[type=radio]:checked + label {\\n background-color: #b3e5ff;\\n}\\n:host .group-container {\\n display: flex;\\n flex-direction: row;\\n margin: 0;\\n justify-content: space-between;\\n}\\n:host .button-group {\\n margin: 0;\\n display: flex;\\n flex-direction: row;\\n}\\n:host .form-option-container {\\n padding: 0px;\\n}\\n:host .list-group {\\n display: flex;\\n flex-direction: row;\\n margin: 0;\\n justify-content: space-between;\\n}\\n:host .list-suboptions {\\n background-color: #f0f0f0;\\n}\\n:host .button-group div {\\n padding: 3px;\\n}\\n:host .name-group {\\n display: inline-block;\\n padding: 3px;\\n}\\n:host .form-item-container {\\n display: flex;\\n flex-direction: row;\\n margin: 0;\\n justify-content: space-between;\\n}\\n:host .form-type-form {\\n display: flex;\\n flex-direction: row;\\n justify-content: space-between;\\n margin: 5px;\\n margin-bottom: 15px;\\n}\\n:host .form-type-form input[type=radio] {\\n display: none;\\n}\\n:host .form-type-form label {\\n border-style: solid;\\n border-width: 1px;\\n border-color: #ddd;\\n transition: all 0.3s;\\n}\\n:host .form-type-form input[type=radio]:checked + label {\\n border-style: solid;\\n border-width: 1px;\\n border-color: #000;\\n}\\n:host .changed {\\n color: #f07575;\\n}\\n:host .unchanged {\\n color: #555555;\\n}\\n:host .asset-list {\\n max-height: 20%;\\n height: 20%;\\n}\\n:host .asset-container {\\n display: flex;\\n flex-direction: row;\\n justify-content: space-between;\\n cursor: pointer;\\n}\\n:host .highlight {\\n background-color: #b3e5ff;\\n}\"","export default \"<div>\\n <textarea\\n [id]=\\\"field.name\\\"\\n rows=\\\"9\\\"\\n class=\\\"form-control\\\"\\n [placeholder]=\\\"'notes'\\\"\\n [(ngModel)]=\\\"value\\\"\\n (keyup)=\\\"updateValue()\\\"\\n ></textarea>\\n</div>\\n\"","export default \":host #share-project-form {\\n display: flex;\\n flex-direction: column;\\n text-align: center;\\n padding: 5em;\\n}\\n\\n.card-container {\\n display: flex;\\n justify-content: space-between;\\n width: 99%;\\n}\\n\\n.card-item {\\n text-align: center;\\n align-items: center;\\n}\\n\\n.card-buttons {\\n align-items: flex-end;\\n}\"","export default \"<div id=\\\"map\\\" style=\\\"min-height: calc(100vh - 67px)\\\"></div>\\n\"","export default \"<div *ngFor=\\\"let opt of form.options\\\" [id]=\\\"form.label\\\" class=\\\"input-group\\\">\\n <div class=\\\"form-check form-check\\\">\\n <label class=\\\"form-check-label\\\">\\n <input\\n class=\\\"form-check-input\\\"\\n [(ngModel)]=\\\"value\\\"\\n type=\\\"radio\\\"\\n id=\\\"inlineCheckbox2\\\"\\n name=\\\"{{ label }}\\\"\\n value=\\\"{{ opt.label }}\\\"\\n (change)=\\\"updateCheckedTag()\\\"\\n />\\n {{ opt.label }}\\n </label>\\n </div>\\n</div>\\n\"","export default \":host #create-project-form {\\n display: flex;\\n flex-direction: column;\\n text-align: center;\\n padding: 5em;\\n}\"","export default \":host .img-container {\\n position: relative;\\n}\\n:host .img-container img {\\n -o-object-fit: cover;\\n object-fit: cover;\\n cursor: default;\\n width: 100%;\\n height: 100%;\\n transition: opacity 0.3s ease;\\n backface-visibility: hidden;\\n max-width: 100%;\\n max-height: 100%;\\n margin: 0 auto;\\n}\\n:host .top-overlay {\\n display: flex;\\n flex-direction: row;\\n transition: 0.3s ease;\\n opacity: 0;\\n position: absolute;\\n right: 10px;\\n top: 10px;\\n cursor: pointer;\\n text-align: center;\\n}\\n:host .bottom-overlay {\\n display: flex;\\n flex-direction: row;\\n transition: 0.3s ease;\\n opacity: 1;\\n position: absolute;\\n right: 10px;\\n bottom: 10px;\\n text-align: center;\\n}\\n:host .img-container:hover img {\\n opacity: 0.9;\\n}\\n:host .img-container:hover .top-overlay {\\n opacity: 0.9;\\n}\\n:host .img-container:hover .top-overlay:hover {\\n opacity: 1;\\n}\\n:host .image-option {\\n opacity: 0.9;\\n background-color: white;\\n display: flex;\\n color: black;\\n width: 40px;\\n height: 30px;\\n border-radius: 5px;\\n font-size: 16px;\\n margin: 3px;\\n justify-content: center;\\n align-items: center;\\n}\\n:host .image-option:hover {\\n opacity: 1;\\n}\\n:host .image-option .fas {\\n top: 5px;\\n}\\n:host .img-selected {\\n border: solid #0191ff;\\n border-width: 5px;\\n}\\n:host .img-unselected {\\n border: solid #fff;\\n border-width: 5px;\\n}\\n:host .group-tags {\\n opacity: 0.9;\\n background-color: white;\\n display: flex;\\n flex-direction: row;\\n width: auto;\\n height: 30px;\\n border-radius: 5px;\\n padding: 5px;\\n justify-content: center;\\n align-items: center;\\n z-index: 999;\\n}\\n:host .center {\\n display: flex;\\n flex-direction: row;\\n justify-content: center;\\n transition: 0.3s ease;\\n align-items: center;\\n}\\n:host .center .inner-del {\\n opacity: 0;\\n transition: 0.3s ease;\\n cursor: pointer;\\n}\\n:host .center:hover .inner-del {\\n opacity: 1;\\n}\\n:host .box {\\n padding: 1px;\\n}\\n.center-temp {\\n display: flex;\\n flex-direction: row;\\n justify-content: center;\\n align-items: center;\\n}\\n.center-temp .inner-del-temp {\\n opacity: 0;\\n transition: 0.3s ease;\\n cursor: pointer;\\n}\\n.center-temp:hover .inner-del-temp {\\n opacity: 0.5;\\n}\\n.zoom-content {\\n display: flex;\\n flex-direction: column;\\n max-height: 700px;\\n}\\n.zoom-content .img-container {\\n overflow-y: scroll;\\n width: 100%;\\n height: 100%;\\n background-color: #e7e7e7;\\n}\\n.zoom-content .img-details {\\n display: flex;\\n flex-direction: row;\\n margin-top: 24px;\\n background-color: #e7e7e7;\\n align-items: center;\\n text-align: center;\\n}\\n.zoom-content .title {\\n background-color: #ccc;\\n padding: 5px;\\n}\\n.zoom-content .detail-container {\\n display: flex;\\n flex-grow: 1;\\n flex-direction: column;\\n padding: 5px;\\n}\\n.zoom-content .detail-contents {\\n display: flex;\\n flex-direction: row;\\n padding: 5px;\\n background-color: #fff;\\n}\\n.zoom-content .detail-item {\\n padding: 5px;\\n}\"","export default \":host {\\n text-align: left;\\n}\\n:host .mat-form-field {\\n width: 100%;\\n text-align: left;\\n}\\n:host .input-group {\\n padding: 5px;\\n}\\n:host label {\\n padding: 5px;\\n}\\n:host input {\\n padding: 5px;\\n vertical-align: middle;\\n}\\n:host .radio-group {\\n display: flex;\\n flex-direction: column;\\n}\\n:host .form-controls {\\n padding: 20px;\\n}\"","export default \"<div *ngFor=\\\"let opt of form.options\\\" [id]=\\\"form.label\\\" class=\\\"input-group\\\">\\n <div class=\\\"form-check form-check\\\">\\n <label class=\\\"form-check-label\\\">\\n <input\\n class=\\\"form-check-input\\\"\\n [(ngModel)]=\\\"chosenTag\\\"\\n type=\\\"radio\\\"\\n id=\\\"inlineCheckbox3\\\"\\n name=\\\"{{ label }}\\\"\\n value=\\\"{{ opt.label }}\\\"\\n (change)=\\\"updateCheckedTag()\\\"\\n />\\n {{ opt.label }}\\n\\n <svg class=\\\"box\\\" width=\\\"10px\\\" height=\\\"10px\\\">\\n <rect width=\\\"10px\\\" height=\\\"10px\\\" style=\\\"fill: #ffffff\\\" />\\n <rect\\n width=\\\"8px\\\"\\n height=\\\"8px\\\"\\n x=\\\"1px\\\"\\n y=\\\"1px\\\"\\n [style.fill]=\\\"opt.color\\\"\\n />\\n </svg>\\n </label>\\n </div>\\n</div>\\n\"","export default \"<h4>Current Gallery/Map</h4>\\n<form\\n [formGroup]=\\\"projCreateForm\\\"\\n id=\\\"current-project-form\\\"\\n>\\n <mat-form-field>\\n <mat-label>Name:</mat-label>\\n <input\\n matInput\\n type=\\\"text\\\"\\n formControlName=\\\"name\\\"\\n appearance=\\\"filled\\\"\\n required=\\\"true\\\"\\n />\\n </mat-form-field>\\n\\n <mat-form-field>\\n <mat-label>Description</mat-label>\\n <textarea matInput formControlName=\\\"description\\\" required=\\\"true\\\"></textarea>\\n </mat-form-field>\\n\\n <div class=\\\"button-group small\\\">\\n <button\\n mat-raised-button\\n color=\\\"basic\\\"\\n class=\\\"button small warning\\\"\\n type=\\\"button\\\"\\n (click)=\\\"close()\\\"\\n >\\n Close\\n </button>\\n <button\\n *ngIf=\\\"activeProject.deletable\\\"\\n mat-raised-button\\n color=\\\"warn\\\"\\n class=\\\"button small warning\\\"\\n type=\\\"delete\\\"\\n (click)=\\\"delete()\\\"\\n >\\n Delete\\n </button>\\n <button\\n mat-raised-button\\n color=\\\"primary\\\"\\n class=\\\"button small align-right\\\"\\n type=\\\"submit\\\"\\n (click)=\\\"update()\\\"\\n [disabled]=\\\"!projCreateForm.valid\\\"\\n >\\n Update\\n </button>\\n </div>\\n</form>\\n\"","export default \"<h4>Create a new Gallery/Map</h4>\\n<form\\n [formGroup]=\\\"projCreateForm\\\"\\n (ngSubmit)=\\\"submit()\\\"\\n id=\\\"create-project-form\\\"\\n>\\n <mat-form-field>\\n <mat-label>Name:</mat-label>\\n <input matInput type=\\\"text\\\" formControlName=\\\"name\\\" required=\\\"true\\\" />\\n </mat-form-field>\\n\\n <mat-form-field>\\n <mat-label>Description</mat-label>\\n <textarea matInput formControlName=\\\"description\\\" required=\\\"true\\\"></textarea>\\n </mat-form-field>\\n\\n <div class=\\\"button-group small\\\">\\n <button\\n mat-raised-button\\n color=\\\"warn\\\"\\n class=\\\"button small warning\\\"\\n type=\\\"button\\\"\\n (click)=\\\"close()\\\"\\n >\\n Close\\n </button>\\n <button\\n mat-raised-button\\n color=\\\"primary\\\"\\n class=\\\"button small align-right\\\"\\n type=\\\"submit\\\"\\n [disabled]=\\\"!projCreateForm.valid\\\"\\n >\\n Submit\\n </button>\\n </div>\\n</form>\\n\"","export default \"\"","export default \":host {\\n font-size: 0.8em;\\n display: block;\\n}\\n:host .subitem-title {\\n text-align: left;\\n display: flex;\\n justify-content: space-between;\\n color: #555;\\n font-size: 14px;\\n padding: 10px;\\n background-color: #f1f1f1;\\n}\\n:host .subitem {\\n border-width: 0px 10px;\\n border-color: #f1f1f1;\\n border-style: solid;\\n padding: 10px;\\n overflow-y: auto;\\n background-color: #ffffff;\\n height: 40vh;\\n}\\n:host .main-form-container {\\n padding: 10px;\\n}\\n:host .subitem-scroll {\\n padding: 10px;\\n}\\n:host .subitem-scroll {\\n border-width: 5px;\\n}\\n:host .highlight {\\n background-color: #b3e5ff;\\n}\\n:host .boxed input[type=radio] {\\n display: none;\\n}\\n:host .boxed label {\\n background-color: #fff;\\n transition: all 0.3s;\\n}\\n:host .boxed input[type=radio]:checked + label {\\n background-color: #b3e5ff;\\n}\\n:host .group-container {\\n display: flex;\\n flex-direction: row;\\n margin: 0;\\n justify-content: space-between;\\n}\\n:host .select-group {\\n max-height: 20%;\\n height: 20%;\\n}\\n:host .tag-forms {\\n height: 500px;\\n}\\n:host .asset-list {\\n max-height: 20%;\\n height: 20%;\\n}\\n:host .asset-container {\\n display: flex;\\n flex-direction: row;\\n justify-content: space-between;\\n cursor: pointer;\\n}\\n:host .preset-descriptions {\\n max-height: 20%;\\n height: 20%;\\n}\\n:host .form-item-container {\\n display: flex;\\n flex-direction: row;\\n margin: 0;\\n justify-content: space-between;\\n}\\n:host .button-group {\\n display: flex;\\n flex-direction: row;\\n margin: 0;\\n}\\n:host .button-group div {\\n padding: 3px;\\n}\\n:host .name-group {\\n padding: 3px;\\n font-size: 17px;\\n font-weight: bold;\\n}\\n:host .list-group {\\n display: flex;\\n flex-direction: row;\\n margin: 0;\\n justify-content: space-between;\\n}\\n:host .list-suboptions {\\n background-color: #f0f0f0;\\n}\"","export default \"<div class=\\\"select-group\\\">\\n <div class=\\\"subitem-title\\\" (click)=\\\"expandPanel()\\\">Groups</div>\\n <div *ngIf=\\\"showSubitem\\\" class=\\\"subitem group-subitem\\\">\\n <!-- TODO redundant functionality radio is just for style -->\\n <form class=\\\"boxed\\\">\\n <div\\n *ngFor=\\\"let group of groups | keyvalue\\\"\\n (click)=\\\"selectGroupForm(group.value)\\\"\\n class=\\\"box form\\\"\\n >\\n <input\\n type=\\\"radio\\\"\\n [id]=\\\"group.key\\\"\\n [value]=\\\"group.key\\\"\\n name=\\\"skills\\\"\\n [checked]=\\\"isChecked(group.key)\\\"\\n />\\n <label\\n class=\\\"group-container\\\"\\n style=\\\"cursor: pointer\\\"\\n [for]=\\\"group.key\\\"\\n >\\n <div class=\\\"name-group\\\">\\n {{ group.key }}\\n <svg class=\\\"box\\\" width=\\\"10px\\\" height=\\\"10px\\\">\\n <rect width=\\\"10px\\\" height=\\\"10px\\\" style=\\\"fill: #ffffff\\\" />\\n <rect\\n width=\\\"8px\\\"\\n height=\\\"8px\\\"\\n x=\\\"1px\\\"\\n y=\\\"1px\\\"\\n [style.fill]=\\\"group.value.color\\\"\\n />\\n </svg>\\n </div>\\n <div class=\\\"button-group\\\">\\n <div (click)=\\\"deleteGroup(group.value)\\\">\\n <i\\n class=\\\"fas fa-minus\\\"\\n matTooltip=\\\"Delete\\\"\\n matTooltipPosition=\\\"below\\\"\\n >\\n </i>\\n </div>\\n <div (click)=\\\"openRenameModal(renameModal, group.value)\\\">\\n <i\\n class=\\\"fas fa-edit\\\"\\n matTooltip=\\\"Rename\\\"\\n matTooltipPosition=\\\"below\\\"\\n >\\n </i>\\n </div>\\n <div (click)=\\\"openIconSelection(iconModal, group.value)\\\">\\n <span\\n class=\\\"fa {{ group.value.icon }}\\\"\\n matTooltip=\\\"icons\\\"\\n matTooltipPosition=\\\"below\\\"\\n ></span>\\n </div>\\n </div>\\n </label>\\n </div>\\n </form>\\n\\n <ng-template #renameModal>\\n <input\\n matInput\\n #groupRename\\n placeholder=\\\"Rename Group\\\"\\n (keyup.enter)=\\\"renameGroup(groupRename.value)\\\"\\n />\\n <br />\\n <br />\\n <div class=\\\"button-group\\\">\\n <button\\n matDialogClose\\n color=\\\"primary\\\"\\n mat-raised-button\\n (click)=\\\"renameGroup(groupRename.value)\\\"\\n >\\n Rename\\n </button>\\n <button matDialogClose mat-button>Cancel</button>\\n </div>\\n </ng-template>\\n\\n <ng-template #iconModal>\\n <div class=\\\"iconDropdown\\\">\\n <select class=\\\"fa\\\" [(ngModel)]=\\\"selectedIcon\\\">\\n <option\\n class=\\\"fa\\\"\\n *ngFor=\\\"let icon of iconList\\\"\\n value=\\\"{{ icon.id }}\\\"\\n [innerHTML]=\\\"icon.unicode\\\"\\n ></option>\\n </select>\\n <br />\\n <br />\\n <div class=\\\"button-group\\\">\\n <button\\n matDialogClose\\n color=\\\"primary\\\"\\n mat-raised-button\\n (click)=\\\"saveIcon(selectedIcon)\\\"\\n >\\n Save\\n </button>\\n <button matDialogClose mat-button>Cancel</button>\\n </div>\\n </div>\\n </ng-template>\\n </div>\\n <!-- subitem -->\\n</div>\\n<!-- select-group -->\\n\"","export default \":host #current-project-form {\\n display: flex;\\n flex-direction: column;\\n text-align: center;\\n padding: 5em;\\n}\"","export default \"\"","export default \":host {\\n min-height: 20em;\\n}\\n:host .fileslisting {\\n height: 20em;\\n overflow-y: scroll;\\n padding: 0px 20px;\\n}\\n:host .file-row {\\n display: flex;\\n background: #f9f9f9;\\n border: 1px solid transparent;\\n user-select: none;\\n -webkit-user-select: none;\\n -moz-user-select: none;\\n}\\n:host .clickable {\\n flex: 1;\\n max-width: 20em;\\n}\\n:host .size {\\n align-items: flex-end;\\n}\\n:host .file-row:hover {\\n border: 1px solid;\\n}\\n:host .file-row.selected {\\n background: #d3d3d3;\\n}\\n.error {\\n background-color: red;\\n color: white;\\n}\\n.lineBreak {\\n max-width: 350px;\\n word-break: break-word;\\n}\"","export default \":host .active-project {\\n background-color: #1aff8c;\\n}\\n:host .menu button.dropdown.button {\\n padding: 0.85em 1em;\\n}\\n:host .button.tiny {\\n margin: 0;\\n}\\n:host .current-project {\\n padding: 30px;\\n font-size: 14px;\\n}\\n:host .goods {\\n height: 27px;\\n margin: 0px;\\n padding: 0px;\\n}\\n:host .toggler {\\n margin-left: 10px;\\n}\\n:host .picker {\\n display: inline-block;\\n}\\n:host .group-bar {\\n display: flex;\\n flex-direction: row;\\n}\\n:host .path-buttons {\\n text-align: center;\\n}\\n:host .project-menu {\\n margin-left: 10px;\\n}\\n:host .top-bar {\\n position: fixed;\\n margin-top: -50px;\\n height: 50px;\\n z-index: 999;\\n}\\n:host .top-bar-right .top-bar-left {\\n -webkit-box-flex: 0;\\n flex-wrap: nowrap;\\n flex: 0 1 auto;\\n max-width: 100%;\\n}\\n:host .my-button {\\n border-radius: 5px;\\n padding: 5px;\\n}\\n:host .button-spacing {\\n margin-right: 15px;\\n}\\n@media print, screen and (min-width: 40em) {\\n :host .top-bar {\\n flex-wrap: nowrap;\\n flex: 0 1 auto;\\n }\\n}\\n:host .example-spacer {\\n flex: 1 1 auto;\\n}\"","export default \"<mat-toolbar class=\\\"top-bar\\\" color=\\\"primary\\\">\\n <img src=\\\"assets/logo.svg\\\" width=\\\"40PX\\\" />\\n <span style=\\\"color: white\\\">Taggit</span>\\n\\n <button\\n mat-icon-button\\n [matMenuTriggerFor]=\\\"project\\\"\\n color=\\\"foreground\\\"\\n class=\\\"project-menu\\\"\\n >\\n <mat-icon>menu</mat-icon>\\n </button>\\n\\n <mat-menu #project=\\\"matMenu\\\">\\n <span\\n mat-menu-item\\n *ngIf=\\\"selectedProject\\\"\\n (click)=\\\"openProjectModal(selectedProject)\\\"\\n >\\n Current Gallery/Map : {{ selectedProject.name }}\\n </span>\\n <button mat-menu-item (click)=\\\"openCreateProjectModal()\\\">\\n Create Gallery/Map\\n </button>\\n <button mat-menu-item [matMenuTriggerFor]=\\\"projectList\\\">\\n Select Gallery/Map\\n </button>\\n <button mat-menu-item (click)=\\\"openFilePicker(test)\\\">Import images from DesignSafe</button>\\n <button mat-menu-item [matMenuTriggerFor]=\\\"saveOptions\\\">Export Tags/Groups</button>\\n </mat-menu>\\n\\n <mat-menu #projectList=\\\"matMenu\\\">\\n <button\\n mat-menu-item\\n class=\\\"clickable\\\"\\n *ngFor=\\\"let p of projects\\\"\\n (click)=\\\"selectProject(p)\\\"\\n [ngClass]=\\\"{ 'active-project': p === selectedProject }\\\"\\n >\\n {{ p.name }}\\n </button>\\n </mat-menu>\\n\\n <mat-menu #saveOptions=\\\"matMenu\\\">\\n <button mat-menu-item (click)=\\\"saveFile(0)\\\">CSV file</button>\\n <button mat-menu-item (click)=\\\"saveFile(1)\\\">JSON file</button>\\n <button mat-menu-item (click)=\\\"openDownloadSelector()\\\">\\n Export to DesignSafe\\n </button>\\n </mat-menu>\\n\\n <span class=\\\"example-spacer\\\"></span>\\n\\n <div *ngIf=\\\"showTagger\\\" class=\\\"path-buttons\\\">\\n <div class=\\\"slides\\\" style=\\\"line-height: 1; font-size: 12px\\\">\\n {{ getAssetDisplay() }}\\n <div class=\\\"lr-buttons\\\" style=\\\"margin-top: 5px\\\">\\n <i\\n (click)=\\\"otherPath(false)\\\"\\n style=\\\"margin-right: 10px; cursor: pointer\\\"\\n class=\\\"fas fa-angle-left\\\"\\n ></i>\\n <i\\n (click)=\\\"otherPath(true)\\\"\\n style=\\\"margin-left: 10px; cursor: pointer\\\"\\n class=\\\"fas fa-angle-right\\\"\\n ></i>\\n </div>\\n </div>\\n </div>\\n\\n <span class=\\\"example-spacer\\\"></span>\\n\\n <div class=\\\"group-bar grid-x align-right\\\">\\n <button\\n mat-raised-button\\n class=\\\"button-spacing\\\"\\n [disabled]=\\\"selectedImages.length === 0\\\"\\n (click)=\\\"clearAll()\\\"\\n >\\n Clear Selected\\n </button>\\n\\n <!-- A link that looks like a button, links to Hazmapper-->\\n <a\\n class=\\\"button-spacing\\\"\\n mat-raised-button\\n href=\\\"{{ hazmapperLink }}\\\"\\n title=\\\"View in HazMapper\\\"\\n target=\\\"_blank\\\"\\n >\\n <img src=\\\"assets/hazmapper-header-logo.png\\\" width=\\\"25PX\\\" />\\n <span style=\\\"padding-left: 5px; color: #00BBD8\\\">View in HazMapper</span>\\n </a>\\n\\n <button\\n mat-raised-button\\n (click)=\\\"openAddGroupModal(addToGroupModal)\\\"\\n *ngIf=\\\"selectedImages.length > 0 && groupsExist && !showTagger\\\"\\n class=\\\"button-spacing\\\"\\n >\\n Add To Group\\n </button>\\n\\n <button\\n mat-raised-button\\n (click)=\\\"openAddGroupModal(addGroupModal)\\\"\\n *ngIf=\\\"selectedImages.length > 0 && !showTagger\\\"\\n >\\n Create Group\\n </button>\\n\\n <ng-template #addGroupModal>\\n <mat-form-field>\\n <mat-label>Group Name</mat-label>\\n <input\\n matInput\\n placeholder=\\\"Group Name\\\"\\n (keyup.enter)=\\\"addGroup(groupInput.value)\\\"\\n #groupInput\\n />\\n </mat-form-field>\\n\\n <div style=\\\"color: #ff0000\\\" *ngIf=\\\"invalidNameError\\\">Invalid Name!</div>\\n <div style=\\\"color: #ff0000\\\" *ngIf=\\\"existingNameError\\\">Existing Name!</div>\\n <br />\\n <br />\\n <button\\n mat-raised-button\\n color=\\\"primary\\\"\\n (click)=\\\"addGroup(groupInput.value)\\\"\\n >\\n Add Group\\n </button>\\n <button mat-button matDialogClose color=\\\"secondary\\\">Cancel</button>\\n </ng-template>\\n\\n <ng-template #addToGroupModal>\\n <mat-form-field appearance=\\\"fill\\\">\\n <mat-label>Groups</mat-label>\\n <mat-select\\n matNativeControl\\n required\\n [value]=\\\"groupToAdd\\\"\\n [compareWith]=\\\"compareGroup\\\"\\n (selectionChange)=\\\"changeGroupToAdd($event)\\\"\\n >\\n <mat-option\\n *ngFor=\\\"let group of groups | keyvalue\\\"\\n [value]=\\\"group.value\\\"\\n >\\n {{ group.key }}\\n </mat-option>\\n </mat-select>\\n </mat-form-field>\\n\\n <p>\\n <button\\n mat-raised-button\\n color=\\\"primary\\\"\\n matDialogClose\\n (click)=\\\"addToGroup(groupToAdd)\\\"\\n [disabled]=\\\"!groupToAdd\\\"\\n >\\n Add To Group\\n </button>\\n <button mat-button color=\\\"secondary\\\" matDialogClose>Cancel</button>\\n </p>\\n </ng-template>\\n </div>\\n\\n <button\\n *ngIf=\\\"showTagger && tagFeaturesQueue.length > 0\\\"\\n mat-raised-button\\n style=\\\"margin-left: 15px\\\"\\n (click)=\\\"saveTags()\\\"\\n >\\n <i class=\\\"fas fa-save\\\"></i>\\n Save Tags\\n </button>\\n\\n <button\\n *ngIf=\\\"groupsExist && !showTagger\\\"\\n mat-raised-button\\n style=\\\"margin-left: 15px\\\"\\n (click)=\\\"toggleTagger()\\\"\\n >\\n Taggit!\\n </button>\\n\\n <button\\n *ngIf=\\\"showTagger\\\"\\n mat-raised-button\\n style=\\\"margin-left: 15px\\\"\\n (click)=\\\"toggleTagger()\\\"\\n >\\n Gallery/Map\\n </button>\\n</mat-toolbar>\\n\"","export default \"<div *ngFor=\\\"let opt of form.options\\\" [id]=\\\"form.label\\\" class=\\\"input-group\\\">\\n <div class=\\\"form-check form-check\\\">\\n <label class=\\\"form-check-label\\\">\\n <input\\n class=\\\"form-check-input\\\"\\n type=\\\"checkbox\\\"\\n [checked]=\\\"isChecked(opt)\\\"\\n id=\\\"inlineCheckbox1\\\"\\n value=\\\"{{ opt.label }}\\\"\\n (change)=\\\"selected($event, opt)\\\"\\n />\\n {{ opt.label }}\\n </label>\\n </div>\\n</div>\\n\"","export default \"\"","import { Component, OnInit } from '@angular/core';\n\n@Component({\n selector: 'app-notfound',\n templateUrl: './notfound.component.html',\n styleUrls: ['./notfound.component.scss'],\n})\nexport class NotFoundComponent implements OnInit {\n constructor() {}\n\n ngOnInit() {}\n}\n","import {\n Feature as GeoJSONFeature,\n GeoJsonProperties,\n Geometry,\n FeatureCollection as IFeatureCollection,\n} from 'geojson';\n\n// TODO: break these out into their own files\n\nexport interface IPointCloud {\n id: number;\n description: string;\n conversion_parameters: string;\n feature_id?: number;\n task_id?: string;\n project_id: number;\n}\n\n// export interface Group {\n// groupName: Array<string>;\n// formList: Array<any>;\n// // type: any;\n// }\n\n// export interface Group {\n// groupName: Array<string>;\n// formList: Array<any>;\n// // type: any;\n// }\n\nexport interface Group {\n groupName: string;\n formList: Array<any>;\n color: string;\n // type: any;\n}\n\nexport class Group implements Group {}\n\nexport interface TagGroup {\n name: string;\n id?: number;\n color?: string;\n icon?: string;\n forms?: GroupForm[];\n}\n\nexport class TagGroup implements TagGroup {}\n\nexport interface GroupForm {\n id?: string;\n groupName?: string;\n label?: string;\n color?: string;\n type?: string;\n options?: Array<any>;\n}\n\nexport class GroupForm implements GroupForm {}\n\nexport interface Tag {\n id?: string;\n value?: any;\n}\n\nexport class Tag implements Tag {}\n\n// NOTE: For geojson/tag\nexport interface TagValue {\n id: number;\n featureId?: number;\n tagId?: number;\n groupId?: string;\n value?: Array<any> | string | number;\n}\n\nexport class TagValue implements TagValue {}\n\nexport class AssetFilters {\n // bbox has the following format: [sw_lng, sw_lat, ne_lng, ne_lat], the same as leaflet\n bbox: Array<number> = [];\n assetType: Set<string> = new Set<string>();\n\n updateAssetTypes(assetType: string) {\n this.assetType.has(assetType)\n ? this.assetType.delete(assetType)\n : this.assetType.add(assetType);\n }\n\n updateBBox(bbox: Array<number>): void {\n this.bbox = bbox;\n }\n\n toJson() {\n return {\n assetType: [...this.assetType],\n bbox: this.bbox,\n };\n }\n}\n\nexport interface Project {\n description: string;\n id?: number;\n name: string;\n ds_id?: string;\n title?: string;\n uuid?: string;\n public?: boolean;\n system_file?: string;\n system_id?: string;\n system_path?: string;\n deletable?: boolean;\n deleting?: boolean;\n deletingFailed?: boolean;\n}\n\nexport class Project implements Project {}\n\nexport interface ProjectRequest {\n project: Project;\n observable?: boolean;\n watch_content?: boolean;\n}\n\nexport class ProjectRequest implements ProjectRequest {}\n\nexport class AuthToken {\n token: string;\n expires: Date;\n /**\n *\n * @param token : String\n * @param expires: Date\n */\n constructor(token: string, expires: Date) {\n this.token = token;\n this.expires = new Date(expires);\n }\n\n static fromExpiresIn(token: string, expires_in: number) {\n const expires = new Date(new Date().getTime() + expires_in * 1000);\n return new AuthToken(token, expires);\n }\n\n /**\n * Checks if the token is expired or not\n */\n public isExpired(): boolean {\n return new Date().getTime() > this.expires.getTime();\n }\n}\n\nexport interface IFeatureAsset {\n id?: number;\n path?: string;\n uuid?: string;\n feature_id?: number;\n asset_type?: string;\n display_path?: string;\n}\n\nexport class FeatureAsset implements IFeatureAsset {\n id: number;\n path: string;\n uuid: string;\n feature_id: number;\n asset_type: string;\n display_path: string;\n\n // TODO: Implenent this\n get assetPath(): string {\n return '';\n }\n}\n\nexport interface FeatureStyles {\n // [key: string]?: string | number;\n faIcon?: string;\n color?: string;\n}\n\nexport class FeatureStyles implements FeatureStyles {}\n\nexport interface Overlay {\n id: number;\n path: string;\n uuid: string;\n minLon: number;\n minLat: number;\n maxLon: number;\n maxLat: number;\n project_id: number;\n label: string;\n}\n\ninterface AppGeoJSONFeature extends GeoJSONFeature {\n assets?: Array<IFeatureAsset>;\n styles?: FeatureStyles;\n project_id?: number;\n // featureType?(): String\n}\n\nexport class FeatureCollection implements IFeatureCollection {\n features: Feature[];\n type: any;\n}\n\nexport class Feature implements AppGeoJSONFeature {\n geometry: Geometry;\n // Taggit specific:\n // properties.taggit\n // properties.taggit.tags: Tag[]\n // properties.taggit.groups: Group[]\n properties: GeoJsonProperties;\n id?: string | number;\n type: any;\n assets?: Array<IFeatureAsset>;\n styles?: FeatureStyles;\n project_id?: number;\n\n constructor(f: AppGeoJSONFeature) {\n this.geometry = f.geometry;\n this.properties = f.properties;\n\n // NOTE: Taggit-specific\n this.properties.taggit = this.properties.taggit ? this.properties.taggit : {};\n this.properties.taggit.groups = this.properties.taggit.groups ? this.properties.taggit.groups : [];\n this.properties.taggit.tags = this.properties.taggit.tags ? this.properties.taggit.tags : [];\n\n this.id = f.id;\n this.type = f.type;\n this.assets = f.assets;\n this.styles = f.styles;\n this.project_id = f.project_id;\n }\n\n initialAsset?() {\n return this.assets[0];\n }\n\n featureType?(): string {\n if (this.assets && this.assets.length === 1) {\n return this.initialAsset().asset_type;\n }\n\n if (this.assets && this.assets.length > 1) {\n return 'collection';\n }\n\n if (!this.assets.length) {\n return this.geometry.type;\n }\n }\n\n featurePath?(): string {\n const initialAsset = this.initialAsset();\n if (initialAsset.display_path) {\n return initialAsset.display_path;\n } else if (initialAsset.path) {\n return initialAsset.path;\n } else {\n return this.id.toString();\n }\n }\n\n featureShortPath?(): string {\n const [initialAsset] = this.assets;\n if (initialAsset.display_path) {\n return /[^/]*$/.exec(initialAsset.display_path)[0];\n } else if (initialAsset.path) {\n const path = /[^/]*$/.exec(initialAsset.path)[0];\n return path.slice(0, 15) + '...';\n } else {\n return this.id.toString();\n }\n }\n}\n\nexport interface IProjectUser {\n id: number;\n username: string;\n}\n","export enum EnvironmentType {\n Production = 'production',\n Staging = 'staging',\n Local = 'local',\n}\n","import { EnvironmentType } from './environmentType';\n\nexport interface AppEnvironment {\n production: boolean;\n apiUrl: string;\n jwt?: string;\n clientId: string;\n baseHref: string;\n backend: EnvironmentType;\n}\n\nexport const environment: AppEnvironment = {\n production: true,\n apiUrl: 'https://agave.designsafe-ci.org/geo/v2/',\n clientId: 'jHXnvsmQQcmP43qlrG7ATaxFXHQa',\n baseHref: '/',\n backend: EnvironmentType.Production,\n};\n","import { Injectable } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { AuthToken } from '../models/models';\nimport { environment } from '../../environments/environment';\nimport { Observable, ReplaySubject } from 'rxjs';\nimport { Router } from '@angular/router';\n\nexport class AuthenticatedUser {\n public readonly username: string;\n public readonly email: string;\n private _token: AuthToken;\n\n constructor(username: string, email: string) {\n this.username = username;\n this.email = email;\n }\n}\n\ninterface OpenIDUser {\n name: string;\n email: string;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class AuthService {\n private _currentUser: ReplaySubject<AuthenticatedUser> =\n new ReplaySubject<AuthenticatedUser>(1);\n public readonly currentUser: Observable<AuthenticatedUser> =\n this._currentUser.asObservable();\n userToken: AuthToken;\n private LS_TOKEN_KEY = 'hazmapperToken';\n private LS_USER_KEY = 'hazmapperUser';\n\n constructor(private http: HttpClient, private router: Router) {}\n\n public login() {\n // First, check if the user has a token in localStorage\n const tokenStr = localStorage.getItem(this.LS_TOKEN_KEY);\n if (!tokenStr) {\n this.redirectToauthenticaor();\n } else {\n const token = JSON.parse(tokenStr);\n this.userToken = new AuthToken(token.token, new Date(token.expires));\n if (!this.userToken || this.userToken.isExpired()) {\n this.logout();\n this.redirectToauthenticaor();\n }\n this.getUserInfo();\n }\n }\n\n private redirectToauthenticaor() {\n const client_id = environment.clientId;\n const callback = location.origin + environment.baseHref + 'callback';\n const state = Math.random().toString(36);\n const AUTH_URL = `https://agave.designsafe-ci.org/authorize?scope=openid&client_id=${client_id}&response_type=token&redirect_uri=${callback}&state=${state}`;\n window.location.href = AUTH_URL;\n }\n\n /**\n * Checks to make sure that the user has a token and the token is not expired;\n */\n public isLoggedIn(): boolean {\n return this.userToken && !this.userToken.isExpired();\n }\n\n public logout(): void {\n this.userToken = null;\n localStorage.removeItem(this.LS_TOKEN_KEY);\n localStorage.removeItem(this.LS_USER_KEY);\n }\n\n public setToken(token: string, expires: number): void {\n this.userToken = AuthToken.fromExpiresIn(token, expires);\n localStorage.setItem(this.LS_TOKEN_KEY, JSON.stringify(this.userToken));\n // hit the wso2 api to retrieve the username etc\n this.router.navigate(['/']);\n }\n\n public getUserInfo() {\n const INFO_URL = `https://agave.designsafe-ci.org/oauth2/userinfo?schema=openid`;\n const userStr = localStorage.getItem(this.LS_USER_KEY);\n const user = JSON.parse(userStr);\n if (user !== null) {\n this._currentUser.next(new AuthenticatedUser(user.username, user.email));\n } else {\n this.http.get<OpenIDUser>(INFO_URL).subscribe((resp) => {\n const u = new AuthenticatedUser(resp.name, resp.email);\n localStorage.setItem(this.LS_USER_KEY, JSON.stringify(u));\n this._currentUser.next(u);\n });\n }\n }\n}\n","import { Injectable } from '@angular/core';\nimport { environment } from 'src/environments/environment';\nimport { ToastrService } from 'ngx-toastr';\nimport { HttpClient } from '@angular/common/http';\nimport { INotification } from '../models/notification';\nimport { interval, Observable, ReplaySubject } from 'rxjs';\nimport { AuthService } from '../services/authentication.service';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class NotificationsService {\n // Interval time to get notifications in millisecs\n private TIMEOUT = 5000;\n private _notifications: ReplaySubject<Array<INotification>> =\n new ReplaySubject<Array<INotification>>(1);\n public readonly notifications: Observable<Array<INotification>> =\n this._notifications.asObservable();\n\n constructor(\n private toastr: ToastrService,\n private http: HttpClient,\n private authService: AuthService\n ) {\n if (this.authService.isLoggedIn()) {\n const timer = interval(this.TIMEOUT);\n timer.subscribe((next) => {\n this.getRecent();\n });\n }\n }\n\n // Sends a request to GeoAPI to retrieve recent notifications\n getRecent(): void {\n const baseUrl = environment.apiUrl + 'notifications/';\n const now = new Date();\n const then = new Date(now.getTime() - this.TIMEOUT);\n\n this.http\n .get<Array<INotification>>(baseUrl + `?startDate=${then.toISOString()}`)\n .subscribe((notes) => {\n this._notifications.next(notes);\n notes.forEach((note) => {\n switch (note.status) {\n case 'success':\n this.showSuccessToast(note.message);\n break;\n case 'error':\n this.showErrorToast(note.message);\n break;\n default:\n break;\n }\n });\n });\n }\n\n showSuccessToast(message: string): void {\n this.toastr.success(message);\n }\n\n showImportErrorToast(message: string): void {\n this.toastr.error(message + ', trying alternate method');\n }\n\n showErrorToast(message: string): void {\n this.toastr.error(message);\n }\n}\n","import { Injectable } from '@angular/core';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ScrollService {\n constructor() {}\n\n public scrollRestored = true; // if true, the scroll was restored to the proper place\n public scrollPosition = 0;\n\n setScrollRestored(change: boolean) {\n this.scrollRestored = change;\n }\n\n setScrollPosition() {\n this.scrollPosition = document.documentElement.scrollTop;\n }\n\n scroll() {\n // Attempts to scroll to the specified location\n document.documentElement.scroll({ top: this.scrollPosition });\n // if it reaches there, marks the check as complete\n if (document.documentElement.scrollTop == this.scrollPosition) {\n this.scrollRestored = false;\n }\n }\n}\n","import { Injectable } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { BehaviorSubject, Observable, ReplaySubject, Subject } from 'rxjs';\nimport { LatLng } from 'leaflet';\nimport {\n AssetFilters,\n FeatureAsset,\n FeatureStyles,\n IFeatureAsset,\n IPointCloud,\n Overlay,\n TagGroup,\n Tag,\n TagValue,\n GroupForm,\n} from '../models/models';\nimport { Feature, FeatureCollection } from '../models/models';\nimport { environment } from '../../environments/environment';\nimport { Form } from '@angular/forms';\nimport { take, first } from 'rxjs/operators';\nimport * as querystring from 'querystring';\nimport { RemoteFile } from 'ng-tapis';\nimport { NotificationsService } from './notifications.service';\nimport { ScrollService } from './scroll.service';\nimport { getRandomColor } from '../utils/randomColor';\nimport { v4 as uuidv4 } from 'uuid';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class GeoDataService {\n // TODO: clean this up and put the observables up here. Also look into Replay/Behavior\n // TODO: Go over this and remove all unused functions, a lot of this was copy/pasted over from Hazmapper without a second thought\n private _features: BehaviorSubject<FeatureCollection>;\n private features$: Observable<FeatureCollection>;\n private _activeFeature: BehaviorSubject<any>;\n private _mapMouseLocation: BehaviorSubject<any>;\n private _basemap: BehaviorSubject<any>;\n private _overlays: BehaviorSubject<any>;\n private _activeOverlay: BehaviorSubject<any>;\n private _pointClouds: BehaviorSubject<Array<IPointCloud>> =\n new BehaviorSubject<Array<IPointCloud>>(null);\n public readonly pointClouds: Observable<Array<IPointCloud>> =\n this._pointClouds.asObservable();\n private fileList: Array<RemoteFile>;\n\n private _loaded: BehaviorSubject<boolean> = new BehaviorSubject(null);\n public loaded: Observable<boolean> = this._loaded.asObservable();\n\n private _loadingGallery: BehaviorSubject<boolean> = new BehaviorSubject(null);\n public loadingGallery: Observable<boolean> = this._loadingGallery.asObservable();\n\n private _activeGroupId: BehaviorSubject<number> = new BehaviorSubject(null);\n public activeGroupId: Observable<number> = this._activeGroupId.asObservable();\n\n private _activeGroup: BehaviorSubject<TagGroup> = new BehaviorSubject(null);\n public activeGroup: Observable<TagGroup> = this._activeGroup.asObservable();\n\n private _tagFeaturesQueue: BehaviorSubject<any[]> = new BehaviorSubject([]);\n public tagFeaturesQueue: Observable<any[]> =\n this._tagFeaturesQueue.asObservable();\n\n private _loadingFeatureProperties: BehaviorSubject<boolean> =\n new BehaviorSubject(false);\n public loadingFeatureProperties: Observable<boolean> =\n this._loadingFeatureProperties.asObservable();\n\n private _activeGroupFeature: BehaviorSubject<any> = new BehaviorSubject<any>(\n null\n );\n public activeGroupFeature: Observable<any> =\n this._activeGroupFeature.asObservable();\n\n private _groups: BehaviorSubject<Map<string, TagGroup>> = new BehaviorSubject(\n null\n );\n public groups: Observable<Map<string, TagGroup>> =\n this._groups.asObservable();\n\n private _groupsFeatures: BehaviorSubject<Map<string, Feature[]>> =\n new BehaviorSubject(null);\n public groupsFeatures: Observable<Map<string, Feature[]>> =\n this._groupsFeatures.asObservable();\n\n constructor(\n private http: HttpClient,\n private notificationsService: NotificationsService,\n private scrollService: ScrollService\n ) {\n this._features = new BehaviorSubject<FeatureCollection>({\n type: 'FeatureCollection',\n features: [],\n });\n this.features$ = this._features.asObservable();\n this._activeFeature = new BehaviorSubject<any>(null);\n this._mapMouseLocation = new BehaviorSubject<any>(null);\n\n // For the style of the basemap, defaults to OpenStreetmap\n this._basemap = new BehaviorSubject<any>('roads');\n\n // Holds all of the overlays on a project\n this._overlays = new BehaviorSubject<any>(null);\n this._activeOverlay = new BehaviorSubject<any>(null);\n }\n\n getFeature(\n projectId: number,\n feature: Feature\n ): Observable<FeatureCollection> {\n return this.http.get<FeatureCollection>(\n environment.apiUrl + `/projects/${projectId}/features/${feature.id}/`\n );\n }\n\n setFeatures(fc: FeatureCollection) {\n fc.features = fc.features.map((feat: Feature) => new Feature(feat));\n this.getGroups(fc.features);\n this._features.next(fc);\n }\n\n setFeatureProperties(featureId: string | number, properties: any) {\n this.features.pipe(first()).subscribe((fc) => {\n fc.features = fc.features.map((feat: Feature) => {\n if (feat.id === featureId) {\n feat.properties = properties;\n }\n return feat;\n });\n this.setFeatures(fc);\n });\n }\n\n updateTagFeaturesQueue(projectId) {\n this._tagFeaturesQueue.value.forEach((featureId) => {\n const feature = this._features.value.features.find(\n (f) => f.id == featureId\n );\n this.updateFeatureProperty(projectId, featureId, feature.properties);\n });\n this.resetTagFeaturesQueue();\n }\n\n setFeatureStyles(featureId: string | number, styles: FeatureStyles) {\n this.features.pipe(first()).subscribe((fc) => {\n fc.features = fc.features.map((feat: Feature) => {\n if (feat.id === featureId) {\n feat.styles = styles;\n }\n return feat;\n });\n this.setFeatures(fc);\n });\n }\n\n getFeatures(\n projectId: number,\n query: AssetFilters = new AssetFilters(),\n restoreScroll = false\n ): void {\n const qstring: string = querystring.stringify(query.toJson());\n this._loadingGallery.next(false);\n this.http\n .get<FeatureCollection>(\n environment.apiUrl + `/projects/${projectId}/features/` + '?' + qstring\n )\n .subscribe(\n (fc: FeatureCollection) => {\n this.setFeatures(fc);\n this._loaded.next(true);\n this._loadingGallery.next(true);\n\n if (restoreScroll) {\n this.scrollService.setScrollRestored(true);\n }\n },\n (error) => {\n this.notificationsService.showErrorToast(\n 'Failed to retrieve project data! Geoapi might be down.'\n );\n }\n );\n }\n\n deleteFeature(feature: Feature) {\n this.http\n .delete(\n environment.apiUrl +\n `projects/${feature.project_id}/features/${feature.id}/`\n )\n .subscribe((resp) => {\n this.getFeatures(feature.project_id, new AssetFilters(), true);\n });\n }\n\n getPointClouds(projectId: number) {\n this.http\n .get<Array<IPointCloud>>(\n environment.apiUrl + `/projects/${projectId}/point-cloud/`\n )\n .subscribe((resp) => {\n this._pointClouds.next(resp);\n });\n }\n\n setActiveGroup(group: TagGroup): void {\n this._activeGroup.next(group);\n if (group) {\n const groupFeatures = this._groupsFeatures.value.get(group.name);\n if (\n !this._activeGroupFeature.value ||\n !groupFeatures.some((gf) => this._activeGroupFeature.value.id === gf.id)\n ) {\n this.setActiveGroupFeature(groupFeatures[0]);\n }\n } else {\n this.setActiveGroupFeature(null);\n }\n }\n\n // NOTE: Tag features queue is the local change to tags before posting it \n // to geoapi to persist.\n setTagFeaturesQueue(featureId, updatedTag) {\n const tagFeatures = this._tagFeaturesQueue.value;\n const fc = this._features.value;\n\n fc.features.map((f) => {\n if (featureId == f.id) {\n if (f.properties.taggit.tags.some((t) => updatedTag.id == t.id)) {\n f.properties.taggit.tags.map((t) => {\n if (t.id == updatedTag.id) {\n t.value = updatedTag.value;\n }\n return t;\n });\n } else {\n f.properties.taggit.tags = f.properties.taggit.tags.length\n ? [...f.properties.taggit.tags, updatedTag]\n : [updatedTag];\n }\n }\n return f;\n });\n\n if (!tagFeatures.includes(featureId)) {\n tagFeatures.push(featureId);\n }\n\n this._tagFeaturesQueue.next(tagFeatures);\n this._features.next(fc);\n }\n\n resetTagFeaturesQueue() {\n this._tagFeaturesQueue.next([]);\n }\n\n setActiveGroupFeature(feat: any): void {\n this._activeGroupFeature.next(feat);\n }\n\n addFeature(feat: Feature): void {\n this.features$.pipe(take(1)).subscribe((current: FeatureCollection) => {\n current.features.push(feat);\n this._features.next(current);\n });\n }\n\n addPointCloud(\n projectId: number,\n title: string,\n conversionParams: string\n ): void {\n const payload = {\n description: title,\n conversion_parameters: conversionParams,\n };\n this.http\n .post(environment.apiUrl + `/projects/${projectId}/point-cloud/`, payload)\n .subscribe(\n (resp) => {\n this.getPointClouds(projectId);\n },\n (error) => {\n this.notificationsService.showErrorToast(\n 'Failed to update image property!'\n );\n }\n );\n }\n\n updateFeatureProperty(\n projectId: number,\n featureId: string | number,\n groupData: any\n ): void {\n this._loadingFeatureProperties.next(true);\n this.http\n .post(\n environment.apiUrl +\n `projects/${projectId}/features/${featureId}/properties/`,\n groupData\n )\n .subscribe(\n (resp) => {\n this.features.pipe(first()).subscribe((fc) => {\n this.setFeatureProperties(featureId, groupData);\n this._loadingFeatureProperties.next(false);\n });\n },\n (error) => {\n this.notificationsService.showErrorToast(\n 'Failed to save tag values!'\n );\n }\n );\n }\n\n // NOTE: unused for now\n updateFeatureStyles(\n projectId: number,\n featureId: string | number,\n styles: FeatureStyles\n ): void {\n this.http\n .post(\n environment.apiUrl +\n `/projects/${projectId}/features/${featureId}/styles/`,\n styles\n )\n .subscribe(\n (resp) => {\n this.features.pipe(first()).subscribe((fc) => {\n this.setFeatureStyles(featureId, styles);\n });\n },\n (error) => {\n this.notificationsService.showErrorToast(\n 'Failed to update image style!'\n );\n }\n );\n }\n\n deletePointCloud(pc: IPointCloud): void {\n this.http\n .delete(\n environment.apiUrl + `/projects/${pc.project_id}/point-cloud/${pc.id}/`\n )\n .subscribe((resp) => {\n this.getPointClouds(pc.project_id);\n });\n }\n\n addFileToPointCloud(pc: IPointCloud, file: File) {\n const form = new FormData();\n form.append('file', file);\n this.http\n .post(\n environment.apiUrl + `/projects/${pc.project_id}/point-cloud/${pc.id}/`,\n form\n )\n .subscribe((resp) => {\n console.log(resp);\n });\n }\n\n // This function updates the underlying observable, so changes naturally flow to feature service\n importFileFromTapis(projectId: number, files: Array<RemoteFile>): void {\n const tmp = files.map((f) => ({ system: f.system, path: f.path }));\n const payload = {\n files: tmp,\n };\n this.fileList = tmp;\n this.http\n .post(\n environment.apiUrl + `projects/${projectId}/features/files/import/`,\n payload\n )\n\n .subscribe(\n (resp) => {\n this.notificationsService.showSuccessToast('Import started!');\n },\n (error) => {\n this.notificationsService.showImportErrorToast(\n 'Import failed! Try again?'\n );\n }\n );\n }\n\n // An alternate function for importing images with no GPS data. A feature is created elsewhere, and the image is added to the feature\n // Inputs:\n // projectId: Id number of current project\n // features: A pre-created feature with user-defined or zeroed out gps data\n // file: A Tapis Remote File containing the image to be imported\n importImage(projectId: number, feature: Feature, path: string): void {\n const featureId = feature.id;\n let file;\n this.fileList.forEach((remoteFile) => {\n if (remoteFile.path == path) {\n file = remoteFile;\n }\n });\n const payload = { system_id: file.system, path: file.path };\n this.http\n .post(\n environment.apiUrl +\n `projects/${projectId}/features/${featureId}/assets/`,\n payload\n )\n .subscribe((resp) => {\n this.notificationsService.showSuccessToast('Import started!');\n // this.getFeatures(projectId)\n });\n }\n\n // Creates a new feature from an uploaded locally created feature\n uploadNewFeature(projectId: number, feature: Feature, path: string): void {\n const payload = feature;\n let response;\n // Calls the addFeatureAsset route in GeoAPI, resp is a list of features\n this.http\n .post(environment.apiUrl + `projects/${projectId}/features/`, payload)\n .subscribe((resp) => {\n response = new Feature(resp[0]);\n this.importImage(projectId, response, path);\n });\n }\n\n downloadGeoJSON(projectId: number, query: AssetFilters = new AssetFilters()) {\n const qstring: string = querystring.stringify(query.toJson());\n const downloadLink = document.createElement('a');\n\n this.http\n .get<FeatureCollection>(\n environment.apiUrl + `/projects/${projectId}/features/` + '?' + qstring\n )\n .subscribe((resp) => {\n const blob = new Blob([JSON.stringify(resp)], {\n type: 'application/json',\n });\n downloadLink.href = URL.createObjectURL(blob);\n downloadLink.setAttribute('download', 'hazmapper.json');\n document.body.appendChild(downloadLink);\n downloadLink.click();\n document.body.removeChild(downloadLink);\n });\n }\n\n uploadFile(projectId: number, file: File): void {\n const form: FormData = new FormData();\n form.append('file', file, file.name);\n this.http\n .post<Array<Feature>>(\n environment.apiUrl + `/projects/${projectId}/features/files/`,\n form\n )\n .subscribe(\n (feats) => {\n feats.forEach((feat) => {\n this.addFeature(new Feature(feat));\n });\n },\n (error) => {\n // TODO: Add notification\n }\n );\n }\n\n uploadAssetFile(projectId: number, featureId: number, file: File): void {\n const form: FormData = new FormData();\n form.append('file', file, file.name);\n this.http\n .post<Feature>(\n environment.apiUrl +\n `/api/projects/${projectId}/features/${featureId}/assets/`,\n form\n )\n .subscribe(\n (feature) => {\n // TODO workaround to update activeFeature\n const f = this._activeFeature.getValue();\n if (f && f.id === featureId) {\n this.activeFeature = new Feature(feature);\n this.getFeatures(projectId);\n }\n },\n (error) => {\n // TODO: Add notification\n }\n );\n }\n\n getOverlays(projectId: number): void {\n this.http\n .get(environment.apiUrl + `/projects/${projectId}/overlays/`)\n .subscribe((ovs: Array<Overlay>) => {\n this._overlays.next(ovs);\n });\n }\n\n addOverlay(\n projectId: number,\n file: File,\n label: string,\n minLat: number,\n maxLat: number,\n minLon: number,\n maxLon: number\n ) {\n const payload = new FormData();\n payload.append('file', file);\n payload.append('label', label);\n payload.append('minLat', minLat.toFixed(6));\n payload.append('maxLat', maxLat.toFixed(6));\n payload.append('minLon', minLon.toFixed(6));\n payload.append('maxLon', maxLon.toFixed(6));\n\n this.http\n .post(environment.apiUrl + `/projects/${projectId}/overlays/`, payload)\n .subscribe((resp) => {\n this.getOverlays(projectId);\n });\n }\n\n // Call on getFeatures (each time feature update)\n getGroups(featureList: Feature[]): void {\n const groups = new Map<string, TagGroup>();\n const groupsFeatures = new Map<string, Feature[]>();\n featureList\n .filter(\n (feat: Feature) =>\n feat.properties.taggit.groups && feat.properties.taggit.groups.length > 0\n )\n .forEach((feat: Feature) => {\n feat.properties.taggit.groups.forEach((group: TagGroup) => {\n groupsFeatures.set(\n group.name,\n groupsFeatures.has(group.name)\n ? [...groupsFeatures.get(group.name), feat]\n : [feat]\n );\n groups.set(group.name, group);\n });\n });\n this._groups.next(groups);\n this._groupsFeatures.next(groupsFeatures);\n const activeGroup = this._activeGroup.value;\n if (activeGroup) {\n this.setActiveGroup(groups.get(activeGroup.name));\n }\n }\n\n getGroup(groupName: string) {\n return this._groups.value.get(groupName);\n }\n\n getGroupFeatures(featureList: Feature[], group: TagGroup) {\n return featureList.filter(\n (feat: Feature) =>\n feat.properties.taggit.groups &&\n feat.properties.taggit.groups.length &&\n feat.properties.taggit.groups.some((grp: TagGroup) => grp.id === group.id)\n );\n }\n\n private createGroup(\n featureList: Feature[],\n group: TagGroup,\n style?: FeatureStyles\n ): Feature[] {\n return featureList.map((feat: Feature) => {\n const groupProp = feat.properties.taggit.groups.filter((grp: TagGroup) => grp.id !== group.id);\n groupProp.push(group);\n feat.properties.taggit.groups = groupProp;\n feat.properties.style = style\n ? style\n : feat.properties.style\n ? feat.properties.style\n : {};\n\n return feat;\n });\n }\n\n private updateGroup(\n featureList: Feature[],\n group: TagGroup,\n style?: FeatureStyles\n ): Feature[] {\n return this.getGroupFeatures(featureList, group).map((feat: Feature) => {\n const groupProp = feat.properties.taggit.groups.filter(\n (grp: TagGroup) => grp.id !== group.id\n );\n groupProp.push(group);\n feat.properties.taggit.groups = groupProp;\n feat.properties.style = style\n ? style\n : feat.properties.style\n ? feat.properties.style\n : {};\n\n return feat;\n });\n }\n\n private deleteGroup(featureList: Feature[], group: TagGroup): Feature[] {\n return this.getGroupFeatures(featureList, group).map((feat: Feature) => {\n feat.properties.taggit.groups = feat.properties.taggit.groups.filter(\n (grp: TagGroup) => grp.id !== group.id\n );\n return feat;\n });\n }\n\n createNewGroup(projectId: number, featureList: Feature[], name: string) {\n const id = uuidv4();\n const myRandColor: string = getRandomColor();\n const group: TagGroup = {\n id,\n name,\n color: myRandColor,\n icon: 'fa-house-damage',\n };\n const style = {\n color: myRandColor,\n faIcon: 'fa-house-damage',\n };\n this.createGroupFeatures(projectId, featureList, group, style);\n return group;\n }\n\n createGroupFeatures(\n projectId: number,\n featureList: Feature[],\n group: TagGroup,\n style?: FeatureStyles\n ) {\n if (style) {\n this.createGroup(featureList, group, style).forEach((feat: Feature) => {\n this.updateFeatureProperty(projectId, feat.id, feat.properties);\n });\n } else {\n this.createGroup(featureList, group).forEach((feat: Feature) => {\n this.updateFeatureProperty(projectId, feat.id, feat.properties);\n });\n }\n }\n\n deleteGroupFeatures(\n projectId: number,\n featureList: Feature[],\n group: TagGroup\n ) {\n this.deleteGroup(featureList, group).forEach((feat: Feature) => {\n this.updateFeatureProperty(projectId, feat.id, feat.properties);\n });\n }\n\n updateGroupFeatures(\n projectId: number,\n featureList: Feature[],\n group: TagGroup,\n style?: FeatureStyles\n ) {\n if (style) {\n this.updateGroup(featureList, group, style).forEach((feat: Feature) => {\n this.updateFeatureProperty(projectId, feat.id, feat.properties);\n });\n } else {\n this.updateGroup(featureList, group).forEach((feat: Feature) => {\n this.updateFeatureProperty(projectId, feat.id, feat.properties);\n });\n }\n }\n\n renameGroup(\n projectId: number,\n featureList: Feature[],\n group: TagGroup,\n name: string\n ): void {\n const renamedGroup = {\n ...group,\n name,\n };\n\n this.updateGroupFeatures(projectId, featureList, renamedGroup);\n }\n\n reiconGroup(\n projectId: number,\n featureList: Feature[],\n group: TagGroup,\n icon: string\n ): void {\n const reiconedGroup = {\n ...group,\n icon,\n };\n\n const reiconedStyle = {\n faIcon: icon,\n color: group.color ? group.color : '#00C8FF',\n };\n\n this.updateGroupFeatures(\n projectId,\n featureList,\n reiconedGroup,\n reiconedStyle\n );\n }\n\n public get overlays(): Observable<Array<Overlay>> {\n return this._overlays.asObservable();\n }\n\n public get features(): Observable<FeatureCollection> {\n return this._features.asObservable();\n }\n\n public get activeFeature() {\n return this._activeFeature.asObservable();\n }\n\n // TODO: This is heinous\n public set activeFeature(f: any) {\n if (f) {\n if (f === this._activeFeature.getValue()) {\n this._activeFeature.next(null);\n } else {\n this._activeFeature.next(f);\n }\n } else {\n this._activeFeature.next(null);\n }\n }\n\n public get activeOverlay(): Observable<Overlay> {\n return this._activeOverlay.asObservable();\n }\n\n public set activeOverlay(ov) {\n this._activeOverlay.next(ov);\n }\n\n public get mapMouseLocation(): Observable<LatLng> {\n return this._mapMouseLocation.asObservable();\n }\n\n public set mapMouseLocation(loc) {\n this._mapMouseLocation.next(loc);\n }\n\n public set basemap(bmap) {\n this._basemap.next(bmap);\n }\n\n public get basemap(): any {\n return this._basemap.asObservable();\n }\n}\n","export function getRandomColor() {\n const letters = '0123456789ABCDEF';\n let color = '#';\n for (let i = 0; i < 6; i++) {\n color += letters[Math.floor(Math.random() * 16)];\n }\n return color;\n}\n","import { Component, OnInit } from '@angular/core';\nimport { GeoDataService } from '../../services/geo-data.service';\nimport { Feature } from '../../models/models';\nimport {\n AuthenticatedUser,\n AuthService,\n} from '../../services/authentication.service';\nimport { Observable } from 'rxjs';\nimport { BsModalRef, BsModalService } from 'ngx-foundation';\nimport { ModalFileBrowserComponent } from '../modal-file-browser/modal-file-browser.component';\nimport { RemoteFile } from 'ng-tapis';\n\n@Component({\n selector: 'app-main',\n templateUrl: './main.component.html',\n styleUrls: ['./main.component.scss'],\n})\nexport class MainComponent implements OnInit {\n // public activeFeature: Feature;\n // public currentUser: AuthenticatedUser;\n\n constructor(\n private geoDataService: GeoDataService,\n private authService: AuthService,\n private bsModalService: BsModalService\n ) {}\n\n ngOnInit() {\n // this.geoDataService.activeFeature.subscribe( next => {\n // this.activeFeature = next;\n // });\n // this.authService.currentUser.subscribe(next => this.currentUser = next);\n }\n}\n","import { Component, NgZone, OnInit } from '@angular/core';\nimport { ActivatedRoute, Router, Route } from '@angular/router';\nimport { AuthService } from '../../services/authentication.service';\n\n@Component({\n selector: 'app-callback',\n templateUrl: './callback.component.html',\n styleUrls: ['./callback.component.scss'],\n})\nexport class CallbackComponent implements OnInit {\n constructor(private route: ActivatedRoute, private auth: AuthService) {}\n\n ngOnInit() {\n // TODO: For some reason wso2 is sending back a fragment like #access_token=qadad&expires_in=3600\n const frag = this.route.snapshot.fragment;\n const params = new URLSearchParams(frag);\n const token = params.get('access_token');\n const expires_in = +params.get('expires_in');\n this.auth.setToken(token, expires_in);\n }\n}\n","import { Component, Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable, ReplaySubject, Subject } from 'rxjs';\nimport { Group, TagGroup, GroupForm, Tag, Project } from '../models/models';\nimport { map, first } from 'rxjs/operators';\nimport { FormControl, FormGroup, Validators } from '@angular/forms';\nimport { GeoDataService } from './geo-data.service';\nimport { prepareSyntheticListenerFunctionName } from '@angular/compiler/src/render3/util';\nimport { fadeInItems } from '@angular/material';\nimport { Feature, FeatureCollection } from 'geojson';\nimport { v4 as uuidv4 } from 'uuid';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class FormsService {\n constructor(private geoDataService: GeoDataService) {}\n\n deleteForm(\n projectId: number,\n form: GroupForm,\n activeGroup: TagGroup,\n featureGroups: Feature[]\n ): void {\n const taggedGroup: TagGroup = {\n ...activeGroup,\n forms: activeGroup.forms.filter((t: GroupForm) => t.id !== form.id),\n };\n\n this.geoDataService.updateGroupFeatures(\n projectId,\n featureGroups,\n taggedGroup\n );\n }\n\n renameForm(\n projectId: number,\n targetForm: GroupForm,\n activeGroup: TagGroup,\n featureGroups: Feature[],\n newName: string\n ): void {\n const taggedGroup: TagGroup = {\n ...activeGroup,\n forms: activeGroup.forms.map((form) => {\n if (form.id == targetForm.id) {\n form.label = newName;\n }\n return form;\n })\n }\n\n this.geoDataService.updateGroupFeatures(\n projectId,\n featureGroups,\n taggedGroup\n );\n }\n\n createForm(\n projectId: number,\n form: GroupForm,\n activeGroup: TagGroup,\n featureGroups: Feature[]\n ): void {\n const id = uuidv4();\n form = { ...form, id };\n const taggedGroup: TagGroup = {\n ...activeGroup,\n forms: activeGroup.forms ? [...activeGroup.forms, form] : [form],\n };\n this.geoDataService.updateGroupFeatures(\n projectId,\n featureGroups,\n taggedGroup\n );\n }\n\n checkDefault(selectedColor: string, feature: any) {\n if (selectedColor === 'default') {\n try {\n selectedColor = feature.styles.color;\n } catch (error) {\n selectedColor = '#00C8FF';\n }\n }\n return selectedColor;\n }\n\n // Inputs:\n // color:string A 7 digit hexadecimal string (#RRGGBB) passed in from a color tag\n // This method accesses group services to retrive the current group's icon as well\n saveStyles(\n projectId: number,\n featureList: Feature[],\n group: TagGroup,\n color?: string,\n icon?: string\n ) {\n const style = {\n color: color ? color : '#00C8FF',\n faIcon: icon ? icon : group.icon,\n };\n }\n\n updateTagValue(\n activeProject: Project,\n feature: Feature,\n form: GroupForm,\n tagValue: any\n ) {\n const tagProp = feature.properties.taggit.tags.filter((tag: Tag) => form.id !== tag.id);\n\n const tag = {\n id: form.id,\n value: tagValue,\n };\n\n feature.properties.taggit.tags = [...tagProp, tag];\n\n this.geoDataService.updateFeatureProperty(\n activeProject.id,\n feature.id,\n feature.properties\n );\n }\n\n updateTagValues(activeProject: Project, feature: Feature, newValues: any[]) {\n feature.properties.taggit.tags = newValues;\n this.geoDataService.updateFeatureProperty(\n activeProject.id,\n feature.id,\n feature.properties\n );\n }\n\n getTagValue(feature: Feature, form: GroupForm): any {\n if (feature && feature.properties.taggit.tags) {\n const tagValueObj = feature.properties.taggit.tags.find(\n (featTag: any) => featTag.id && featTag.id === form.id\n );\n\n if (tagValueObj) {\n return tagValueObj.value;\n }\n }\n if (form.type === 'checkbox') {\n return [];\n } else {\n return '';\n }\n }\n}\n\n// TODO: put this in models so we can reference it like we do the Features type\nexport interface tags {\n type: string;\n groupName: string;\n label: string;\n options: Array<Group>;\n feature: string | number;\n extra: Array<Group>;\n id?: string;\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable, ReplaySubject, Subject } from 'rxjs';\nimport { ProjectsService } from './projects.service';\nimport { Feature, TagGroup } from '../models/models';\n\n// Will inject Projects and GeoData Service to get properties of Feature\n@Injectable({\n providedIn: 'root',\n})\nexport class GroupsService {\n private _selectedImages: BehaviorSubject<Array<any>> = new BehaviorSubject(\n []\n );\n public selectedImages: Observable<Array<any>> =\n this._selectedImages.asObservable();\n\n private _showTagger: BehaviorSubject<boolean> = new BehaviorSubject(false);\n public showTagger: Observable<boolean> = this._showTagger.asObservable();\n\n private _showTagGenerator: BehaviorSubject<boolean> =\n new BehaviorSubject<boolean>(false);\n public showTagGenerator: Observable<boolean> =\n this._showTagGenerator.asObservable();\n\n private _groupToAdd: BehaviorSubject<TagGroup> = new BehaviorSubject({\n name: undefined,\n });\n public groupToAdd: Observable<TagGroup> = this._groupToAdd.asObservable();\n\n constructor() {}\n\n imageSelected(feature: Feature): boolean {\n const currentFeatures = this._selectedImages.value;\n return currentFeatures.some((feat) => feat.id === feature.id);\n }\n\n unselectAllImages() {\n this._selectedImages.next([]);\n }\n\n toggleImageSelect(feature: Feature): void {\n const currentFeatures = this._selectedImages.value;\n const newFeatures = this.imageSelected(feature)\n ? currentFeatures.filter((feat) => feat.id !== feature.id)\n : [feature, ...currentFeatures];\n\n this._selectedImages.next(newFeatures);\n }\n\n setSelectedImages(selectedImages: any): void {\n this._selectedImages.next(selectedImages);\n }\n\n setGroupToAdd(group: TagGroup): void {\n this._groupToAdd.next(group);\n }\n\n toggleTagger(): void {\n this._showTagger.next(!this._showTagger.value);\n }\n\n setShowTagGenerator(value: boolean): void {\n this._showTagGenerator.next(value);\n }\n}\n","import { Injectable } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { BehaviorSubject, Observable, ReplaySubject } from 'rxjs';\nimport { tap } from 'rxjs/operators';\nimport { Project, IProjectUser, ProjectRequest } from '../models/models';\nimport { environment } from '../../environments/environment';\nimport { AuthService } from './authentication.service';\nimport { NotificationsService } from './notifications.service';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ProjectsService {\n private _projects: BehaviorSubject<Project[]> = new BehaviorSubject([]);\n public readonly projects: Observable<Project[]> =\n this._projects.asObservable();\n private _activeProject: ReplaySubject<Project> = new ReplaySubject<Project>(\n 1\n );\n public readonly activeProject: Observable<Project> =\n this._activeProject.asObservable();\n private _projectUsers: ReplaySubject<Array<IProjectUser>> = new ReplaySubject<\n Array<IProjectUser>\n >(1);\n public readonly projectUsers$: Observable<Array<IProjectUser>> =\n this._projectUsers.asObservable();\n\n\n constructor(\n private http: HttpClient,\n private authService: AuthService,\n private notificationsService: NotificationsService\n ) {}\n\n testGeoApi(): void {\n const data = {\n name: 'Awesome Project',\n description: 'Cool project',\n };\n const prom = this.http\n .post<Project>(`http://localhost:8888/projects/`, data)\n .subscribe((resp) => {\n this._projects.next([...this._projects.value, resp]);\n // Set the active project to the one just created?\n this._activeProject.next(resp);\n });\n\n this.http\n .get<Project[]>(`http://localhost:8888/projects/`)\n .subscribe((resp) => {\n this._projects.next(resp);\n });\n }\n\n // Queries database for all user projects.\n getProjects(): void {\n this.http.get<Project[]>(environment.apiUrl + `/projects/`).subscribe(\n (projects) => {\n this._projects.next(projects);\n },\n (error) => {\n this.notificationsService.showErrorToast(\n 'Error getting projects DesignSafe or GeoAPI might be down'\n );\n }\n );\n }\n\n create(data: ProjectRequest) {\n this.http.post<Project>(\n environment.apiUrl + `/projects/`,\n data\n ).subscribe((proj) => {\n // Adding deletable attribute as missing from response https://jira.tacc.utexas.edu/browse/DES-2381\n proj = {...proj, deletable: true};\n this.setActiveProject(proj);\n this._projects.next([...this._projects.value, proj]);\n });\n }\n\n setActiveProject(proj: Project): void {\n // saves change as last visited project\n window.localStorage.setItem('lastProj', JSON.stringify(proj));\n try {\n this._activeProject.next(proj);\n } catch (error) {\n return error;\n }\n }\n\n update(data: ProjectRequest): void {\n this.http\n .put<Project>(environment.apiUrl + `/projects/${data.project.id}/`, data)\n .subscribe((resp) => {\n this._activeProject.next(resp);\n this.getProjects();\n });\n }\n\n // Note: This will delete the project for everyone, if the project is shared.\n delete(data: Project): void {\n this.http.delete(environment.apiUrl + `projects/${data.id}/`).subscribe(\n (resp) => {\n window.localStorage.removeItem('lastProj');\n this.getProjects();\n },\n (error) => {\n this.notificationsService.showErrorToast('Could not delete project!');\n console.error(error);\n }\n );\n }\n\n getProjectUsers(proj: Project): Observable<Array<IProjectUser>> {\n return this.http\n .get<Array<IProjectUser>>(\n environment.apiUrl + `/projects/${proj.id}/users/`\n )\n .pipe(\n tap((users) => {\n this._projectUsers.next(users);\n })\n );\n }\n\n addUserToProject(proj: Project, uname: string): void {\n const payload = {\n username: uname,\n };\n this.http\n .post(environment.apiUrl + `/projects/${proj.id}/users/`, payload)\n .subscribe((resp) => {\n this.getProjectUsers(proj).subscribe();\n });\n }\n\n deleteUserFromProject(proj: Project, user: string): void {\n this.http\n .delete(environment.apiUrl + `/projects/${proj.id}/users/${user}/`)\n .subscribe(\n (resp) => {\n this.getProjectUsers(proj).subscribe();\n },\n (error) => {\n // TODO: Create popup for an error message.\n console.log(error);\n }\n );\n }\n}\n","import {\n Component,\n OnInit,\n TemplateRef,\n ChangeDetectorRef,\n ChangeDetectionStrategy,\n} from '@angular/core';\nimport { FormsService, tags } from '../../../services/forms.service';\nimport { GroupsService } from '../../../services/groups.service';\nimport { MatDialog } from '@angular/material/dialog';\nimport { Router } from '@angular/router';\nimport { Subscription } from 'rxjs';\nimport { Feature, Project, TagGroup, GroupForm } from 'src/app/models/models';\nimport { GeoDataService } from 'src/app/services/geo-data.service';\nimport { ProjectsService } from 'src/app/services/projects.service';\n\n@Component({\n selector: 'app-tag-generator',\n templateUrl: './tag-generator.component.html',\n styleUrls: ['./tag-generator.component.scss'],\n})\nexport class TagGeneratorComponent implements OnInit {\n formLabel: string;\n formColor: string;\n formOptions: Array<any> = [];\n selectedGroup: string;\n formType: string;\n labelFilter: string;\n optionColorFilter = '#000000';\n activeGroup: TagGroup;\n optionFilter: string;\n formName: string;\n formValue: string;\n formRequired: boolean;\n openOption: any = {};\n enabledControls: Array<string> = [];\n showSubitem = true;\n groups: Map<string, TagGroup>;\n groupsFeatures: Map<string, any>;\n groups$: Subscription;\n private activeProject: Project;\n\n constructor(\n private formsService: FormsService,\n private groupsService: GroupsService,\n private dialog: MatDialog,\n private router: Router,\n private geoDataService: GeoDataService,\n private projectsService: ProjectsService\n ) {}\n\n ngOnInit() {\n this.geoDataService.activeGroup.subscribe((next) => {\n this.activeGroup = next;\n });\n\n this.geoDataService.groups.subscribe((next) => {\n this.groups = next;\n });\n\n this.geoDataService.groupsFeatures.subscribe((next) => {\n this.groupsFeatures = next;\n });\n\n this.projectsService.activeProject.subscribe((next) => {\n this.activeProject = next;\n });\n\n this.formOptions = [];\n this.formType = 'text';\n this.formName = '';\n this.formLabel = '';\n this.formValue = '';\n this.formRequired = false;\n this.enabledControls = ['Text', 'Checkbox', 'Radio', 'Dropdown', 'Color'];\n }\n\n inputFormLabel(event: any) {\n this.formLabel = event.target.value;\n }\n\n inputFormColor(event: any) {\n this.formColor = event.target.value;\n }\n\n addOptionItem(value: string) {\n if (value) {\n const formWithValue = this.formOptions.filter((e) => e.label == value);\n if (formWithValue.length == 0 && value.length != 0) {\n this.formOptions.push({\n label: value,\n color: this.optionColorFilter,\n });\n }\n }\n }\n\n deleteOption(opt: any) {\n this.formOptions = this.formOptions.filter(\n (option) => option.label != opt.label\n );\n }\n\n openRenameModal(template: TemplateRef<any>, name: string) {\n this.selectedGroup = name;\n this.dialog.open(template);\n }\n\n openRenameOptionModal(template: TemplateRef<any>) {\n this.dialog.open(template);\n }\n\n renameOption(opt: any, label: string) {\n label = label.toLowerCase();\n this.formOptions.forEach((e) => {\n if (e.label == opt.label) {\n e.label = label;\n }\n });\n }\n\n selectInputForm(name: string) {\n this.formType = name;\n this.formLabel = '';\n this.formOptions = [];\n }\n\n clearOption() {\n this.optionFilter = '';\n }\n\n clearLabel() {\n this.labelFilter = '';\n }\n\n clearOptionColor() {\n this.optionColorFilter = '#000000';\n }\n\n clear() {\n this.clearLabel();\n this.clearOptionColor();\n this.clearOption();\n }\n\n addFormItem() {\n // Assemble the new tag\n const formItem: GroupForm = {\n type: this.formType,\n groupName: this.activeGroup.name,\n label: this.formLabel,\n options: [],\n };\n this.openOption[this.formLabel] = false;\n // Adds the options for drop down, checklist, and radio buttons\n if (this.formType !== 'text' && this.formOptions.length != 0) {\n const myOpts = [];\n for (const opt of this.formOptions) {\n myOpts.push({\n label: opt,\n });\n }\n formItem.options = this.formOptions;\n }\n\n this.formsService.createForm(\n this.activeProject.id,\n formItem,\n this.groups.get(this.activeGroup.name),\n this.groupsFeatures.get(this.activeGroup.name)\n );\n\n // Reset user-defined fields to blank options\n this.formLabel = '';\n this.formColor = '';\n this.formOptions = [];\n this.groupsService.setShowTagGenerator(false);\n this.clear();\n }\n\n cancelCreate() {\n this.groupsService.setShowTagGenerator(false);\n this.clear();\n }\n\n expandPanel() {\n this.showSubitem = !this.showSubitem;\n }\n}\n","import { Component, OnInit, TemplateRef } from '@angular/core';\nimport { MatDialog } from '@angular/material/dialog';\nimport { Feature } from 'geojson';\nimport { combineLatest } from 'rxjs';\nimport { GroupForm, TagGroup } from 'src/app/models/models';\nimport { GeoDataService } from 'src/app/services/geo-data.service';\nimport { ProjectsService } from 'src/app/services/projects.service';\nimport { FormsService } from '../../../services/forms.service';\nimport { GroupsService } from '../../../services/groups.service';\n\n@Component({\n selector: 'app-tag-images',\n templateUrl: './tag-images.component.html',\n styleUrls: ['./tag-images.component.scss'],\n})\nexport class TagImagesComponent implements OnInit {\n private activeProject;\n payload: any;\n activeGroup: TagGroup;\n showSubitem = true;\n formList: GroupForm[] = [];\n tagName = '';\n groups: Map<string, TagGroup>;\n groupsFeatures: Map<string, Feature[]>;\n activeGroupFeature: Feature;\n tagValues = [];\n newTagValue = '';\n\n constructor(\n private groupsService: GroupsService,\n private formsService: FormsService,\n private dialog: MatDialog,\n private projectsService: ProjectsService,\n private geoDataService: GeoDataService\n ) { }\n\n ngOnInit() {\n combineLatest(\n this.geoDataService.activeGroup,\n this.geoDataService.groupsFeatures,\n this.geoDataService.groups\n ).subscribe(([grp, grpFts, grps]) => {\n this.activeGroup = grp;\n this.groupsFeatures = grpFts;\n this.groups = grps;\n if (grp) {\n this.formList = grp.forms;\n }\n });\n\n this.geoDataService.activeGroupFeature.subscribe((next) => {\n this.activeGroupFeature = next;\n });\n\n this.projectsService.activeProject.subscribe((next) => {\n this.activeProject = next;\n });\n }\n\n openRenameModal(template: TemplateRef<any>) {\n this.dialog.open(template);\n }\n\n // Takes the name of the tag's group, and the tag itself to delete\n deleteForm(tag: GroupForm) {\n this.formsService.deleteForm(\n this.activeProject.id,\n tag,\n this.groups.get(this.activeGroup.name),\n this.groupsFeatures.get(this.activeGroup.name)\n );\n }\n\n // submits a tag's name change to geoAPI\n renameForm(tag: GroupForm) {\n this.formsService.renameForm(\n this.activeProject.id,\n tag,\n this.groups.get(this.activeGroup.name),\n this.groupsFeatures.get(this.activeGroup.name),\n this.tagName\n );\n // Reset newTagValue for the next rename\n this.tagName = '';\n this.dialog.closeAll(); // Ensures the window closes when using enter-submission\n }\n\n showTagGenerator() {\n this.groupsService.setShowTagGenerator(true);\n }\n\n expandPanel() {\n this.showSubitem = !this.showSubitem;\n }\n}\n","import { Injectable, NgModule } from '@angular/core';\nimport {\n Routes,\n RouterModule,\n CanActivate,\n ActivatedRouteSnapshot,\n RouterStateSnapshot,\n} from '@angular/router';\nimport { NotFoundComponent } from './components/notfound/notfound.component';\nimport { AuthService } from './services/authentication.service';\nimport { MainComponent } from './components/main/main.component';\nimport { CallbackComponent } from './components/callback/callback.component';\nimport { TagGeneratorComponent } from './components/side-bar/tag-generator/tag-generator.component';\nimport { TagImagesComponent } from './components/side-bar/tag-images/tag-images.component';\n\n@Injectable()\nexport class Activate implements CanActivate {\n constructor(private authSvc: AuthService) {}\n\n canActivate(\n route: ActivatedRouteSnapshot,\n state: RouterStateSnapshot\n ): boolean {\n if (this.authSvc.isLoggedIn()) {\n return true;\n }\n this.authSvc.login();\n }\n}\n\nconst routes: Routes = [\n {\n path: '',\n component: MainComponent,\n canActivate: [Activate],\n children: [\n {\n path: 'tagger',\n component: TagImagesComponent,\n canActivateChild: [Activate],\n },\n {\n path: 'preset',\n component: TagGeneratorComponent,\n canActivateChild: [Activate],\n },\n ],\n },\n { path: 'callback', component: CallbackComponent },\n { path: '404', component: NotFoundComponent },\n];\n\n@NgModule({\n imports: [RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' })],\n exports: [RouterModule],\n providers: [Activate],\n})\nexport class AppRoutingModule {}\n","import { Component, OnInit } from '@angular/core';\nimport { AuthService } from './services/authentication.service';\n\n@Component({\n selector: 'app-root',\n templateUrl: './app.component.html',\n styleUrls: ['./app.component.scss'],\n})\nexport class AppComponent implements OnInit {\n title = 'viewer';\n\n constructor(private authService: AuthService) {}\n\n ngOnInit() {\n this.authService.login();\n }\n}\n","import {\n CircleMarker,\n circleMarker,\n divIcon,\n LatLng,\n Marker,\n marker,\n} from 'leaflet';\nimport { Feature } from '../models/models';\n\nfunction createCircleMarker(feature: Feature, latlng: LatLng): CircleMarker {\n const options = {\n radius: 8,\n fillColor: '#d3d3d3',\n color: 'black',\n weight: 1,\n opacity: 1,\n fillOpacity: 0.8,\n };\n return circleMarker(latlng, options);\n}\n\nfunction createImageMarker(feature: Feature, latlng: LatLng): Marker {\n const divHtml = '<i class=\\'fas fa-camera-retro fa-2x light-blue\\'></i>';\n const ico = divIcon({ className: 'leaflet-fa-marker-icon', html: divHtml });\n return marker(latlng, { icon: ico });\n}\n\nfunction createCollectionMarker(feature: Feature, latlng: LatLng): Marker {\n const divHtml = '<i class=\"fa fa-folder-open fa-2x light-blue\"></i>';\n const ico = divIcon({ className: 'icon-marker', html: divHtml });\n return marker(latlng, { icon: ico });\n}\nfunction createVideoMarker(feature: Feature, latlng: LatLng): Marker {\n const divHtml = '<i class=\\'fas fa-video fa-2x light-blue\\'></i>';\n const ico = divIcon({ className: 'leaflet-fa-marker-icon', html: divHtml });\n return marker(latlng, { icon: ico });\n}\n\nexport function createMarker(feature: Feature, latlng: LatLng): Marker {\n let marker;\n if (feature.featureType() == 'image') {\n marker = createImageMarker(feature, latlng);\n } else if (feature.featureType() == 'collection') {\n marker = createCollectionMarker(feature, latlng);\n } else if (feature.featureType() == 'video') {\n marker = createVideoMarker(feature, latlng);\n } else {\n marker = createCircleMarker(feature, latlng);\n }\n return marker;\n}\n","import { Component, OnInit } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport * as L from 'leaflet';\nimport 'leaflet.markercluster';\n\nimport { GeoDataService } from '../../services/geo-data.service';\nimport { createMarker } from '../../utils/leafletUtils';\nimport { Feature } from 'geojson';\nimport { FeatureGroup, ImageOverlay, LatLng, LeafletMouseEvent } from 'leaflet';\nimport * as turf from '@turf/turf';\nimport { AllGeoJSON } from '@turf/helpers';\nimport { filter, skip } from 'rxjs/operators';\nimport { Overlay } from '../../models/models';\nimport { AppEnvironment, environment } from '../../../environments/environment';\n\n@Component({\n selector: 'app-map',\n templateUrl: './map.component.html',\n styleUrls: ['./map.component.scss'],\n})\nexport class MapComponent implements OnInit {\n map: L.Map;\n mapType = 'normal';\n activeFeature: Feature;\n activeOverlay: Overlay;\n features: FeatureGroup = new FeatureGroup();\n overlays: Map<number, ImageOverlay>;\n environment: AppEnvironment;\n\n constructor(\n private GeoDataService: GeoDataService,\n private route: ActivatedRoute\n ) {\n // Have to bind these to keep this being this\n this.featureClickHandler.bind(this);\n this.mouseEventHandler.bind(this);\n }\n\n ngOnInit() {\n // const mapType: string = this.route.snapshot.queryParamMap.get('mapType');\n // this.projectId = +this.route.snapshot.paramMap.get(\"projectId\");\n // this.cluster = this.route.snapshot.queryParamMap.get('mapType');\n this.environment = environment;\n this.overlays = new Map();\n this.map = new L.Map('map', {\n center: [40, -80],\n zoom: 9,\n });\n\n const baseOSM = L.tileLayer(\n 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',\n {\n maxZoom: 19,\n attribution:\n '© <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors',\n }\n );\n const satellite = L.tileLayer(\n 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',\n {\n attribution:\n 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community',\n }\n );\n // default to streetmap view;\n this.map.addLayer(baseOSM);\n\n this.loadFeatures();\n\n // Publish the mouse location on the mapMouseLocation stream\n this.map.on('mousemove', (ev: LeafletMouseEvent) =>\n this.mouseEventHandler(ev)\n );\n this.GeoDataService.activeOverlay.pipe(skip(1)).subscribe((next) => {\n this.addRemoveOverlay(next);\n });\n\n // Listen on the activeFeature stream and zoom map to that feature when it changes\n this.GeoDataService.activeFeature\n .pipe(filter((n) => n != null))\n .subscribe((next) => {\n this.activeFeature = next;\n const bbox = turf.bbox(<AllGeoJSON> next);\n this.map.fitBounds([\n [bbox[1], bbox[0]],\n [bbox[3], bbox[2]],\n ]);\n });\n\n // Listen for changes to the basemap\n this.GeoDataService.basemap.pipe(skip(1)).subscribe((next) => {\n if (next == 'sat') {\n this.map.removeLayer(baseOSM);\n this.map.addLayer(satellite);\n }\n if (next == 'roads') {\n this.map.removeLayer(satellite);\n this.map.addLayer(baseOSM);\n }\n });\n }\n\n addRemoveOverlay(ov: Overlay): void {\n if (this.overlays.has(ov.id)) {\n this.features.removeLayer(this.overlays.get(ov.id));\n this.overlays.delete(ov.id);\n } else {\n const overlay = L.imageOverlay(\n environment.apiUrl + '/assets/' + ov.path,\n [\n [ov.minLat, ov.minLon],\n [ov.maxLat, ov.maxLon],\n ]\n );\n this.overlays.set(ov.id, overlay);\n this.features.addLayer(overlay);\n }\n this.map.fitBounds(this.features.getBounds());\n }\n\n mouseEventHandler(ev: any): void {\n this.GeoDataService.mapMouseLocation = ev.latlng;\n }\n\n /**\n * Load Features for a project.\n */\n loadFeatures() {\n const geojsonOptions = {\n pointToLayer: createMarker,\n };\n this.GeoDataService.features.subscribe((collection) => {\n this.features.clearLayers();\n const markers = L.markerClusterGroup({\n iconCreateFunction: (cluster) => {\n return L.divIcon({\n html: `<div><b>${cluster.getChildCount()}</b></div>`,\n className: 'marker-cluster',\n });\n },\n });\n collection.features.forEach((d) => {\n const feat = L.geoJSON(d, geojsonOptions);\n feat.on('click', (ev) => {\n this.featureClickHandler(ev);\n });\n\n if (d.geometry.type == 'Point') {\n markers.addLayer(feat);\n } else {\n this.features.addLayer(feat);\n }\n });\n this.features.addLayer(markers);\n this.map.addLayer(this.features);\n try {\n this.map.fitBounds(this.features.getBounds());\n } catch (e) {}\n });\n }\n\n /**\n *\n * @param ev\n */\n featureClickHandler(ev: any): void {\n const f = ev.layer.feature;\n this.GeoDataService.activeFeature = f;\n }\n}\n","import { Injectable } from '@angular/core';\nimport { SystemSummary } from 'ng-tapis';\nimport { ApiService } from 'ng-tapis';\nimport { Observable, ReplaySubject } from 'rxjs';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class AgaveSystemsService {\n private baseUrl = 'https://agave.designsafe-ci.org/systems/v2/';\n private _systems: ReplaySubject<SystemSummary[]> = new ReplaySubject<\n SystemSummary[]\n >(1);\n public readonly systems: Observable<SystemSummary[]> =\n this._systems.asObservable();\n private _projects: ReplaySubject<SystemSummary[]> = new ReplaySubject<\n SystemSummary[]\n >(1);\n public readonly projects: Observable<SystemSummary[]> =\n this._projects.asObservable();\n private systemsList: SystemSummary[];\n\n constructor(private tapis: ApiService) {}\n\n // list() runs when the file browser is opened, retrieves all files in TACC for given user\n list() {\n this.tapis.systemsList({ type: 'STORAGE' }).subscribe(\n (resp) => {\n this._systems.next(resp.result);\n this._projects.next(\n resp.result.filter((sys) => sys.id.startsWith('project'))\n );\n },\n (error) => {\n this._systems.next(null);\n this._projects.next(null);\n }\n );\n }\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport { ApiService, FileOperationRequest } from 'ng-tapis';\nimport { RemoteFile } from 'ng-tapis';\nimport { Project } from '../models/models';\nimport { share } from 'rxjs/operators';\nimport { HttpClient } from '@angular/common/http';\nimport { HttpHeaders } from '@angular/common/http';\nimport { environment } from '../../environments/environment';\nimport { AuthService } from './authentication.service';\nimport { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';\nimport { SystemSummary } from 'ng-tapis';\n// import { verify } from 'ts-mockito';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class TapisFilesService {\n private baseUrl = 'https://agave.designsafe-ci.org/files/v2/';\n public currentListing: Array<RemoteFile>;\n private _listing: BehaviorSubject<RemoteFile[]> = new BehaviorSubject<\n RemoteFile[]\n >([]);\n public readonly listing: Observable<RemoteFile[]> =\n this._listing.asObservable();\n public readonly IMPORTABLE_TYPES: Array<string> = [\n 'jpg',\n 'jpeg',\n 'las',\n 'laz',\n 'json',\n 'geojson',\n 'geotiff',\n 'tiff',\n 'gpx',\n ];\n public lastSystem: SystemSummary; // The last filesystem the user was browsing\n public lastFile: RemoteFile; // The last directory the user was browsing\n public noPreviousSelections: boolean;\n\n constructor(\n private tapis: ApiService,\n private http: HttpClient,\n private authService: AuthService,\n private popup: MatSnackBar\n ) {}\n\n checkIfSelectable(file: RemoteFile): boolean {\n if (file.type === 'dir') {\n return false;\n }\n const ext = this.getFileExtension(file);\n return this.IMPORTABLE_TYPES.includes(ext);\n }\n\n private getFileExtension(file: RemoteFile): string {\n return file.name.split('.').pop().toLowerCase();\n }\n\n listFiles(system: string, path: string, offset: number, limit: number) {\n return this.tapis.filesList({\n systemId: system,\n filePath: path,\n offset,\n limit,\n });\n }\n\n public getParentPath(path: string): string {\n const cleaned = path.replace('//', '/');\n const arr = cleaned.split('/');\n arr.pop();\n const parentPath = arr.join('/');\n return parentPath;\n }\n\n // saves project to a specified format in Design Safe's my Data section\n public export(\n systemID: string,\n path: string,\n fileName: string,\n extension: string,\n data: any\n ) {\n // Constructs an object that configures the success/error pop-up\n const snackbarConfig: MatSnackBarConfig = {\n duration: 3000,\n horizontalPosition: 'right',\n verticalPosition: 'top',\n };\n // construct the full URL that points to where the data will be stored\n const fullURL = `https://agave.designsafe-ci.org/files/v2/media/system/${systemID}${path}`;\n\n // construct a file to submit\n let fileType = 'plain/text';\n extension == '.csv'\n ? (fileType = 'text/csv')\n : (fileType = 'application/json');\n const tmp = new Blob([data], { type: fileType });\n const date = new Date();\n const file = new File([tmp], fileName, { lastModified: date.valueOf() });\n\n // Creates a form data object which holds the file to be uploaded\n const form: FormData = new FormData();\n form.append('fileToUpload', file);\n\n // sends the packaged data to Designsafe. URL its being uploaded to handles authentication\n this.http.post(fullURL, form).subscribe(\n (resp) => {\n console.log(resp);\n const msg = 'Successfully saved file to ' + systemID + path;\n this.popup.open(msg, '', snackbarConfig);\n },\n (error) => {\n console.log(error);\n const msg = 'Faled to save file to ' + systemID + path;\n this.popup.open(msg, '', snackbarConfig);\n }\n );\n }\n\n // Saves the current file directory and file system to Local Storage\n saveState() {\n const sysStr = JSON.stringify(this.lastSystem);\n const fileStr = JSON.stringify(this.lastFile);\n window.localStorage.setItem('system', sysStr);\n window.localStorage.setItem('file', fileStr);\n }\n\n // Attempts to retrieve the last used state\n getState() {\n try {\n this.lastSystem = JSON.parse(window.localStorage.getItem('system'));\n this.lastFile = JSON.parse(window.localStorage.getItem('file'));\n this.noPreviousSelections = this.lastFile == null;\n } catch (error) {\n console.log(error);\n }\n }\n}\n","import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';\nimport { AgaveSystemsService } from '../../services/agave-systems.service';\nimport {\n AuthenticatedUser,\n AuthService,\n} from '../../services/authentication.service';\nimport { RemoteFile } from 'ng-tapis/models/remote-file';\nimport { SystemSummary } from 'ng-tapis';\nimport { TapisFilesService } from '../../services/tapis-files.service';\nimport { BsModalRef } from 'ngx-foundation/modal/bs-modal-ref.service';\nimport { Subject, combineLatest } from 'rxjs';\nimport { MatDialog, MatDialogRef } from '@angular/material/dialog';\nimport { take } from 'rxjs/operators';\n\n@Component({\n selector: 'app-modal-file-browser',\n templateUrl: './modal-file-browser.component.html',\n styleUrls: ['./modal-file-browser.component.scss'],\n})\nexport class ModalFileBrowserComponent implements OnInit {\n static limit = 200; // Limits maximum amount of files displayed\n\n @Output() currentPath: EventEmitter<string> = new EventEmitter<string>();\n\n public allowedExtensions: Array<string> =\n this.tapisFilesService.IMPORTABLE_TYPES;\n\n private currentUser: AuthenticatedUser;\n public selectedPath;\n public filesList: Array<RemoteFile> = [];\n public inProgress = true;\n public retrievalError = false;\n public selectedFiles: Map<string, RemoteFile> = new Map();\n public onClose: Subject<Array<RemoteFile>> = new Subject<Array<RemoteFile>>();\n public projects: Array<SystemSummary>;\n private selectedSystem: SystemSummary;\n public myDataSystem: SystemSummary;\n public communityDataSystem: SystemSummary;\n public publishedDataSystem: SystemSummary;\n public currentDirectory: RemoteFile;\n private offset: number;\n public firstFileIndex: number;\n\n constructor(\n private tapisFilesService: TapisFilesService,\n // private modalRef: BsModalRef,\n public dialogRef: MatDialogRef<ModalFileBrowserComponent>,\n private dialog: MatDialog,\n private authService: AuthService,\n private agaveSystemsService: AgaveSystemsService\n ) {}\n\n ngOnInit() {\n // retrive state data\n // this.tapisFilesService.getState()\n\n // This finds all the projects, and file systems found from a user\n this.agaveSystemsService.list();\n\n // TODO: change those hard coded systemIds to environment vars or some sort of config\n // wait on the currentUser and systems to resolve\n combineLatest([\n this.authService.currentUser,\n this.agaveSystemsService.systems,\n this.agaveSystemsService.projects,\n ])\n // This little thing helped me fix the problem on calling ngOnInit several times\n .pipe(take(1))\n .subscribe(([user, systems, projects]) => {\n // Uses systems to find the different directories that has the files in\n this.myDataSystem = systems.find(\n (sys) => sys.id === 'designsafe.storage.default'\n );\n this.communityDataSystem = systems.find(\n (sys) => sys.id === 'designsafe.storage.community'\n );\n this.publishedDataSystem = systems.find(\n (sys) => sys.id === 'designsafe.storage.published'\n );\n\n // This is where they choose which one they start with\n this.selectedSystem = this.tapisFilesService.lastSystem;\n\n if (this.selectedSystem == null) {\n this.selectedSystem = this.myDataSystem;\n this.tapisFilesService.lastSystem = this.myDataSystem;\n }\n\n // If the user has already navigated to a folder, restore those options\n this.currentDirectory = this.tapisFilesService.lastFile;\n\n this.projects = projects;\n this.currentUser = user;\n const init = <RemoteFile> {\n system: this.myDataSystem.id,\n type: 'dir',\n path: this.currentUser.username,\n };\n // If the user hasn't yet opened the file browser, set the last file to an init file.\n if (this.tapisFilesService.noPreviousSelections) {\n this.selectedSystem = this.myDataSystem;\n this.tapisFilesService.lastFile = init;\n this.tapisFilesService.noPreviousSelections = false;\n }\n this.browse(this.tapisFilesService.lastFile);\n });\n }\n\n selectSystem(system: SystemSummary): void {\n let pth;\n system.id === this.myDataSystem.id\n ? (pth = this.currentUser.username)\n : (pth = '/');\n const init = <RemoteFile> {\n system: system.id,\n type: 'dir',\n path: pth,\n };\n this.selectedSystem = system;\n this.tapisFilesService.lastSystem = this.selectedSystem;\n this.browse(init);\n }\n\n browse(file: RemoteFile) {\n this.selectedPath = file.path;\n this.selectedSystem = this.selectedSystem; // Self-assignment keeps the system name from disappearing while browsing subfolders\n if (file.type !== 'dir') {\n return;\n }\n this.currentDirectory = file;\n this.tapisFilesService.lastFile = file; // Updates the last directory visted\n // this.selectedFiles.clear();\n this.filesList = [];\n this.offset = 0;\n this.inProgress = false;\n this.getFiles();\n }\n\n toRoot() {\n let pth;\n this.selectedSystem.id === this.myDataSystem.id\n ? (pth = this.currentUser.username)\n : (pth = '/');\n const init = <RemoteFile> {\n system: this.selectedSystem.id,\n type: 'dir',\n path: pth,\n };\n this.browse(init);\n }\n\n getFiles() {\n const hasMoreFiles = this.offset % ModalFileBrowserComponent.limit === 0;\n\n if (this.inProgress || !hasMoreFiles) {\n return;\n }\n\n this.inProgress = true;\n this.tapisFilesService\n .listFiles(\n this.currentDirectory.system,\n this.currentDirectory.path,\n this.offset,\n ModalFileBrowserComponent.limit\n )\n .subscribe(\n (listing) => {\n const files = listing.result;\n\n if (files.length && files[0].name === '.') {\n // This removes the first item in the listing, which in Agave\n // is always a reference to self '.' and replaces with '..'\n const current = files.shift();\n this.currentPath.next(current.path);\n current.path = this.tapisFilesService.getParentPath(current.path);\n current.name = '..';\n files.unshift(current);\n }\n const newFile = [];\n const allowedExt = this.allowedExtensions;\n files.forEach(function(value, index) {\n if (\n (value.type == 'file' &&\n allowedExt.includes(\n value.path.split('.').pop().toLowerCase()\n )) ||\n value.type == 'dir'\n ) {\n newFile.push(value);\n }\n });\n\n this.inProgress = false;\n this.retrievalError = false;\n this.filesList = this.filesList.concat(newFile);\n this.offset = this.offset + files.length;\n },\n (error) => {\n // If retrieving the files from DesignSafe bugs out due to the site being down, this is where it ends up\n this.retrievalError = true;\n this.inProgress = false;\n }\n );\n }\n\n // TODO: Ian: Error message on incorrect file type?\n select(event: any, file: RemoteFile, index: number) {\n if (event.shiftKey) {\n this.selectFilesShiftClick(index, file);\n } else {\n if (this.tapisFilesService.checkIfSelectable(file)) {\n this.addSelectedFile(file, index);\n } else {\n }\n }\n }\n\n selectFilesShiftClick(index: number, file: RemoteFile) {\n // this.selectedFiles.clear();\n this.selectShift(index, file);\n }\n\n addSelectedFile(file: RemoteFile, index: number) {\n if (index != -1) {\n this.firstFileIndex = index;\n }\n\n if (this.tapisFilesService.checkIfSelectable(file)) {\n if (this.selectedFiles.has(file.path)) {\n this.selectedFiles.delete(file.path);\n } else {\n this.selectedFiles.set(file.path, file);\n }\n }\n }\n\n chooseFiles() {\n this.tapisFilesService.saveState();\n this.tapisFilesService.lastSystem = this.selectedSystem;\n const tmp = Array.from(this.selectedFiles.values());\n this.dialogRef.close(tmp);\n }\n\n cancel() {\n this.tapisFilesService.saveState();\n this.tapisFilesService.lastSystem = this.selectedSystem;\n this.dialogRef.close();\n }\n\n selectAll() {\n const indexTmp = -1;\n let count = 0;\n for (const file of this.filesList) {\n if (!this.selectedFiles.has(file.path)) {\n this.select('', file, indexTmp);\n count += 1;\n }\n }\n if (count == 1) {\n this.selectedFiles.clear();\n }\n }\n\n selectShift(index: number, file: RemoteFile) {\n if (this.firstFileIndex != undefined && this.firstFileIndex != index) {\n this.addRangeFiles(this.firstFileIndex, index, true);\n } else {\n this.addSelectedFile(file, index);\n }\n }\n\n addRangeFiles(firstFileIndex: number, lastFileIndex: number, again: boolean) {\n const maxIndex = Math.max(firstFileIndex, lastFileIndex);\n const minIndex = Math.min(firstFileIndex, lastFileIndex);\n\n for (let i = minIndex; i < maxIndex + 1; ++i) {\n this.addSelectedFile(this.filesList[i], -1);\n }\n\n if (again) {\n this.addSelectedFile(this.filesList[firstFileIndex], -1);\n }\n }\n}\n","import { Component, OnInit, Output, EventEmitter } from '@angular/core';\nimport { AgaveSystemsService } from '../../services/agave-systems.service';\nimport {\n AuthenticatedUser,\n AuthService,\n} from '../../services/authentication.service';\nimport { RemoteFile } from 'ng-tapis/models/remote-file';\nimport { SystemSummary } from 'ng-tapis';\nimport { TapisFilesService } from '../../services/tapis-files.service';\nimport { BsModalRef } from 'ngx-foundation/modal/bs-modal-ref.service';\nimport { Subject, combineLatest } from 'rxjs';\nimport { MatDialog, MatDialogRef } from '@angular/material/dialog';\nimport { take } from 'rxjs/operators';\nimport { FormGroup, FormControl } from '@angular/forms';\n\n@Component({\n selector: 'app-modal-download-selector',\n templateUrl: './modal-download-selector.component.html',\n styleUrls: ['./modal-download-selector.component.scss'],\n})\nexport class ModalDownloadSelectorComponent implements OnInit {\n static limit = 200; // Limits maximum amount of files displayed\n\n @Output() currentPath: EventEmitter<string> = new EventEmitter<string>();\n\n private downloadSelectForm: FormGroup;\n private currentUser: AuthenticatedUser;\n public filesList: Array<RemoteFile> = [];\n public inProgress = true;\n public selectedFiles: Map<string, RemoteFile> = new Map();\n public onClose: Subject<Array<RemoteFile>> = new Subject<Array<RemoteFile>>();\n public projects: Array<SystemSummary>;\n private selectedSystem: SystemSummary;\n public myDataSystem: SystemSummary;\n public communityDataSystem: SystemSummary;\n public publishedDataSystem: SystemSummary;\n public currentDirectory: RemoteFile;\n public passbackData: Array<string> = ['', '', '', ''];\n public fileName = 'Custom File Name';\n public fileExtension = '.csv';\n private offset: number;\n\n constructor(\n private tapisFilesService: TapisFilesService,\n // private modalRef: BsModalRef,\n public dialogRef: MatDialogRef<ModalDownloadSelectorComponent>,\n private dialog: MatDialog,\n private authService: AuthService,\n private agaveSystemsService: AgaveSystemsService\n ) {}\n\n ngOnInit() {\n this.downloadSelectForm = new FormGroup({\n Name: new FormControl(this.fileName),\n Extension: new FormControl(this.fileExtension),\n });\n\n // This finds all the projects, and file systems found from a user\n this.agaveSystemsService.list();\n\n // TODO: change those hard coded systemIds to environment vars or some sort of config\n // wait on the currentUser and systems to resolve\n combineLatest([\n this.authService.currentUser,\n this.agaveSystemsService.systems,\n this.agaveSystemsService.projects,\n ])\n // This little thing helped me fix the problem on calling ngOnInit several times\n .pipe(take(1))\n .subscribe(([user, systems, projects]) => {\n // Uses systems to find the different directories that has the files in\n this.myDataSystem = systems.find(\n (sys) => sys.id === 'designsafe.storage.default'\n );\n this.communityDataSystem = systems.find(\n (sys) => sys.id === 'designsafe.storage.community'\n );\n this.publishedDataSystem = systems.find(\n (sys) => sys.id === 'designsafe.storage.published'\n );\n\n // This is where they choose which one they start with\n this.selectedSystem = this.myDataSystem;\n\n this.projects = projects;\n this.currentUser = user;\n const init = <RemoteFile> {\n system: this.myDataSystem.id,\n type: 'dir',\n path: this.currentUser.username,\n };\n this.browse(init);\n });\n }\n\n selectSystem(system: SystemSummary): void {\n let pth;\n system.id === this.myDataSystem.id\n ? (pth = this.currentUser.username)\n : (pth = '/');\n const init = <RemoteFile> {\n system: system.id,\n type: 'dir',\n path: pth,\n };\n this.browse(init);\n }\n\n browse(file: RemoteFile) {\n if (file.type !== 'dir') {\n return;\n }\n this.currentDirectory = file;\n // this.selectedFiles.clear();\n this.filesList = [];\n this.offset = 0;\n this.inProgress = false;\n this.getFiles();\n }\n\n getFiles() {\n const hasMoreFiles =\n this.offset % ModalDownloadSelectorComponent.limit === 0;\n\n if (this.inProgress || !hasMoreFiles) {\n return;\n }\n\n this.inProgress = true;\n\n this.tapisFilesService\n .listFiles(\n this.currentDirectory.system,\n this.currentDirectory.path,\n this.offset,\n ModalDownloadSelectorComponent.limit\n )\n .subscribe(\n (listing) => {\n const files = listing.result;\n\n if (files.length && files[0].name === '.') {\n // This removes the first item in the listing, which in Agave\n // is always a reference to self '.' and replaces with '..'\n const current = files.shift();\n this.currentPath.next(current.path);\n this.passbackData[1] = current.path;\n current.path = this.tapisFilesService.getParentPath(current.path);\n current.name = '..';\n files.unshift(current);\n }\n const newFile = [];\n files.forEach(function(value, index) {\n if (value.type == 'file' || value.type == 'dir') {\n newFile.push(value);\n }\n });\n\n this.inProgress = false;\n this.filesList = this.filesList.concat(newFile);\n this.offset = this.offset + files.length;\n },\n (error) => {\n this.inProgress = false;\n }\n );\n }\n\n chooseFiles() {\n this.passbackData[0] = this.selectedSystem.id;\n\n // checks to see if the input was left unchanged\n if (this.downloadSelectForm.dirty) {\n // if changed, enter name as specified\n this.passbackData[2] = this.downloadSelectForm.get('Name').value;\n } else {\n // if unchanged, enter filename as empty string\n this.passbackData[2] = '';\n }\n this.passbackData[3] = this.fileExtension;\n this.dialogRef.close(this.passbackData);\n }\n\n cancel() {\n this.dialogRef.close();\n }\n}\n","import { Component, OnInit } from '@angular/core';\nimport { BsModalService, BsModalRef } from 'ngx-foundation';\nimport { FormGroup, FormControl } from '@angular/forms';\nimport { ProjectsService } from '../../services/projects.service';\nimport { Project, ProjectRequest } from '../../models/models';\nimport { MatDialog, MatDialogRef } from '@angular/material/dialog';\nimport { Subject } from 'rxjs';\n\n@Component({\n selector: 'app-modal-create-project',\n templateUrl: './modal-create-project.component.html',\n styleUrls: ['./modal-create-project.component.scss'],\n})\nexport class ModalCreateProjectComponent implements OnInit {\n public readonly onClose: Subject<any> = new Subject<any>();\n\n projCreateForm: FormGroup;\n\n constructor(\n public dialogRef: MatDialogRef<ModalCreateProjectComponent>,\n private dialog: MatDialog,\n private projectsService: ProjectsService\n ) {}\n\n ngOnInit() {\n this.projCreateForm = new FormGroup({\n name: new FormControl(''),\n description: new FormControl(''),\n });\n }\n\n close(project: Project) {\n this.dialogRef.close();\n }\n\n submit() {\n // Watch content we can set to false, for our project, we don't need this yet.\n // Watch content refers to syncing files created in a folder with a hazmapper map\n // Set observable to true, Hazmapper doesn't let users define that value for some reason.\n const proj = new Project();\n const projRqst = new ProjectRequest();\n\n // Retrieve project name and description\n proj.description = this.projCreateForm.get('description').value;\n proj.name = this.projCreateForm.get('name').value;\n\n projRqst.project = proj;\n\n this.projectsService.create(projRqst);\n this.dialogRef.close();\n }\n}\n","import { Component, OnInit } from '@angular/core';\nimport { MatDialog, MatDialogRef } from '@angular/material/dialog';\nimport { FormGroup, FormControl } from '@angular/forms';\nimport { ProjectsService } from '../../services/projects.service';\nimport { Project } from '../../models/models';\nimport { THIS_EXPR } from '@angular/compiler/src/output/output_ast';\n\n@Component({\n selector: 'app-modal-share-project',\n templateUrl: './modal-share-project.component.html',\n styleUrls: ['./modal-share-project.component.scss'],\n})\nexport class ModalShareProjectComponent implements OnInit {\n projShareForm: FormGroup;\n activeProj: Project;\n projectUsers;\n onlyOne: boolean; // if only one user is present == TRUE\n\n constructor(\n public dialogRef: MatDialogRef<ModalShareProjectComponent>,\n private dialog: MatDialog,\n private projectsService: ProjectsService\n ) {}\n\n ngOnInit() {\n // creates new form control group to access input value\n this.projShareForm = new FormGroup({\n name: new FormControl(''),\n });\n\n // retrieves active project, needed to add users to the project\n this.projectsService.activeProject.subscribe((proj) => {\n this.activeProj = proj;\n });\n\n // retrieves all users currently registered to the active project\n this.projectsService.getProjectUsers(this.activeProj).subscribe((next) => {\n this.projectUsers = next;\n this.onlyOne = this.projectUsers.length == 1;\n });\n }\n\n // closes modal without submitting anything\n close() {\n this.dialogRef.close();\n }\n\n // shares project with specified user\n submit() {\n this.projectsService.addUserToProject(\n this.activeProj,\n this.projShareForm.get('name').value\n );\n this.dialogRef.close();\n }\n\n // deletes user from project\n delete(user) {\n this.projectsService.deleteUserFromProject(this.activeProj, user);\n this.dialogRef.close();\n }\n}\n","import { Component, OnInit, Inject } from '@angular/core';\nimport { BsModalService, BsModalRef } from 'ngx-foundation';\nimport { FormGroup, FormControl } from '@angular/forms';\nimport { ProjectsService } from '../../services/projects.service';\nimport { Project, ProjectRequest } from '../../models/models';\nimport {\n MAT_DIALOG_DATA,\n MatDialog,\n MatDialogRef,\n} from '@angular/material/dialog';\n\n@Component({\n selector: 'app-modal-current-project',\n templateUrl: './modal-current-project.component.html',\n styleUrls: ['./modal-current-project.component.scss'],\n})\nexport class ModalCurrentProjectComponent implements OnInit {\n projCreateForm: FormGroup;\n activeProject: Project;\n\n constructor(\n public dialogRef: MatDialogRef<ModalCurrentProjectComponent>,\n private dialog: MatDialog,\n private projectsService: ProjectsService,\n @Inject(MAT_DIALOG_DATA) public projData: any\n ) {}\n\n ngOnInit() {\n this.projectsService.activeProject.subscribe((next) => {\n this.activeProject = next;\n });\n\n this.projCreateForm = new FormGroup({\n name: new FormControl(this.activeProject.name),\n description: new FormControl(this.activeProject.description),\n });\n }\n\n close() {\n this.dialogRef.close();\n }\n\n delete() {\n if (\n confirm(\n 'Are you sure you want to delete this project? This will also delete it from HazMapper, and anyone this project was shared with.'\n )\n ) {\n this.projectsService.delete(this.activeProject);\n }\n this.dialogRef.close();\n }\n\n update() {\n const p = new Project();\n const projRqst = new ProjectRequest();\n\n p.description = this.projCreateForm.get('description').value;\n p.name = this.projCreateForm.get('name').value;\n p.id = this.activeProject.id;\n p.uuid = this.activeProject.uuid;\n\n projRqst.project = p;\n\n this.projectsService.update(projRqst);\n this.dialogRef.close();\n }\n}\n","import { Injectable } from '@angular/core';\nimport { Feature, FeatureCollection } from '../models/models';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport { GeoDataService } from './geo-data.service';\nimport { feature } from '@turf/turf';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class FeatureService {\n private featureCollection: FeatureCollection;\n private _features: BehaviorSubject<FeatureCollection>;\n public features$: Observable<FeatureCollection>;\n\n constructor(private geoDataService: GeoDataService) {\n this._features = new BehaviorSubject<FeatureCollection>({\n type: 'FeatureCollection',\n features: [],\n });\n this.features$ = this._features.asObservable();\n\n this.geoDataService.features.subscribe((fc: FeatureCollection) => {\n this._features.next(fc);\n this.featureCollection = fc;\n });\n }\n\n // Takes the feature to be deleted, and filters it out of the feature list\n deleteFeature(feat: Feature): void {\n this.featureCollection.features = this.featureCollection.features.filter(\n (featListfeat) => featListfeat.id != feat.id\n );\n this._features.next(this.featureCollection); // Update the observable\n this.geoDataService.deleteFeature(feat);\n }\n\n // Takes a list of features, and deletes them from the observable in a more efficient manner\n bulkFeatureDelete(delFeats: Array<Feature>): void {\n delFeats.forEach((feat) => {\n // Filter out every feature in delFeats from the master list\n this.featureCollection.features = this.featureCollection.features.filter(\n (featListFeature) => featListFeature.id != feat.id\n );\n this.geoDataService.deleteFeature(feat);\n });\n this._features.next(this.featureCollection); // Update the observable with the filtered list\n }\n\n saveFeature(feat: Feature): void {\n this.geoDataService.updateFeatureProperty(\n feat.project_id,\n Number(feat.id),\n feat.properties\n );\n }\n\n // Takes a feature, and optionally an updated property section\n // If featprop is null, it assumes the passed in feature was already updated with the new properties\n updateFeatureProperties(feature: Feature, featProp = null): void {\n // If featprop has a value, update the feature's properties to the new section\n if (featProp != null) {\n feature.properties = featProp;\n }\n // Update and save the list\n this.featureCollection.features.forEach((feat) => {\n if (feat.id == feature.id) {\n feat = feature;\n }\n });\n this.saveFeature(feature);\n }\n}\n","import {\n Component,\n OnInit,\n Output,\n TemplateRef,\n ChangeDetectorRef,\n} from '@angular/core';\nimport { ProjectsService } from '../../services/projects.service';\nimport { Feature, Project, TagGroup } from '../../models/models';\nimport { FeatureCollection } from 'geojson';\nimport { GeoDataService } from '../../services/geo-data.service';\nimport { LatLng } from 'leaflet';\nimport { skip } from 'rxjs/operators';\nimport { BsModalRef, BsModalService } from 'ngx-foundation';\nimport { ModalFileBrowserComponent } from '../modal-file-browser/modal-file-browser.component';\nimport { ModalDownloadSelectorComponent } from '../modal-download-selector/modal-download-selector.component';\nimport { ModalCreateProjectComponent } from '../modal-create-project/modal-create-project.component';\nimport { ModalShareProjectComponent } from '../modal-share-project/modal-share-project.component';\nimport { combineLatest } from 'rxjs';\nimport { RemoteFile } from 'ng-tapis';\nimport { GroupsService } from '../../services/groups.service';\nimport { FormsService } from '../../services/forms.service';\nimport {\n AuthenticatedUser,\n AuthService,\n} from '../../services/authentication.service';\nimport { Router } from '@angular/router';\nimport { MatDialog } from '@angular/material/dialog';\nimport { ModalCurrentProjectComponent } from '../modal-current-project/modal-current-project.component';\nimport { environment } from '../../../environments/environment';\nimport { TapisFilesService } from '../../services/tapis-files.service';\n\nimport { ScrollService } from 'src/app/services/scroll.service';\nimport { NotificationsService } from 'src/app/services/notifications.service';\nimport { FeatureService } from 'src/app/services/feature.service';\nimport * as JSZip from 'jszip';\n\n@Component({\n selector: 'app-control-bar',\n templateUrl: './control-bar.component.html',\n styleUrls: ['./control-bar.component.scss'],\n})\nexport class ControlBarComponent implements OnInit {\n public activeFeature: Feature;\n features: FeatureCollection;\n featureList: Array<any> = [];\n\n public currentUser: AuthenticatedUser;\n public projects: Project[];\n public selectedProject: Project;\n public mapMouseLocation: LatLng = new LatLng(0, 0);\n imageName: string;\n groupsExist: boolean;\n groupName: string;\n showTagger = false;\n selectedImages: Array<any>;\n modalRef: BsModalRef;\n activeGroup: TagGroup;\n groups: Map<string, TagGroup>;\n groupsFeatures: Map<string, any>;\n activeGroupFeatures: any;\n activeGroupFeaturesRotate: any;\n activeGroupFeature: any;\n invalidNameError = false;\n existingNameError = false;\n hazmapperLink: string;\n foundFilePaths = [];\n groupToAdd: TagGroup;\n public activeProject: Project;\n tagFeaturesQueue: any;\n\n constructor(\n private projectsService: ProjectsService,\n private geoDataService: GeoDataService,\n private bsModalService: BsModalService,\n private groupsService: GroupsService,\n private formsService: FormsService,\n private authService: AuthService,\n private readonly cdr: ChangeDetectorRef,\n private filesService: TapisFilesService,\n private router: Router,\n private dialog: MatDialog,\n private scrollService: ScrollService,\n private notificationsService: NotificationsService,\n private featureService: FeatureService\n ) {}\n\n ngOnInit() {\n this.filesService.getState();\n\n this.groupsService.groupToAdd.subscribe((next) => {\n console.log(next);\n this.groupToAdd = next;\n });\n\n this.geoDataService.tagFeaturesQueue.subscribe((next) => {\n this.tagFeaturesQueue = next;\n });\n\n this.featureService.features$.subscribe((fc: FeatureCollection) => {\n this.features = fc;\n\n if (this.features != undefined) {\n this.featureList = fc.features.filter(\n (feature: Feature) =>\n feature.assets.length &&\n feature.initialAsset() &&\n feature.featureType() === 'image'\n );\n }\n });\n\n this.geoDataService.groups.subscribe((next) => {\n this.groups = next;\n this.groupsExist = next && next.size ? true : false;\n });\n\n this.projectsService.activeProject.subscribe((next) => {\n this.activeProject = next;\n });\n\n combineLatest(\n this.geoDataService.activeGroup,\n this.geoDataService.groupsFeatures\n ).subscribe(([grp, grpFts]) => {\n this.activeGroup = grp;\n this.groupsFeatures = grpFts;\n if (grp && grpFts) {\n this.activeGroupFeatures = grpFts.get(grp.name);\n if (this.activeGroupFeatures) {\n this.activeGroupFeaturesRotate = [...this.activeGroupFeatures];\n }\n }\n });\n\n this.geoDataService.activeGroupFeature.subscribe((next) => {\n this.activeGroupFeature = next;\n });\n\n this.geoDataService.activeFeature.subscribe((next) => {\n this.activeFeature = next;\n });\n\n this.notificationsService.notifications.subscribe((next) => {\n const hasSuccessNotification = next.some(\n (note) => note.status === 'success'\n );\n const hasFailureNotification = next.some(\n (note) => note.status === 'error'\n );\n if (hasSuccessNotification) {\n this.geoDataService.getFeatures(this.selectedProject.id);\n }\n if (hasFailureNotification) {\n next.forEach((item) => {\n // Compiles a list of all necessary files to import via the alt method\n // The substring from 0 to 16 contains the phrase \"Error importing\", everything after this is the file path\n if (\n item.message.substring(0, 16) == 'Error importing ' &&\n !this.foundFilePaths.some(\n (filePath) => filePath === item.message.substring(16)\n )\n ) {\n const path = item.message.substring(16);\n this.geoDataService.uploadNewFeature(\n this.selectedProject.id,\n this.createBlankFeature(),\n path\n );\n this.foundFilePaths.push(path);\n }\n });\n this.geoDataService.getFeatures(this.selectedProject.id);\n }\n });\n\n this.authService.currentUser.subscribe((next) => (this.currentUser = next));\n\n this.projectsService.getProjects();\n this.projectsService.projects.subscribe((projects) => {\n this.projects = projects;\n\n // restores view to the last visited project from local storage\n let lastProject = null;\n try {\n lastProject = JSON.parse(window.localStorage.getItem('lastProj'));\n } catch (error) {\n // possible that lastProj item is null and not json\n lastProject = null;\n }\n\n if (projects.length) {\n const selectedLastProject = lastProject\n ? this.projects.find((prj) => prj.id === lastProject.id)\n : null;\n if (selectedLastProject) {\n this.projectsService.setActiveProject(selectedLastProject);\n } else {\n // default to the first project in the list\n this.projectsService.setActiveProject(this.projects[0]);\n }\n }\n\n this.groupsService.selectedImages.subscribe((next) => {\n this.selectedImages = next;\n });\n\n this.groupsService.showTagger.subscribe((next) => {\n this.showTagger = next;\n });\n });\n\n this.projectsService.activeProject.subscribe((next) => {\n this.selectedProject = next;\n if (this.selectedProject) {\n this.getDataForProject(this.selectedProject);\n // retrieves uuid for project, formats result into a link to that Hazmapper map\n this.hazmapperLink =\n 'https://hazmapper.tacc.utexas.edu/hazmapper/project/' + next.uuid;\n }\n });\n\n this.geoDataService.mapMouseLocation.pipe(skip(1)).subscribe((next) => {\n this.mapMouseLocation = next;\n });\n }\n\n ngAfterViewChecked() {\n this.cdr.detectChanges();\n }\n\n clearAll() {\n this.groupsService.unselectAllImages();\n }\n\n compareGroup(a, b) {\n return a.name === b.name;\n }\n\n changeGroupToAdd(ev: any) {\n this.groupsService.setGroupToAdd(ev.value);\n }\n\n selectProject(p: Project): void {\n this.projectsService.setActiveProject(p);\n }\n\n getDataForProject(p: Project): void {\n this.geoDataService.getFeatures(p.id);\n this.geoDataService.getOverlays(p.id);\n this.geoDataService.getPointClouds(p.id);\n }\n\n openFilePicker() {\n // Refreshes the list of found paths used in importing images without Geo tagging\n this.foundFilePaths = [];\n const modal = this.dialog.open(ModalFileBrowserComponent);\n modal.afterClosed().subscribe((files: Array<RemoteFile>) => {\n if (files != null) {\n this.geoDataService.importFileFromTapis(this.selectedProject.id, files);\n }\n });\n }\n\n // Creates a feature with a long/lat value of 0,0 and no associated image. Used in alternate image inport\n // I think if we want a placeholder image, we can add it here.\n createBlankFeature() {\n const blankFeature: Feature = {\n type: 'Feature',\n geometry: {\n type: 'Point',\n coordinates: [0, 0],\n },\n properties: {},\n };\n return blankFeature;\n }\n\n openDownloadSelector(fileName: string) {\n const modal = this.dialog.open(ModalDownloadSelectorComponent);\n let path: Array<string>;\n modal.afterClosed().subscribe((passbackData: Array<string>) => {\n path = passbackData;\n this.saveFile(path[3] == '.json', true, path[0], path[1], path[2]);\n });\n }\n\n openCreateProjectModal() {\n this.dialog.open(ModalCreateProjectComponent, {\n height: '400px',\n width: '600px',\n });\n }\n\n openShareProjectModal() {\n this.dialog.open(ModalShareProjectComponent, {\n height: '400px',\n width: '600px',\n });\n }\n\n openProjectModal(project) {\n const modal = this.dialog.open(ModalCurrentProjectComponent, {\n height: '400px',\n width: '600px',\n data: {\n id: project.id,\n name: project.name,\n description: project.description,\n uuid: project.uuid,\n },\n });\n }\n\n addGroup(name: string) {\n this.groupName = name;\n if (!name || 0 === name.length) {\n this.invalidNameError = true;\n this.existingNameError = false;\n } else if (this.groups.get(name)) {\n this.invalidNameError = false;\n this.existingNameError = true;\n } else {\n this.invalidNameError = false;\n this.existingNameError = false;\n const newGroup = this.geoDataService.createNewGroup(\n this.selectedProject.id,\n this.selectedImages,\n name\n );\n this.dialog.closeAll();\n this.groupsService.unselectAllImages();\n }\n }\n\n addToGroup(group: TagGroup) {\n this.geoDataService.createGroupFeatures(\n this.activeProject.id,\n this.selectedImages,\n this.groups.get(group.name)\n );\n this.groupsService.unselectAllImages();\n this.scrollService.setScrollRestored(true);\n }\n openAddGroupModal(template: TemplateRef<any>) {\n this.dialog.open(template);\n }\n\n toggleTagger() {\n if (!this.showTagger) {\n this.scrollService.setScrollPosition();\n\n const [initialGroupName] = this.groupsFeatures.keys();\n const activeGroupFeatures = this.groupsFeatures.get(initialGroupName);\n const activeGroup = this.groups.get(initialGroupName);\n this.geoDataService.setActiveGroup(activeGroup);\n\n this.groupsService.setShowTagGenerator(false);\n this.groupsService.unselectAllImages();\n } else {\n this.scrollService.setScrollRestored(true);\n }\n\n this.groupsService.toggleTagger();\n }\n\n getAssetDisplay() {\n return this.activeGroupFeature.featureShortPath();\n }\n\n otherPath(dir: boolean) {\n if (dir) {\n this.activeGroupFeaturesRotate.push(\n this.activeGroupFeaturesRotate.shift()\n );\n } else {\n this.activeGroupFeaturesRotate.unshift(\n this.activeGroupFeaturesRotate.pop()\n );\n }\n this.activeGroupFeature = this.activeGroupFeaturesRotate[0];\n this.geoDataService.setActiveGroupFeature(this.activeGroupFeature);\n }\n\n getCSVHeaders(exportFeatures) {\n let headerArray = [];\n exportFeatures.forEach((ef) => {\n headerArray = [...Object.keys(ef)];\n });\n return headerArray;\n }\n\n exportList() {\n const exportList = [];\n\n this.groups.forEach((e) => {\n const exportGroupObj = {};\n exportGroupObj['groupName'] = e.name;\n const groupFeatures = this.groupsFeatures.get(e.name);\n exportGroupObj['features'] = [];\n\n const forms = e.forms;\n\n groupFeatures.forEach((groupFeature) => {\n let featureSource =\n environment.apiUrl + '/assets/' + groupFeature.assets[0].path;\n featureSource = featureSource.replace(/([^:])(\\/{2,})/g, '$1/');\n const coordinates = groupFeature.geometry.coordinates;\n const tags = groupFeature.properties.taggit.tags;\n const featureObj = {\n src: featureSource,\n id: groupFeature.id,\n longitude: coordinates[0],\n latitude: coordinates[1],\n groupName: e.name,\n icon: e.icon,\n color: e.color,\n };\n\n if (forms && tags) {\n forms.forEach((f) => {\n const tag = tags.find((t) => {\n return f.id === t.id;\n });\n if (tag) {\n const label = f.label.charAt(0).toUpperCase() + f.label.slice(1);\n featureObj['Tag' + label + 'Type'] = f.type;\n featureObj['Tag' + label + 'Value'] =\n f.type === 'checkbox'\n ? tag.value.map((v) => v.label).join('|')\n : tag.value;\n }\n });\n }\n exportGroupObj['features'].push(featureObj);\n });\n exportList.push(exportGroupObj);\n });\n return exportList;\n }\n\n saveFile(\n isJSON: Boolean,\n forExport: Boolean = false,\n systemID = '',\n path = '',\n fileName\n ) {\n const exportList = this.exportList();\n const filename = 'taggit-proj-' + this.selectedProject.name;\n if (isJSON) {\n const content = JSON.stringify(exportList);\n const blob = new Blob(['\\ufeff' + content], {\n type: 'text/json;charset=utf-8;',\n });\n if (forExport) {\n this.filesService.export(systemID, path, fileName, '.json', blob);\n } else {\n this.download(blob, '.json', filename);\n }\n } else {\n const csvFiles = exportList.map((exportItem) => {\n const csvRows = [];\n const headers = this.getCSVHeaders(exportItem.features);\n csvRows.push(headers.join(','));\n\n exportItem.features.forEach((ef) => {\n const values = headers.map((header) =>\n ef[header] ? ef[header] : ''\n );\n csvRows.push(values.join(','));\n });\n\n return csvRows.join('\\n');\n });\n\n const zip = new JSZip();\n csvFiles.forEach((csv, i) => {\n zip.file(`group-${i}.csv`, csv);\n });\n\n zip.generateAsync({ type: 'blob' }).then((content) => {\n if (forExport) {\n this.filesService.export(systemID, path, fileName, '.zip', content);\n } else {\n this.download(content, '.zip', filename);\n }\n });\n }\n }\n\n download(content, extension, filename) {\n // Creates a download link in typescript through a blob\n const download = document.createElement('a');\n const url = window.URL.createObjectURL(content);\n\n // checks if the browser is Safari or otherwise, if so open download in new window\n // Its a quirk of those browsers that they don't allow same-page downloads\n if (\n navigator.userAgent.indexOf('Safari') != -1 &&\n navigator.userAgent.indexOf('Chrome') == -1\n ) {\n download.setAttribute('target', '_blank');\n }\n // Sets up the link, and simulates a click\n download.setAttribute('href', url);\n download.setAttribute('download', filename + extension);\n download.style.visibility = 'hidden';\n document.body.appendChild(download);\n download.click();\n document.body.removeChild(download);\n\n window.URL.revokeObjectURL(url);\n }\n\n saveTags(ev) {\n this.geoDataService.updateTagFeaturesQueue(this.activeProject.id);\n }\n}\n","import { Injectable } from '@angular/core';\nimport {\n HttpRequest,\n HttpHandler,\n HttpEvent,\n HttpInterceptor,\n} from '@angular/common/http';\nimport { Observable, throwError } from 'rxjs';\nimport { AuthService } from './services/authentication.service';\nimport { environment } from '../environments/environment';\nimport { catchError } from 'rxjs/operators';\n\n@Injectable()\nexport class AuthInterceptor implements HttpInterceptor {\n constructor(private authService: AuthService) {}\n\n intercept(\n request: HttpRequest<any>,\n next: HttpHandler\n ): Observable<HttpEvent<any>> {\n return next.handle(request).pipe(\n catchError((err) => {\n if (err.status === 401) {\n // auto logout if 401 response returned from api\n this.authService.logout();\n location.reload();\n }\n\n const error = err.error.message || err.statusText;\n return throwError(error);\n })\n );\n }\n}\n\n@Injectable()\nexport class TokenInterceptor implements HttpInterceptor {\n constructor(private authSvc: AuthService) {}\n\n intercept(\n request: HttpRequest<any>,\n next: HttpHandler\n ): Observable<HttpEvent<any>> {\n if (request.url.indexOf('https://agave.designsafe-ci.org') > -1) {\n if (this.authSvc.isLoggedIn()) {\n request = request.clone({\n setHeaders: {\n Authorization: 'Bearer ' + this.authSvc.userToken.token,\n },\n });\n }\n }\n // we put the JWT on the request to our geoapi API because it is not behind ws02 if in local dev\n // and if user is logged in\n if (\n request.url.indexOf('http://localhost') > -1 &&\n this.authSvc.isLoggedIn()\n ) {\n // add header\n request = request.clone({\n setHeaders: {\n 'X-JWT-Assertion-designsafe': environment.jwt,\n },\n });\n }\n\n return next.handle(request);\n }\n}\n","import {\n AfterViewChecked,\n Component,\n OnInit,\n Renderer2,\n ChangeDetectorRef,\n} from '@angular/core';\nimport { GeoDataService } from '../../services/geo-data.service';\nimport {\n FeatureAsset,\n Feature,\n Project,\n FeatureCollection,\n TagGroup,\n} from '../../models/models';\nimport { AppEnvironment, environment } from '../../../environments/environment';\nimport { ProjectsService } from '../../services/projects.service';\nimport { ScrollService } from 'src/app/services/scroll.service';\nimport { GroupsService } from '../../services/groups.service';\nimport { NgxSpinnerService } from 'ngx-spinner';\nimport { startWith } from 'rxjs/operators';\nimport { MatDialog } from '@angular/material/dialog';\nimport { ModalCreateProjectComponent } from '../modal-create-project/modal-create-project.component';\nimport { FeatureService } from 'src/app/services/feature.service';\n\n@Component({\n selector: 'app-image-gallery',\n templateUrl: './image-gallery.component.html',\n styleUrls: ['./image-gallery.component.scss'],\n})\nexport class ImageGalleryComponent implements OnInit, AfterViewChecked {\n environment: AppEnvironment;\n\n public projects: Project[];\n groupName: string;\n showTagger = false;\n scrolling = false;\n scrollStatus: string;\n imagesExist: boolean = false;\n projectsExist: boolean;\n featureList: Array<any> = [];\n featureListScroll: Array<any>;\n scrollSum = 15;\n activeGroup: TagGroup;\n activeFeature: Feature;\n activeGroupFeature: Feature;\n // activeFeatureNum: number;\n featurePath: string;\n loaded: boolean;\n loadingGallery: boolean = false;\n groupsFeatures: Map<string, any>;\n groups: Map<string, any>;\n\n constructor(\n private geoDataService: GeoDataService,\n private projectsService: ProjectsService,\n private groupsService: GroupsService,\n private readonly cdr: ChangeDetectorRef,\n private renderer: Renderer2,\n private spinner: NgxSpinnerService,\n private dialog: MatDialog,\n private scrollService: ScrollService,\n private featureService: FeatureService\n ) {}\n\n ngAfterViewChecked() {\n if (this.scrollService.scrollRestored) {\n this.scrollService.scroll();\n }\n this.cdr.detectChanges();\n }\n\n ngOnInit() {\n this.environment = environment;\n\n this.geoDataService.loaded.subscribe(\n (e) => {\n this.loaded = e;\n },\n (error) => {\n this.projectsExist = false;\n }\n );\n\n this.geoDataService.loadingGallery.subscribe(e => {\n this.loadingGallery = e;\n });\n\n this.featureService.features$.subscribe((fc: any) => {\n this.imagesExist = false;\n if (fc) {\n if (fc.features.length > 0) {\n this.featureList = fc.features.filter((feature) => {\n try {\n return (\n feature.initialAsset() && feature.featureType() === 'image'\n );\n } catch (error) {\n // If a feature has no asset, it ends up in this catch\n console.error(error);\n // After outputting the error, add an \"image not found\" placeholder,\n // Allowing users to still select their errored import\n // Note that this doesn't really work!\n feature.assets.push({ path: '../../images/Image-not-found.png' });\n return false;\n }\n });\n if (this.featureList.length > 0) {\n this.imagesExist = true;\n }\n this.featureListScroll = this.featureList.slice(0, this.scrollSum);\n } else {\n this.imagesExist = false;\n }\n }\n });\n\n this.projectsService.projects.subscribe((projects) => {\n this.projects = projects;\n if (this.projects.length) {\n this.projectsExist = true;\n } else {\n this.projectsExist = false;\n }\n });\n\n this.geoDataService.groupsFeatures.subscribe((next) => {\n this.groupsFeatures = next;\n });\n\n this.geoDataService.groups.subscribe((next) => {\n this.groups = next;\n });\n\n this.geoDataService.activeFeature.subscribe((next) => {\n if (next) {\n this.activeFeature = next;\n }\n });\n\n this.geoDataService.activeGroup.subscribe((next: TagGroup) => {\n this.activeGroup = next;\n });\n\n this.geoDataService.activeGroupFeature.subscribe((next) => {\n this.activeGroupFeature = next;\n });\n\n this.geoDataService.groups.subscribe((next) => {\n this.groups = next;\n });\n\n this.groupsService.showTagger.subscribe((next) => {\n this.showTagger = next;\n this.scrollStatus = next ? 'success' : 'danger';\n });\n }\n\n getPath() {\n return (\n this.environment.apiUrl +\n '/assets/' +\n this.activeGroupFeature.assets[0].path.replace(/([^:])(\\/{2,})/g, '$1/')\n );\n }\n\n appendSum() {\n if (this.featureList.length != 0) {\n if (this.scrollSum == this.featureList.length) {\n this.spinner.hide();\n this.scrolling = false;\n return;\n }\n // If scrollSum is larger than the length of the feature list, curtail it to just be the length\n if (this.scrollSum > this.featureList.length) {\n this.scrollSum = this.featureList.length;\n }\n }\n this.featureListScroll = this.featureList.slice(0, this.scrollSum);\n setTimeout(() => {\n this.spinner.hide();\n this.scrolling = false;\n }, 1300);\n }\n\n onScroll() {\n if (!this.scrolling) {\n this.spinner.show();\n this.scrollSum += 10;\n this.appendSum();\n this.scrolling = true;\n }\n }\n\n openCreateProjectModal() {\n this.dialog.open(ModalCreateProjectComponent, {\n height: '400px',\n width: '600px',\n });\n }\n}\n","import { Component, Input, OnInit, TemplateRef } from '@angular/core';\nimport { MatDialog } from '@angular/material/dialog';\nimport { BsModalRef } from 'ngx-foundation/modal/bs-modal-ref.service';\nimport { FeatureService } from 'src/app/services/feature.service';\nimport { ScrollService } from 'src/app/services/scroll.service';\nimport { AppEnvironment, environment } from '../../../environments/environment';\nimport { Feature, Project, TagGroup } from '../../models/models';\nimport { GeoDataService } from '../../services/geo-data.service';\nimport { GroupsService } from '../../services/groups.service';\nimport { ProjectsService } from '../../services/projects.service';\n\n@Component({\n selector: 'app-image-box',\n templateUrl: './image-box.component.html',\n styleUrls: ['./image-box.component.scss'],\n})\nexport class ImageBoxComponent implements OnInit {\n @Input() feature: any;\n environment: AppEnvironment;\n featureSource: string;\n featurePath: string;\n status = false; // Controls the whether or not an image box is selected or not\n imageSelected = 'img-unselected'; // Controls the whether or not an image box is selected or not\n hasGroup = false;\n colors: Array<string> = [];\n groups: Map<string, TagGroup>;\n coordinates: Array<any>;\n containingGroupList: Array<any>;\n selectedImages: Array<any>;\n modalRef: BsModalRef;\n groupToAdd: TagGroup;\n\n public activeProject: Project;\n\n constructor(\n private geoDataService: GeoDataService,\n private groupsService: GroupsService,\n private projectsService: ProjectsService,\n private dialog: MatDialog,\n private scrollService: ScrollService,\n private featureService: FeatureService\n ) {}\n\n ngOnInit() {\n // TODO: put this in models\n this.environment = environment;\n let featureSource: string;\n if (this.feature.assets[0].path != '../../images/Image-not-found.png') {\n featureSource =\n this.environment.apiUrl + '/assets/' + this.feature.assets[0].path;\n } else {\n featureSource = this.feature.assets[0].path;\n }\n featureSource = featureSource.replace(/([^:])(\\/{2,})/g, '$1/');\n this.featureSource = featureSource;\n this.coordinates = this.feature.geometry.coordinates;\n\n this.projectsService.activeProject.subscribe((next) => {\n this.activeProject = next;\n });\n\n this.geoDataService.groups.subscribe((next) => {\n this.groups = next;\n });\n\n this.groupsService.selectedImages.subscribe((next) => {\n this.selectedImages = next;\n this.imageSelected = this.groupsService.imageSelected(this.feature)\n ? 'img-selected'\n : 'img-unselected';\n });\n\n this.groupsService.groupToAdd.subscribe((next) => {\n this.groupToAdd = next;\n });\n\n this.featurePath = this.feature.featurePath();\n }\n\n imageSelect() {\n this.groupsService.toggleImageSelect(this.feature);\n }\n\n compareGroup(a, b) {\n return a.name === b.name;\n }\n\n imageZoom(template: TemplateRef<any>) {\n this.dialog.open(template);\n }\n\n imageDelete() {\n const featureService = this.featureService;\n this.selectedImages.forEach(function (value) {\n featureService.deleteFeature(value);\n });\n this.groupsService.unselectAllImages();\n this.scrollService.setScrollRestored(true);\n }\n\n openModal(template: TemplateRef<any>) {\n this.dialog.open(template);\n }\n\n openPreserveScrollModal(template: TemplateRef<any>) {\n this.scrollService.setScrollPosition();\n this.dialog.open(template);\n }\n\n deleteFromGroup(feature: Feature, group: TagGroup) {\n this.geoDataService.deleteGroupFeatures(\n this.activeProject.id,\n [feature],\n group\n );\n }\n\n openImageAddModal(template: TemplateRef<any>) {\n this.scrollService.setScrollPosition();\n this.dialog.open(template);\n }\n\n changeGroupToAdd(ev: any) {\n this.groupsService.setGroupToAdd(ev.value);\n }\n\n addGroup(group: TagGroup) {\n this.geoDataService.createGroupFeatures(\n this.activeProject.id,\n [this.feature],\n this.groups.get(group.name)\n );\n this.groupsService.unselectAllImages();\n this.scrollService.setScrollRestored(true);\n }\n}\n","import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { FormControl } from '@angular/forms';\nimport { GroupForm } from 'src/app/models/models';\n\n@Component({\n selector: 'app-form-generator',\n templateUrl: './form-generator.component.html',\n styleUrls: ['./form-generator.component.scss'],\n})\nexport class FormGeneratorComponent implements OnInit {\n constructor() { }\n @Input() form: GroupForm;\n checked = false;\n colorArray: Array<string> = [];\n values = [];\n\n name = new FormControl('');\n\n ngOnInit() {\n if (this.form.type == 'color' && this.form.options) {\n this.generateColors();\n }\n }\n\n // Generates a key:value list of colors ranging from green (#00FF00) to red (#FF0000) based on passed in info\n generateColors() {\n let itemCount = this.form.options.length;\n let isOdd = false;\n if (itemCount % 2 === 1) {\n // if there are an odd number of items in the collection, mark it and decriment the counter\n isOdd = true;\n itemCount--;\n }\n // Subtract 2 from item count (first entry is always green, #00FF00, last entry is always red, #FF0000\n // Then half the item count, and use it to divide 255, this gives the amount we have to increment the colors\n itemCount = (itemCount - 2) / 2;\n let incrementVal = Math.floor(255 / itemCount);\n if (incrementVal === 255) {\n incrementVal = Math.floor(incrementVal / 2);\n }\n this.colorArray.push('#00FF00');\n let baseNum = 0;\n let temp: string;\n // First loop, counts up from zero towards 255\n for (let index = 0; index < itemCount; index++) {\n baseNum = baseNum + incrementVal;\n temp = baseNum.toString(16);\n this.colorArray.push(`#${temp}FF00`);\n }\n // if there is an odd number of selections, push full yellow as a midpoint in the gradient\n if (isOdd) {\n this.colorArray.push('#FFFF00');\n }\n baseNum = 255; // Resets baseNum to 255 for the count down\n // Second loop, counts down from 255 towards zero\n for (let index = 0; index < itemCount; index++) {\n baseNum = baseNum - incrementVal;\n temp = baseNum.toString(16);\n if (temp.length != 2) {\n temp = '0' + temp;\n }\n this.colorArray.push(`#FF${temp}00`);\n }\n // Finally, pushes the color code for red onto the stack for the last entry\n this.colorArray.push('#FF0000');\n }\n}\n","import { Component, OnInit } from '@angular/core';\nimport { GroupsService } from '../../services/groups.service';\nimport { GeoDataService } from '../../services/geo-data.service';\n\n@Component({\n selector: 'app-side-bar',\n templateUrl: './side-bar.component.html',\n styleUrls: ['./side-bar.component.scss'],\n})\nexport class SideBarComponent implements OnInit {\n showTagGenerator = false;\n loadingFeatureProperties;\n\n constructor(\n private groupsService: GroupsService,\n private geoDataService: GeoDataService\n ) { }\n\n ngOnInit() {\n this.groupsService.showTagGenerator.subscribe((next) => {\n this.showTagGenerator = next;\n });\n\n this.geoDataService.loadingFeatureProperties.subscribe((next) => {\n this.loadingFeatureProperties = next;\n });\n }\n}\n","export const groupIcons: Array<any> = [\n { id: 'fa-house-damage', unicode: ' house-damage' },\n { id: 'fa-car', unicode: ' car' },\n { id: 'fa-tree', unicode: ' tree' },\n\n { id: 'fa-school', unicode: ' school' },\n { id: 'fa-archway', unicode: ' archway' },\n { id: 'fa-building', unicode: ' building' },\n { id: 'fa-bus', unicode: ' bus' },\n { id: 'fa-church', unicode: ' church' },\n\n { id: 'fa-helicopter', unicode: ' helicopter' },\n { id: 'fa-hospital-alt', unicode: ' hospital' },\n { id: 'fa-hotel', unicode: ' hotel' },\n { id: 'fa-igloo', unicode: ' igloo' },\n { id: 'fa-motorcycle', unicode: ' motorcycle' },\n { id: 'fa-place-of-worship', unicode: ' place-of-worship' },\n { id: 'fa-plane', unicode: ' plane' },\n { id: 'fa-school', unicode: ' school' },\n\n { id: 'fa-rocket', unicode: ' rocket' },\n { id: 'fa-ship', unicode: ' ship' },\n { id: 'fa-shopping-cart', unicode: ' shopping-cart' },\n { id: 'fa-shuttle-van', unicode: ' shuttle-van' },\n { id: 'fa-monument', unicode: ' monument' },\n { id: 'fa-store', unicode: ' store' },\n\n { id: 'fa-subway', unicode: ' subway' },\n { id: 'fa-taxi', unicode: ' taxi' },\n { id: 'fa-train', unicode: ' train' },\n { id: 'fa-truck', unicode: ' truck' },\n { id: 'fa-truck-pickup', unicode: ' truck-pickup' },\n { id: 'fa-university', unicode: ' university' },\n { id: 'fa-warehouse', unicode: ' warehouse' },\n { id: 'fa-bolt', unicode: ' bolt' },\n];\n","import { Component, OnInit, OnDestroy, TemplateRef } from '@angular/core';\nimport { Project, TagGroup } from '../../../models/models';\nimport { ProjectsService } from '../../../services/projects.service';\nimport { FormsService } from '../../../services/forms.service';\nimport { GroupsService } from '../../../services/groups.service';\nimport { GeoDataService } from '../../../services/geo-data.service';\nimport { MatDialog } from '@angular/material/dialog';\nimport { Subscription } from 'rxjs';\nimport { FeatureService } from 'src/app/services/feature.service';\n\nimport { groupIcons } from 'src/app/utils/groups';\n\n@Component({\n selector: 'app-select-group',\n templateUrl: './select-group.component.html',\n styleUrls: ['./select-group.component.scss'],\n})\nexport class SelectGroupComponent implements OnInit, OnDestroy {\n groups$: Subscription;\n activeGroup$: Subscription;\n\n public selectedProject: Project;\n\n iconList = groupIcons;\n selectedIcon = 'fa-house-damage';\n\n selectedGroup: TagGroup;\n\n activeGroup: TagGroup;\n groups: Map<string, TagGroup>;\n groupsFeatures: Map<string, any>;\n\n showTagger: boolean;\n showSubitem = true;\n\n constructor(\n private groupsService: GroupsService,\n private geoDataService: GeoDataService,\n private projectsService: ProjectsService,\n private dialog: MatDialog\n ) {}\n\n ngOnInit() {\n this.projectsService.activeProject.subscribe((next) => {\n this.selectedProject = next;\n });\n\n this.groups$ = this.geoDataService.groups.subscribe((next) => {\n this.groups = next;\n });\n\n this.geoDataService.groupsFeatures.subscribe((next) => {\n this.groupsFeatures = next;\n });\n\n this.activeGroup$ = this.geoDataService.activeGroup.subscribe((next) => {\n this.activeGroup = next;\n if (!next) {\n this.groupsService.toggleTagger();\n }\n });\n }\n\n selectGroupForm(group: TagGroup) {\n this.geoDataService.setActiveGroup(group);\n }\n\n openRenameOptionModal(template: TemplateRef<any>) {\n this.dialog.open(template);\n }\n\n // TODO: ensure ui is updated from getFeatures()\n deleteGroup(group: TagGroup) {\n const features = this.groupsFeatures.get(group.name);\n this.geoDataService.deleteGroupFeatures(\n this.selectedProject.id,\n features,\n group\n );\n }\n\n openRenameModal(template: TemplateRef<any>, group: TagGroup) {\n this.selectedGroup = group;\n this.dialog.open(template);\n }\n\n openIconSelection(template: TemplateRef<any>, group: TagGroup) {\n this.selectedGroup = group;\n this.selectedIcon = group.icon;\n this.dialog.open(template);\n }\n\n saveIcon(icon: string) {\n this.geoDataService.reiconGroup(\n this.selectedProject.id,\n this.groupsFeatures.get(this.selectedGroup.name),\n this.groups.get(this.selectedGroup.name),\n icon\n );\n\n this.dialog.closeAll();\n }\n\n isChecked(name: string) {\n if (this.activeGroup && this.activeGroup.name === name) {\n return 'checked';\n } else {\n return '';\n }\n }\n\n renameGroup(name: string) {\n this.geoDataService.renameGroup(\n this.selectedProject.id,\n this.groupsFeatures.get(this.selectedGroup.name),\n this.groups.get(this.selectedGroup.name),\n name\n );\n\n this.dialog.closeAll();\n }\n\n expandPanel() {\n this.showSubitem = !this.showSubitem;\n }\n\n ngOnDestroy() {\n this.groups$.unsubscribe();\n this.activeGroup$.unsubscribe();\n }\n}\n","import { Component, OnInit } from '@angular/core';\nimport { Project, TagGroup } from '../../../models/models';\nimport { ProjectsService } from '../../../services/projects.service';\nimport { GeoDataService } from '../../../services/geo-data.service';\nimport { FormsService } from '../../../services/forms.service';\nimport { Feature } from '@turf/turf';\n\n@Component({\n selector: 'app-select-image',\n templateUrl: './select-image.component.html',\n styleUrls: ['./select-image.component.scss'],\n})\nexport class SelectImageComponent implements OnInit {\n public activeProject: Project;\n private groups: Map<string, TagGroup>;\n activeGroup: TagGroup;\n activeGroupFeature: Feature;\n showSubitem = true;\n groupsFeatures: Map<string, any>;\n\n constructor(\n private geoDataService: GeoDataService,\n private projectsService: ProjectsService\n ) {}\n\n ngOnInit() {\n this.projectsService.activeProject.subscribe((next) => {\n this.activeProject = next;\n });\n\n this.geoDataService.groups.subscribe((next) => {\n this.groups = next;\n });\n\n this.geoDataService.activeGroup.subscribe((next) => {\n this.activeGroup = next;\n });\n\n this.geoDataService.activeGroupFeature.subscribe((next) => {\n this.activeGroupFeature = next;\n });\n\n this.geoDataService.groupsFeatures.subscribe((next) => {\n this.groupsFeatures = next;\n if (next && this.activeGroup) {\n const groupFeatures = this.groupsFeatures.get(this.activeGroup.name);\n if (groupFeatures) {\n if (!groupFeatures.some((f) => f.id === this.activeGroupFeature.id)) {\n this.geoDataService.setActiveGroupFeature(groupFeatures[0]);\n }\n } else {\n const [nextGroup] = this.groups.values();\n if (nextGroup) {\n this.geoDataService.setActiveGroup(nextGroup);\n } else {\n this.geoDataService.setActiveGroup(null);\n }\n }\n }\n });\n }\n\n getActiveFeatures() {\n if (this.activeGroup) {\n const groupFeatures = this.groupsFeatures.get(this.activeGroup.name);\n const group = this.groups.get(this.activeGroup.name);\n if (group) {\n return groupFeatures;\n } else {\n const [nextGroup] = this.groups.values();\n if (nextGroup) {\n this.geoDataService.setActiveGroup(nextGroup);\n return this.groupsFeatures.get(nextGroup.name);\n } else {\n return [];\n }\n }\n } else {\n return [];\n }\n }\n\n jumpToImage(feat: Feature) {\n this.geoDataService.setActiveGroupFeature(feat);\n }\n\n isActiveFeature(feature: Feature) {\n return this.activeGroupFeature.id === feature.id;\n }\n\n deleteFeature(feat: any) {\n this.geoDataService.deleteGroupFeatures(\n this.activeProject.id,\n [feat],\n this.groups.get(this.activeGroup.name)\n );\n }\n\n getFeaturePath(feat: any) {\n return feat.featureShortPath();\n }\n\n expandPanel() {\n this.showSubitem = !this.showSubitem;\n }\n}\n","import { Component, OnInit } from '@angular/core';\nimport { GroupForm } from 'src/app/models/models';\n\n@Component({\n selector: 'app-form-fields',\n templateUrl: './form-fields.component.html',\n})\nexport class FormFieldsComponent implements OnInit {\n field: any;\n form: GroupForm;\n\n constructor() {}\n\n // This file and the HTML connected to this is useless so don't worry about it\n ngOnInit() {}\n}\n","import { Component, Input, Output, EventEmitter } from '@angular/core';\nimport { FormGroup } from '@angular/forms';\nimport { Subscription } from 'rxjs';\nimport { take } from 'rxjs/operators';\nimport { FeatureService } from 'src/app/services/feature.service';\nimport { FormsService } from 'src/app/services/forms.service';\nimport { GroupsService } from 'src/app/services/groups.service';\nimport { Feature, GroupForm, Project, TagGroup } from 'src/app/models/models';\nimport { ProjectsService } from 'src/app/services/projects.service';\nimport { GeoDataService } from 'src/app/services/geo-data.service';\n\n@Component({\n selector: 'app-form-checkbox',\n templateUrl: 'form-checkbox.component.html',\n})\nexport class FormCheckBoxComponent {\n @Input() field: any;\n @Input() form: GroupForm;\n value: any[] = [];\n activeGroupFeature: Feature;\n activeGroup: TagGroup;\n private activeProject: Project;\n\n constructor(\n private formsService: FormsService,\n private groupsService: GroupsService,\n private geoDataService: GeoDataService,\n private projectsService: ProjectsService,\n private featureService: FeatureService\n ) {}\n\n ngOnInit() {\n this.geoDataService.activeGroupFeature.subscribe((next) => {\n this.activeGroupFeature = next;\n this.value = this.formsService.getTagValue(next, this.form);\n });\n\n this.geoDataService.activeGroup.subscribe((next) => {\n this.activeGroup = next;\n });\n\n this.projectsService.activeProject.subscribe((next) => {\n this.activeProject = next;\n });\n }\n\n isChecked(opt) {\n return this.value.some((val) => val.label === opt.label);\n }\n\n selected(e: any, option: any) {\n this.value = this.value.filter((opt) => opt.label !== option.label);\n if (e.target.checked) {\n this.value.push(option);\n }\n this.geoDataService.setTagFeaturesQueue(this.activeGroupFeature.id, {\n id: this.form.id,\n value: this.value,\n });\n }\n}\n","import { Component, Input, Output, EventEmitter } from '@angular/core';\nimport { FormGroup } from '@angular/forms';\nimport { Subscription } from 'rxjs';\nimport { FormsService } from 'src/app/services/forms.service';\nimport { GroupsService } from 'src/app/services/groups.service';\nimport { Feature, GroupForm } from 'src/app/models/models';\nimport { GeoDataService } from 'src/app/services/geo-data.service';\n\n@Component({\n selector: 'app-form-dropdown',\n templateUrl: './form-dropdown.component.html',\n})\nexport class FormDropDownComponent {\n @Input() field: any = {};\n @Input() form: GroupForm;\n value: string;\n activeGroupFeature: any;\n\n constructor(\n private formsService: FormsService,\n private geoDataService: GeoDataService\n ) {}\n\n ngOnInit() {\n this.geoDataService.activeGroupFeature.subscribe((next) => {\n this.activeGroupFeature = next;\n this.value = this.formsService.getTagValue(next, this.form);\n });\n }\n\n updateCheckedTag() {\n this.geoDataService.setTagFeaturesQueue(this.activeGroupFeature.id, {\n id: this.form.id,\n value: this.value,\n });\n }\n}\n","import { Component, Input } from '@angular/core';\nimport { FormGroup } from '@angular/forms';\nimport { GroupForm } from 'src/app/models/models';\n\n@Component({\n selector: 'app-form-file',\n templateUrl: './form-file.component.html',\n styleUrls: ['./form-file.component.scss'],\n})\nexport class FormFileComponent {\n field: any = {};\n form: GroupForm;\n\n constructor() {}\n\n ngOnChange() {\n console.log(this.field.value);\n }\n}\n","import { Component, Input, Output, EventEmitter } from '@angular/core';\nimport { FormsService } from 'src/app/services/forms.service';\nimport { GroupForm } from 'src/app/models/models';\nimport { GeoDataService } from 'src/app/services/geo-data.service';\n\n@Component({\n selector: 'app-form-radio',\n templateUrl: './form-radio.component.html',\n})\nexport class FormRadioComponent {\n @Input() field: any = {};\n @Input() form: GroupForm;\n @Input() label: String;\n public value: string;\n activeGroupFeature: any;\n\n constructor(\n private formsService: FormsService,\n private geoDataService: GeoDataService\n ) {}\n\n ngOnInit() {\n this.geoDataService.activeGroupFeature.subscribe((next) => {\n this.activeGroupFeature = next;\n this.value = this.formsService.getTagValue(next, this.form);\n });\n }\n\n updateCheckedTag() {\n this.geoDataService.setTagFeaturesQueue(this.activeGroupFeature.id, {\n id: this.form.id,\n value: this.value,\n });\n }\n}\n","import { Component, Input, Output, EventEmitter } from '@angular/core';\nimport { FormGroup } from '@angular/forms';\nimport { Subscription } from 'rxjs';\nimport { FormsService } from 'src/app/services/forms.service';\nimport { Feature, GroupForm, Project, TagGroup } from 'src/app/models/models';\nimport { GeoDataService } from 'src/app/services/geo-data.service';\n\n@Component({\n selector: 'app-form-textbox',\n templateUrl: './form-textbox.component.html',\n})\nexport class FormTextBoxComponent {\n @Input() field: any = {};\n @Input() form: GroupForm;\n value = '';\n activeGroupFeature: any;\n\n constructor(\n private formsService: FormsService,\n private geoDataService: GeoDataService\n ) {}\n\n ngOnInit() {\n this.geoDataService.activeGroupFeature.subscribe((next) => {\n this.activeGroupFeature = next;\n this.value = this.formsService.getTagValue(next, this.form);\n });\n }\n\n updateValue() {\n this.geoDataService.setTagFeaturesQueue(this.activeGroupFeature.id, {\n id: this.form.id,\n value: this.value,\n });\n }\n}\n","import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';\nimport { FormGroup } from '@angular/forms';\nimport { Subscription } from 'rxjs';\nimport { FormsService } from 'src/app/services/forms.service';\nimport { Feature, Project, GroupForm, TagGroup } from 'src/app/models/models';\nimport { GeoDataService } from 'src/app/services/geo-data.service';\nimport { ProjectsService } from 'src/app/services/projects.service';\n\n@Component({\n selector: 'app-form-color',\n templateUrl: './form-color.component.html',\n styleUrls: ['./form-color.component.scss'],\n})\nexport class FormColorComponent implements OnInit {\n @Input() field: any = {};\n @Input() form: GroupForm;\n @Input() color: string;\n @Input() label: String;\n\n public chosenTag: string;\n public activeProject: Project;\n public activeGroup: TagGroup;\n public activeGroupFeature: Feature;\n public chosenColor = '#ffffff';\n value: any = {};\n\n constructor(\n private formsService: FormsService,\n private projectsService: ProjectsService,\n private geoDataService: GeoDataService\n ) {}\n\n ngOnInit() {\n this.geoDataService.activeGroupFeature.subscribe((next) => {\n this.value = this.formsService.getTagValue(next, this.form);\n this.chosenTag = this.value.label;\n });\n\n this.projectsService.activeProject.subscribe((next) => {\n this.activeProject = next;\n });\n\n this.geoDataService.activeGroup.subscribe((next: TagGroup) => {\n this.activeGroup = next;\n });\n\n this.geoDataService.activeGroupFeature.subscribe((next) => {\n this.activeGroupFeature = next;\n });\n }\n\n updateCheckedTag() {\n this.value = this.form.options.find((opt) => opt.label === this.chosenTag);\n this.formsService.saveStyles(\n this.activeProject.id,\n [this.activeGroupFeature],\n this.activeGroup,\n this.value.color\n );\n\n this.geoDataService.setTagFeaturesQueue(this.activeGroupFeature.id, {\n id: this.form.id,\n value: this.value,\n });\n }\n}\n","import { BrowserModule } from '@angular/platform-browser';\nimport { NgModule } from '@angular/core';\nimport { BrowserAnimationsModule } from '@angular/platform-browser/animations';\nimport { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';\n// CommonModule for dynamic field\nimport { APP_BASE_HREF, CommonModule } from '@angular/common';\n\nimport { InfiniteScrollModule } from 'ngx-infinite-scroll';\nimport { NgxSpinnerModule } from 'ngx-spinner';\nimport { ModalModule, BsDropdownModule, AccordionModule } from 'ngx-foundation';\nimport { MatSliderModule } from '@angular/material/slider';\nimport { MatMenuModule } from '@angular/material/menu';\nimport { MatToolbarModule } from '@angular/material/toolbar';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatDialogModule } from '@angular/material/dialog';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatRadioModule } from '@angular/material/radio';\nimport { MatSelectModule } from '@angular/material/select';\nimport { NgxMasonryModule } from 'ngx-masonry';\nimport { ToastrModule } from 'ngx-toastr';\n\nimport { FileSizeModule } from 'ngx-filesize';\nimport { ApiModule } from 'ng-tapis';\n\nimport { AppRoutingModule } from './app-routing.module';\nimport { AppComponent } from './app.component';\nimport { MapComponent } from './components/map/map.component';\nimport { MainComponent } from './components/main/main.component';\nimport { NotFoundComponent } from './components/notfound/notfound.component';\nimport { ControlBarComponent } from './components/control-bar/control-bar.component';\nimport { AuthService } from './services/authentication.service';\nimport { CallbackComponent } from './components/callback/callback.component';\nimport { AuthInterceptor, TokenInterceptor } from './app.interceptors';\nimport { ReactiveFormsModule, FormsModule } from '@angular/forms';\nimport { ModalFileBrowserComponent } from './components/modal-file-browser/modal-file-browser.component';\nimport { environment } from '../environments/environment';\nimport { ImageGalleryComponent } from './components/image-gallery/image-gallery.component';\n// import { TaggerComponent } from './components/tagger/tagger.component';\n// import { PresetGeneratorComponent } from './components/preset-generator/preset-generator.component';\nimport { ImageBoxComponent } from './components/image-box/image-box.component';\nimport { FormGeneratorComponent } from './components/side-bar/tag-images/form-generator/form-generator.component';\nimport { SideBarComponent } from './components/side-bar/side-bar.component';\n// import { ImageListComponent } from './components/image-list/image-list.component';\nimport { SelectGroupComponent } from './components/side-bar/select-group/select-group.component';\nimport { SelectImageComponent } from './components/side-bar/select-image/select-image.component';\nimport { TagGeneratorComponent } from './components/side-bar/tag-generator/tag-generator.component';\nimport { TagImagesComponent } from './components/side-bar/tag-images/tag-images.component';\nimport { ModalCreateProjectComponent } from './components/modal-create-project/modal-create-project.component';\nimport { ModalCurrentProjectComponent } from './components/modal-current-project/modal-current-project.component';\nimport { ScrollingModule } from '@angular/cdk/scrolling';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport { MatTreeModule } from '@angular/material/tree';\nimport { MatProgressBar } from '@angular/material';\nimport { MatSnackBarModule } from '@angular/material/snack-bar';\nimport { ModalDownloadSelectorComponent } from './components/modal-download-selector/modal-download-selector.component';\nimport { FormFieldsComponent } from './components/side-bar/tag-images/form-generator/form-fields/form-fields.component';\nimport { FormCheckBoxComponent } from './components/side-bar/tag-images/form-generator/form-fields/form-checkbox/form-checkbox.component';\nimport { FormDropDownComponent } from './components/side-bar/tag-images/form-generator/form-fields/form-dropdown/form-dropdown.component';\nimport { FormFileComponent } from './components/side-bar/tag-images/form-generator/form-fields/form-file/form-file.component';\nimport { FormRadioComponent } from './components/side-bar/tag-images/form-generator/form-fields/form-radio/form-radio.component';\nimport { FormTextBoxComponent } from './components/side-bar/tag-images/form-generator/form-fields/form-textbox/form-textbox.component';\nimport { FormColorComponent } from './components/side-bar/tag-images/form-generator/form-fields/form-color/form-color.component';\nimport { ModalShareProjectComponent } from './components/modal-share-project/modal-share-project.component';\nimport { MatCardModule } from '@angular/material/card';\n\n@NgModule({\n declarations: [\n AppComponent,\n MapComponent,\n NotFoundComponent,\n MainComponent,\n ControlBarComponent,\n CallbackComponent,\n ModalFileBrowserComponent,\n ImageGalleryComponent,\n // TaggerComponent,\n // PresetGeneratorComponent,\n ImageBoxComponent,\n FormGeneratorComponent,\n SideBarComponent,\n // ImageListComponent,\n SelectGroupComponent,\n SelectImageComponent,\n TagGeneratorComponent,\n TagImagesComponent,\n ModalCreateProjectComponent,\n ModalCurrentProjectComponent,\n MatProgressBar,\n ModalDownloadSelectorComponent,\n FormFieldsComponent,\n FormCheckBoxComponent,\n FormDropDownComponent,\n FormFileComponent,\n FormRadioComponent,\n FormTextBoxComponent,\n ModalShareProjectComponent,\n FormColorComponent,\n ],\n imports: [\n // this is for the ng-tapis library\n ApiModule.forRoot({ rootUrl: 'https://agave.designsafe-ci.org/' }),\n BrowserModule,\n AppRoutingModule,\n HttpClientModule,\n BrowserAnimationsModule,\n InfiniteScrollModule,\n NgxSpinnerModule,\n NgxMasonryModule,\n ToastrModule.forRoot(),\n ModalModule.forRoot(),\n MatMenuModule,\n MatToolbarModule,\n MatButtonModule,\n MatDialogModule,\n MatTooltipModule,\n MatInputModule,\n MatCheckboxModule,\n MatSelectModule,\n MatRadioModule,\n MatIconModule,\n AccordionModule.forRoot(),\n ReactiveFormsModule,\n FormsModule,\n FileSizeModule,\n BsDropdownModule.forRoot(),\n CommonModule,\n MatProgressSpinnerModule,\n ScrollingModule,\n MatTreeModule,\n MatSnackBarModule,\n MatCardModule,\n ],\n providers: [\n AuthService,\n {\n provide: HTTP_INTERCEPTORS,\n multi: true,\n useClass: AuthInterceptor,\n },\n {\n provide: HTTP_INTERCEPTORS,\n multi: true,\n useClass: TokenInterceptor,\n },\n {\n provide: APP_BASE_HREF,\n useValue: environment.baseHref,\n },\n ],\n bootstrap: [AppComponent],\n entryComponents: [\n ModalFileBrowserComponent,\n ModalDownloadSelectorComponent,\n ModalCreateProjectComponent,\n ModalCurrentProjectComponent,\n ModalShareProjectComponent,\n ],\n})\nexport class AppModule {}\n","import 'hammerjs';\nimport { enableProdMode } from '@angular/core';\nimport { platformBrowserDynamic } from '@angular/platform-browser-dynamic';\n\nimport { AppModule } from './app/app.module';\nimport { environment } from './environments/environment';\n\nif (environment.production) {\n enableProdMode();\n}\n\nplatformBrowserDynamic()\n .bootstrapModule(AppModule)\n .catch((err) => console.error(err));\n","export default \"<div class=\\\"tag-forms\\\">\\n <div class=\\\"subitem-title\\\" (click)=\\\"expandPanel()\\\">\\n <span> Tag Images </span>\\n <span>\\n <span\\n style=\\\"cursor: pointer\\\"\\n (click)=\\\"showTagGenerator()\\\"\\n matTooltip=\\\"Add New Tag Form\\\"\\n style=\\\"cursor: pointer; margin-right: 10px\\\"\\n matTooltipPosition=\\\"above\\\"\\n >\\n <i class=\\\"fas fa-plus\\\"></i>\\n </span>\\n </span>\\n </div>\\n <!-- subitem-title -->\\n\\n <div *ngIf=\\\"showSubitem\\\" class=\\\"subitem\\\">\\n <div class=\\\"subitem-scroll\\\">\\n <div *ngFor=\\\"let form of formList\\\">\\n <div class=\\\"form-item-container\\\">\\n <div class=\\\"name-group\\\">{{ form.label }} ({{ form.type }})</div>\\n <div class=\\\"button-group\\\">\\n <div (click)=\\\"deleteForm(form)\\\">\\n <i\\n class=\\\"fas fa-minus\\\"\\n matTooltip=\\\"Delete\\\"\\n matTooltipPosition=\\\"above\\\"\\n style=\\\"cursor: pointer\\\"\\n >\\n </i>\\n </div>\\n <!-- delete button -->\\n\\n <div (click)=\\\"openRenameModal(renameFormItemModal)\\\">\\n <i\\n class=\\\"fas fa-edit\\\"\\n matTooltip=\\\"Rename\\\"\\n matTooltipPosition=\\\"above\\\"\\n style=\\\"cursor: pointer\\\"\\n >\\n </i>\\n </div>\\n\\n <ng-template #renameFormItemModal>\\n <input\\n matInput\\n #formItemRename\\n [(ngModel)]=\\\"tagName\\\"\\n value=\\\"{{ form.label }}\\\"\\n placeholder=\\\"Rename Form Item\\\"\\n (keyup.enter)=\\\"renameForm(form)\\\"\\n />\\n <br />\\n <br />\\n <div class=\\\"button-group\\\">\\n <button\\n matDialogClose\\n mat-raised-button\\n color=\\\"primary\\\"\\n (click)=\\\"renameForm(form.label)\\\"\\n >\\n Rename\\n </button>\\n <button matDialogClose mat-button>Cancel</button>\\n </div>\\n </ng-template>\\n <!-- rename modal -->\\n </div>\\n <!-- button group -->\\n </div>\\n <!-- form-item-container -->\\n <app-form-generator [form]=\\\"form\\\"></app-form-generator>\\n </div>\\n </div>\\n <!-- subitem scroll -->\\n </div>\\n <!--subitem -->\\n</div>\\n<!-- tag-forms -->\\n\"","export default \"<div>\\n <div [ngSwitch]=\\\"form.type\\\" class=\\\"form-controls\\\">\\n <ng-container *ngSwitchCase=\\\"'text'\\\">\\n <app-form-textbox [field]=\\\"form.options\\\" [form]=\\\"form\\\"></app-form-textbox>\\n </ng-container>\\n\\n <ng-container *ngSwitchCase=\\\"'dropdown'\\\">\\n <app-form-dropdown\\n [field]=\\\"form.options\\\"\\n [form]=\\\"form\\\"\\n ></app-form-dropdown>\\n </ng-container>\\n\\n <ng-container *ngSwitchCase=\\\"'radio'\\\">\\n <app-form-radio\\n [field]=\\\"opt\\\"\\n [form]=\\\"form\\\"\\n label=\\\"{{ form.label }}\\\"\\n ></app-form-radio>\\n </ng-container>\\n\\n <ng-container *ngSwitchCase=\\\"'checkbox'\\\">\\n <app-form-checkbox [form]=\\\"form\\\"></app-form-checkbox>\\n </ng-container>\\n\\n <ng-container *ngSwitchCase=\\\"'color'\\\">\\n <app-form-color\\n [field]=\\\"opt\\\"\\n [form]=\\\"form\\\"\\n label=\\\"{{ form.label }}\\\"\\n [color]=\\\"colorArray[form.options.indexOf(opt)]\\\"\\n ></app-form-color>\\n </ng-container>\\n </div>\\n</div>\\n\""]}