<commit_before>import {BehaviorSubject, Subject, combineLatest, concat, of, pipe} from 'rxjs'
import {Content, SectionLayout} from 'widget/sectionLayout'
import {ElementResizeDetector} from 'widget/elementResizeDetector'
import {LegendImport} from './legendImport'
import {MapAreaContext} from './mapAreaContext'
import {MapContext} from './mapContext'
import {MapInfo} from './mapInfo'
import {SplitView} from 'widget/split/splitView'
import {VisParamsPanel} from './visParams/visParamsPanel'
import {compose} from 'compose'
import {connect} from 'store'
import {filter, finalize, first, last, map as rxMap, share, switchMap, takeUntil, windowTime} from 'rxjs/operators'
import {getImageLayerSource} from './imageLayerSource/imageLayerSource'
import {getLogger} from 'log'
import {getProcessTabsInfo} from '../body/process/process'
import {mapTag} from 'tag'
import {recipePath} from '../body/process/recipe'
import {selectFrom} from 'stateUtils'
import {v4 as uuid} from 'uuid'
import {withLayers} from '../body/process/withLayers'
import {withMapsContext} from './maps'
import {withRecipe} from '../body/process/recipeContext'
import MapToolbar from './mapToolbar'
import PropTypes from 'prop-types'
import React from 'react'
import _ from 'lodash'
import actionBuilder from 'action-builder'
import styles from './map.module.css'
import withSubscriptions from 'subscription'

const log = getLogger('map')

const mapRecipeToProps = recipe => ({
    bounds: selectFrom(recipe, 'ui.bounds'),
    recipe
})

class _Map extends React.Component {
    updateView$ = new BehaviorSubject({})
    linked$ = new BehaviorSubject(false)
    mouseDown$ = new Subject()
    draggingMap$ = new BehaviorSubject(false)
    viewChanged$ = new Subject()
    splitPosition$ = new BehaviorSubject()
    draggingSplit$ = new BehaviorSubject(false)
    cursor$ = new Subject()

    state = {
        maps: {}, // [id]: {id, map, listeners, subscriptions}
        mapId: null,
        googleMapsApiKey: null,
        norwayPlanetApiKey: null,
        zoomArea: null,
        selectedZoomArea: null,
        overlay: null,
        overlayActive: false,
        drawPolygon: false
    }

    markers = {}

    constructor() {
        super()
        this.mapDelegate = this.mapDelegate.bind(this)
        this.toggleLinked = this.toggleLinked.bind(this)
        this.toggleZoomArea = this.toggleZoomArea.bind(this)
        this.cancelZoomArea = this.cancelZoomArea.bind(this)
        this.isZoomArea = this.isZoomArea.bind(this)
        this.drawPolygon = this.drawPolygon.bind(this)
        this.disableDrawingMode = this.disableDrawingMode.bind(this)
        this.setLocationMarker = this.setLocationMarker.bind(this)
        this.setAreaMarker = this.setAreaMarker.bind(this)
        this.addClickListenerOnce = this.addClickListenerOnce.bind(this)
        this.removeListener = this.removeListener.bind(this)
    }

    withAllMaps(func) {
        const {maps} = this.state
        return _.map(maps, ({map, area, listeners, subscriptions}, id) =>
            func({id, map, area, listeners, subscriptions})
        )
    }

    withFirstMap(func) {
        const {maps} = this.state
        const id = _.head(_.keys(maps))
        const {map = null} = maps[id] || {}
        return map
            ? func(map)
            : null
    }

    removeMap(id) {
        const {maps} = this.state
        const {map, area, listeners, subscriptions} = maps[id]
        const {google} = map.getGoogle()
        log.debug(() => `Removing ${mapTag(this.state.mapId, id)} (${area})`)
        listeners.forEach(listener =>
            google.maps.event.removeListener(listener)
        )
        subscriptions.forEach(subscription =>
            subscription.unsubscribe()
        )
        this.setState(
            ({maps}) => ({maps: _.omit(maps, id)})
        )
    }

    synchronizeOut(map, area) {
        const {overlay} = this.state
        const view = map.getView()
        this.withAllMaps(({map, area: currentArea}) => {
            if (currentArea !== area) {
                map.setView(view)
            }
        })
        if (area === 'overlay') {
            this.updateView$.next(view)
        } else {
            overlay && overlay.map.setView(view)
        }
    }

    synchronizeIn(view) {
        const {overlay} = this.state
        this.withAllMaps(({map}) => map.setView(view))
        overlay && overlay.map.setView(view)
    }

    synchronizeCursor(cursorId, latLng, event) {
        const {layers: {mode}} = this.props
        const cursorArea = this.getArea(cursorId)
        if (event) {
            this.cursor$.next({
                screenPixel: {x: event.clientX, y: event.clientY},
                mapPixel: {x: event.layerX, y: event.layerY},
                cursorArea,
                latLng,
                mode
            })
        }
        this.withAllMaps(({id, map}) => {<commit_msg>Fixed map bounds in view$.<commit_after>import {BehaviorSubject, Subject, combineLatest, concat, of, pipe} from 'rxjs'
import {Content, SectionLayout} from 'widget/sectionLayout'
import {ElementResizeDetector} from 'widget/elementResizeDetector'
import {LegendImport} from './legendImport'
import {MapAreaContext} from './mapAreaContext'
import {MapContext} from './mapContext'
import {MapInfo} from './mapInfo'
import {SplitView} from 'widget/split/splitView'
import {VisParamsPanel} from './visParams/visParamsPanel'
import {compose} from 'compose'
import {connect} from 'store'
import {filter, finalize, first, last, map as rxMap, share, switchMap, takeUntil, windowTime} from 'rxjs/operators'
import {getImageLayerSource} from './imageLayerSource/imageLayerSource'
import {getLogger} from 'log'
import {getProcessTabsInfo} from '../body/process/process'
import {mapTag} from 'tag'
import {recipePath} from '../body/process/recipe'
import {selectFrom} from 'stateUtils'
import {v4 as uuid} from 'uuid'
import {withLayers} from '../body/process/withLayers'
import {withMapsContext} from './maps'
import {withRecipe} from '../body/process/recipeContext'
import MapToolbar from './mapToolbar'
import PropTypes from 'prop-types'
import React from 'react'
import _ from 'lodash'
import actionBuilder from 'action-builder'
import styles from './map.module.css'
import withSubscriptions from 'subscription'

const log = getLogger('map')

const mapRecipeToProps = recipe => ({
    bounds: selectFrom(recipe, 'ui.bounds'),
    recipe
})

class _Map extends React.Component {
    updateView$ = new BehaviorSubject({})
    linked$ = new BehaviorSubject(false)
    mouseDown$ = new Subject()
    draggingMap$ = new BehaviorSubject(false)
    viewChanged$ = new Subject()
    splitPosition$ = new BehaviorSubject()
    draggingSplit$ = new BehaviorSubject(false)
    cursor$ = new Subject()

    state = {
        maps: {}, // [id]: {id, map, listeners, subscriptions}
        mapId: null,
        googleMapsApiKey: null,
        norwayPlanetApiKey: null,
        zoomArea: null,
        selectedZoomArea: null,
        overlay: null,
        overlayActive: false,
        drawPolygon: false
    }

    markers = {}

    constructor() {
        super()
        this.mapDelegate = this.mapDelegate.bind(this)
        this.toggleLinked = this.toggleLinked.bind(this)
        this.toggleZoomArea = this.toggleZoomArea.bind(this)
        this.cancelZoomArea = this.cancelZoomArea.bind(this)
        this.isZoomArea = this.isZoomArea.bind(this)
        this.drawPolygon = this.drawPolygon.bind(this)
        this.disableDrawingMode = this.disableDrawingMode.bind(this)
        this.setLocationMarker = this.setLocationMarker.bind(this)
        this.setAreaMarker = this.setAreaMarker.bind(this)
        this.addClickListenerOnce = this.addClickListenerOnce.bind(this)
        this.removeListener = this.removeListener.bind(this)
    }

    withAllMaps(func) {
        const {maps} = this.state
        return _.map(maps, ({map, area, listeners, subscriptions}, id) =>
            func({id, map, area, listeners, subscriptions})
        )
    }

    withFirstMap(func) {
        const {maps} = this.state
        const id = _.head(_.keys(maps))
        const {map = null} = maps[id] || {}
        return map
            ? func(map)
            : null
    }

    removeMap(id) {
        const {maps} = this.state
        const {map, area, listeners, subscriptions} = maps[id]
        const {google} = map.getGoogle()
        log.debug(() => `Removing ${mapTag(this.state.mapId, id)} (${area})`)
        listeners.forEach(listener =>
            google.maps.event.removeListener(listener)
        )
        subscriptions.forEach(subscription =>
            subscription.unsubscribe()
        )
        this.setState(
            ({maps}) => ({maps: _.omit(maps, id)})
        )
    }

    synchronizeOut(map, area) {
        const {overlay} = this.state
        const view = map.getView()
        this.withAllMaps(({map, area: currentArea}) => {
            if (currentArea !== area) {
                map.setView(view)
            }
        })
        this.updateView$.next(view)
        if (area !== 'overlay') {
            overlay && overlay.map.setView(view)
        }
    }

    synchronizeIn(view) {
        const {overlay} = this.state
        this.withAllMaps(({map}) => map.setView(view))
        overlay && overlay.map.setView(view)
    }

    synchronizeCursor(cursorId, latLng, event) {
        const {layers: {mode}} = this.props
        const cursorArea = this.getArea(cursorId)
        if (event) {
            this.cursor$.next({
                screenPixel: {x: event.clientX, y: event.clientY},
                mapPixel: {x: event.layerX, y: event.layerY},
                cursorArea,
                latLng,
                mode
            })
        }
        this.withAllMaps(({id, map}) => {
{'fraction_non_alphanumeric': 0.1246684350132626, 'fraction_numerical': 0.00020403999183840033, 'mean_word_length': 2.6950621937429324, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3424047', 'n_tokens_mistral': 2903, 'n_tokens_neox': 2868, 'n_words': 673}