{"version":3,"sources":["../../common/src/model.ts","../../common/src/error.ts","../../common/src/interactive-map/delaunay-model.ts","../../common/src/map-model.ts","web-utils.tsx","index.tsx","app.tsx","web-interactive-map-screen.tsx","../../common/src/parsing.ts","../../common/src/pinzme-client.ts","../../common/src/common-strings.ts","../../common/src/interactive-map/linear-map-model.ts","../../common/src/app-info.ts","../../common/src/common-utils.ts","web-interactive-map-component.tsx","../../components/src/utils.ts","map-screen.tsx","marker-popup-component.tsx","marker-view-component.tsx","../../components/src/common-components-utils.ts","morda-component.tsx","reportWebVitals.ts","../../components/src/registry.ts"],"names":["obj","address","years","architect","style","name","photoUrl","cwUrl","year","url","wikipediaUrl","json","parseUserChannelInfo","id","parseNumber","isViewerParticipant","parseBoolean","isViewerAdmin","notify","canViewerJoin","unreadCount","parseNumberIfPresent","canViewerAddMarker","user","parseUser","isAdmin","joinedAt","parseDate","parseCommentData","markerId","date","viewerLiked","likesTotal","channelId","parseString","authorId","type","parseNonEmptyString","localizedName","parseDictionary","entityType","pinzmeAdminVerification","parseBooleanIfPresent","row","geoPoint","parseGeoPoint","imagePoint","parsePoint","mapId","image","parseImageWithSize","mapThumbnailUrl","activeSnapshotId","parseMarkerView","parseUserMarkerContent","createdAt","updatedAt","sourceUrl","parseStringIfPresent","ticketUrl","author","commentsEnabled","commentsTotal","contentHTML","fid","layer","copyrights","border","parseArray","map","el","center","distanceMeters","filePath","text","weblink","mimeType","contentUri","fileName","extension","model","parseDelaunayModel","requireField","viewerCanEdit","key","latitude","longitude","x","y","parseSize","width","height","size","isPublic","isGroup","channelKey","avatarUrl","title","isApproved","mapImageUrl","read","canViewerEdit","deadline","parseDateIfPresent","parseUserMarkerContentData","content","imageUrl","startDate","endDate","videoUrl","namespace","login","isBanned","email","BackendError","errorKey","params","Object","setPrototypeOf","prototype","errorMessage","errorJson","JSON","parse","param","e","Error","UnauthorizedError","points","parsePointMapping","DelaunayMapModel","delaunay","this","Delaunay","from","p","findTriangle","v","linearModel","trainModel","InteractiveLinearMapModel","apply","n","Math","floor","triangles","length","i","getTriangle","v1","v2","v3","getPoint","p1","p2","p3","pointInTriangle","convert","closest","find","inedges","t","Array","slice","pt","d1","sign","d2","d3","centerPosition","thumbnailUrl","snapshotId","View","flex","alignItems","justifyContent","ActivityIndicator","color","pinzmeBaseColor","ReactDOM","render","HashRouter","document","getElementById","reportWebVitals","Switch","Route","path","component","WebInteractiveMapScreen","MapScreenComponent","MordaComponent","match","useState","setMap","useEffect","pinzmeWeb","getInteractiveMapById","then","centeredActivityIndicator","flexDirection","alignContent","Text","fontSize","fontWeight","Image","source","uri","marginLeft","resizeMode","TouchableOpacity","onPress","Linking","openURL","appStorePinzMeUrl","appStoreMarketImageUrl","styles","imageMarket","googlePlayPinzMeUrl","googlePlayMarketImageUrl","WebInteractiveMapComponent","StyleSheet","create","array","isArray","CommonStringKeys","shouldBeArrayField","hasField","undefined","dict","constructor","shouldBeDictionaryField","s","parseInt","value","trim","expectedNotEmptyString","noRequiredField","invalidNumberJsonValue","invalidStringJsonValue","invalidBooleanJsonValue","Date","PinzmeClient","baseUrl","tokenProvider","appInfo","oldPassword","password","postRequest","newPassword","token","setToken","provideToken","getRequest","recaptchaToken","notificationToken","removeToken","deleteRequest","console","log","parseInteractiveMap","parseSnapshot","pointId","parseDraftPoint","parseInteractiveMapView","commentsJson","comment","parseComment","markersJson","parseMarker","markersViewsJson","markerView","channelParticipants","channelParticipant","parseChannelParticipant","compsJson","comp","parseCompilation","channelsJson","channel","parseChannel","parseMarkersJson","put","markerJson","base64","data","marker","parseCommentsJson","commentId","compilationName","compilationId","parseCompilations","compilations","parseMarkerViewsJson","compilation","unread","markers","objects","o","parseMetrofanObjectView","compId","parseChannels","destinationChannelId","channelPrefix","prefix","info","body","offset","limit","parseChannelParticipantsJson","users","parseReportCause","causeId","complainCauseId","entity","element","parseComplainStatus","abuserId","shareItems","request","canRetry","method","fullUrl","headers","Accept","Authorization","entries","serializeToHeaders","fetchPlus","stringify","response","status","error","backendError","options","tries","fetch","CommonStrings","en","tokenExpired","youAreNotAuthorized","youAreBanned","youShouldBePinzmeAdmin","notEnoughRightsToEditMarker","onlyAuthorCanEditComment","youShouldBeChannelAdmin","youShouldBeAuthorizedToChannelAccess","youShouldBeChannelParticipant","notAbleToCloneInSameChannel","incorrectLoginOrPassword","incorrectLogin","incorrectPassword","youAreRobot","moreComplexPassword","badToken","newPasswordShouldBeDifferent","currentInvalidPassword","notEmptyName","unavailableLogin","unavailableEmail","unavailableChannelLogin","unableToSendEmail","ru","xModel","parseLinearModel","yModel","allPoints","stub","bX","bY","forEach","point","push","A","jStat","AT","transpose","tmp","multiply","inv","ansX","ansY","a","b","c","lMM","applyModel","applicationName","toHeaderName","brand","buildNumber","bundleId","deviceId","deviceType","systemVersion","systemName","uniqueId","version","hasNotch","isLandscape","isTablet","result","kebabize","arr","reduce","characters","charactersLength","charAt","random","str","split","letter","idx","toUpperCase","toLowerCase","join","ms","Promise","resolve","setTimeout","now","snapshot","setSnapshot","currentPosition","setCurrentPosition","animatedPosition","useRef","Animated","ValueXY","current","listenerId","addListener","removeListener","showPositionRequestHint","setShowPositionRequestHint","locationEnabled","setLocationEnabled","userAgreed","setUserAgreed","getSnapshotById","lm","watchPosition","geoPosition","imagePosition","timing","toValue","duration","useNativeDriver","easing","Easing","linear","start","navigator","permissions","query","state","imageScreenWidth","Dimensions","get","imageScreenHeight","computeImageScreenHeight","Modal","animationType","transparent","visible","centeredView","modalView","marginBottom","textAlign","pointImageUrl","Pressable","ImageBackground","computePointPosition","marginTop","margin","backgroundColor","borderRadius","padding","shadowColor","shadowOffset","shadowOpacity","shadowRadius","elevation","reject","Geolocation","getCurrentPosition","position","coords","maximumAge","success","onGeolocationError","watchId","distanceFilter","clearWatch","showMarkerId","setShowMarkerId","setChannel","setMarkers","getMarkerById","realChannelId","getChannelById","getChannelMarkers","loadMarkers","MapContainer","zoom","bottom","top","TileLayer","attribution","m","LeafletMarker","onClick","window","history","replaceState","panTo","rightView","MarkerPopupComponent","onClose","left","zIndex","popupWidth","min","originalIconSize","L","Point","iconSize","iconPerson","Icon","iconUrl","iconAnchor","useMap","panToMarker","project","unproject","Marker","icon","eventHandlers","click","Tooltip","alignSelf","marginRight","paddingHorizontal","paddingVertical","setMarker","MarkerViewComponent","right","MdClose","imageHeight","setImageHeight","titleView","ScrollView","maxHeight","flexGrow","dangerouslySetInnerHTML","__html","onLayout","event","nativeEvent","layout","container","toLocaleString","iconGroup","likeIcon","flexWrap","imageView","imageSize","zoomScale","scale","scaledPointWidth","scaledPointHeight","description","bodyText","imageLink","fontFamily","link","fontStyle","borderBottomWidth","borderStyle","borderBottomColor","onPerfEntry","Function","getCLS","getFID","getFCP","getLCP","getTTFB","EmptyTokenProvider","_"],"mappings":"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","file":"static/js/main.07efd793.chunk.js","sourcesContent":["/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\nimport {\n parseArray,\n parseBoolean,\n parseBooleanIfPresent,\n parseDate,\n parseDateIfPresent,\n parseDictionary,\n parseNonEmptyString,\n parseNumber,\n parseNumberIfPresent,\n parseString,\n parseStringIfPresent,\n requireField,\n} from './parsing'\nimport { InteractiveMap, InteractiveMapDraftPoint, InteractiveMapModelSnapshot } from './map-model'\nimport { parseDelaunayModel } from './interactive-map/delaunay-model'\n\nexport type ID = number\n\nexport type LocalizedString = {\n [language: string]: string\n}\n\nexport interface GeoPoint {\n readonly latitude: number\n readonly longitude: number\n}\n\nexport function parseGeoPoint(json: any, key?: string): GeoPoint {\n if (key) {\n return parseGeoPoint(requireField(json, key))\n }\n return {\n latitude: parseNumber(json, 'latitude'),\n longitude: parseNumber(json, 'longitude'),\n }\n}\n\nexport interface Point {\n readonly x: number\n readonly y: number\n}\n\nexport function parsePoint(json: any, key?: string): Point {\n if (key) {\n return parsePoint(requireField(json, key))\n }\n return {\n x: parseNumber(json, 'x'),\n y: parseNumber(json, 'y'),\n }\n}\n\nexport interface Size {\n readonly width: number\n readonly height: number\n}\n\nexport function parseSize(json: any, key?: string): Size {\n if (key) {\n return parseSize(requireField(json, key))\n }\n return {\n width: parseNumber(json, 'width'),\n height: parseNumber(json, 'height'),\n }\n}\n\nexport interface ImageWithSize {\n readonly url: string\n readonly size: Size\n}\n\nexport function parseImageWithSize(json: any, key?: string): ImageWithSize {\n if (key) {\n return parseImageWithSize(requireField(json, key))\n }\n return {\n url: parseString(json, 'url'),\n size: parseSize(json, 'size'),\n }\n}\n\nexport interface UserChannelInfo {\n readonly name: string\n readonly isPublic: boolean\n readonly isGroup: boolean\n readonly channelKey: string\n readonly avatarUrl?: string\n readonly commentsEnabled: boolean\n}\n\nexport function parseUserChannelInfo(json: any, key?: string): UserChannelInfo {\n if (key) {\n return parseUserChannelInfo(requireField(json, key))\n }\n return {\n name: parseNonEmptyString(json, 'name'),\n isPublic: parseBoolean(json, 'isPublic'),\n isGroup: parseBoolean(json, 'isGroup'),\n channelKey: parseNonEmptyString(json, 'channelKey'),\n avatarUrl: parseStringIfPresent(json, 'avatarUrl'),\n commentsEnabled: parseBooleanIfPresent(json, 'commentsEnabled') ?? true, // TODO: remove ??\n }\n}\n\n/**\n * Отображение канала для пользователя\n */\nexport interface ChannelView extends UserChannelInfo {\n readonly id: ID\n /**\n * Является ли пользователь участником канала\n */\n readonly isViewerParticipant: boolean\n /**\n * Является ли пользователь, который смотрит на канал, его админом\n */\n readonly isViewerAdmin: boolean\n /**\n * Включены у пользователя нотификации о новых событиях в канале\n */\n readonly notify: boolean\n /**\n * Количество непрочитанных у пользователя точек в канале\n */\n readonly unreadCount?: number\n /**\n * Может ли пользователь стать участником канала\n */\n readonly canViewerJoin: boolean\n /**\n * Может ли пользователь добавить маркер\n */\n readonly canViewerAddMarker: boolean\n}\n\nexport function parseChannel(json: any): ChannelView {\n return {\n ...parseUserChannelInfo(json),\n id: parseNumber(json, 'id'),\n isViewerParticipant: parseBoolean(json, 'isViewerParticipant'),\n isViewerAdmin: parseBoolean(json, 'isViewerAdmin'),\n notify: parseBoolean(json, 'notify'),\n canViewerJoin: parseBoolean(json, 'canViewerJoin'),\n unreadCount: parseNumberIfPresent(json, 'unreadCount'),\n canViewerAddMarker: parseBoolean(json, 'canViewerAddMarker'),\n }\n}\n\nexport interface ChannelParticipant {\n readonly user: User\n readonly isAdmin: boolean\n readonly joinedAt: Date\n}\n\nexport function parseChannelParticipant(json: any): ChannelParticipant {\n return {\n user: parseUser(json.user),\n isAdmin: parseBoolean(json, 'isAdmin'),\n joinedAt: parseDate(json, 'joinedAt'),\n }\n}\n\nexport interface MarkerMapView {\n readonly id?: ID\n // ключ идемпотентности на клиенте, чтобы различать добавляемые точки\n readonly key?: string\n readonly geoPoint: GeoPoint\n readonly title: string\n readonly mapImageUrl?: string\n readonly canViewerEdit: boolean\n readonly address: string\n readonly deadline?: Date\n readonly read: boolean\n}\n\nexport interface MarkerView extends MarkerMapView {\n readonly id: ID\n readonly mapImageUrl: string\n readonly isApproved?: boolean\n}\n\nexport function parseMarkerView(json: any): MarkerView {\n return {\n id: parseNumber(json, 'id'),\n address: parseString(json, 'address'),\n geoPoint: parseGeoPoint(json, 'geoPoint'),\n title: parseString(json, 'title'),\n isApproved: parseBooleanIfPresent(json, 'isApproved'),\n mapImageUrl: parseString(json, 'mapImageUrl'),\n read: parseBoolean(json, 'read'),\n canViewerEdit: parseBoolean(json, 'canViewerEdit'),\n deadline: parseDateIfPresent(json, 'deadline'),\n }\n}\n\nexport interface UserMarkerContentData {\n readonly title: string\n readonly content: string\n readonly imageUrl?: string\n readonly startDate?: Date\n readonly endDate?: Date\n readonly videoUrl?: string\n readonly deadline?: Date\n}\n\nexport function parseUserMarkerContentData(json: any): UserMarkerContentData {\n return {\n title: parseNonEmptyString(json, 'title'),\n content: parseString(json, 'content'),\n imageUrl: parseStringIfPresent(json, 'imageUrl'),\n startDate: parseDateIfPresent(json, 'startDate'),\n endDate: parseDateIfPresent(json, 'endDate'),\n videoUrl: parseStringIfPresent(json, 'videoUrl'),\n deadline: parseDateIfPresent(json, 'deadline'),\n }\n}\n\nexport interface UserMarkerContent extends UserMarkerContentData {\n readonly namespace?: string\n // ключ идемпотентности, чтобы одна и та же точка не добавилась 2 раза\n readonly key?: string\n readonly address: string // TODO: почему тут нет ?\n readonly geoPoint: GeoPoint\n // пользователь может передать дату при создании точки\n // необходимо для корректного отображения даты у офлайн точек\n readonly createdAt?: Date\n}\n\nexport function parseUserMarkerContent(json: any): UserMarkerContent {\n return {\n ...parseUserMarkerContentData(json),\n namespace: parseStringIfPresent(json, 'namespace'),\n key: parseStringIfPresent(json, 'key'),\n address: parseString(json, 'address'),\n geoPoint: parseGeoPoint(json, 'geoPoint'),\n createdAt: parseDateIfPresent(json, 'createdAt'),\n }\n}\n\nexport interface AddMarkerRequest extends UserMarkerContent {\n readonly channelId: ID\n readonly authorId: ID\n readonly sourceUrl?: string\n readonly ticketUrl?: string\n readonly isApproved?: boolean\n}\n\nexport interface Marker extends MarkerView, AddMarkerRequest {\n readonly createdAt: Date\n readonly updatedAt: Date\n readonly author: User\n readonly viewerLiked: boolean\n readonly likesTotal: number\n readonly commentsEnabled: boolean\n readonly commentsTotal: number\n readonly contentHTML: string\n}\n\nexport interface MetrofanObject {\n readonly fid: ID\n readonly address?: string\n readonly years?: string\n readonly architect?: string\n readonly style?: string\n readonly name?: string\n readonly photoUrl?: string\n readonly cwUrl?: string\n readonly layer?: string\n readonly year?: number\n readonly url?: string\n readonly copyrights?: string\n readonly wikipediaUrl?: string\n readonly border: GeoPoint[]\n}\n\nexport interface MetrofanObjectView extends MetrofanObject {\n readonly center: GeoPoint\n readonly distanceMeters: number\n}\n\nexport function isEmptyMetrofanObject(obj: MetrofanObject): boolean {\n return (\n !obj.address &&\n !obj.years &&\n !obj.architect &&\n !obj.style &&\n !obj.name &&\n !obj.photoUrl &&\n !obj.cwUrl &&\n !obj.year &&\n !obj.url &&\n !obj.wikipediaUrl\n )\n}\n\nexport function parseMetrofanObjectView(json: any): MetrofanObjectView {\n return {\n fid: parseNumber(json, 'fid'),\n address: parseString(json, 'address'),\n years: parseStringIfPresent(json, 'years'),\n architect: parseStringIfPresent(json, 'architect'),\n style: parseStringIfPresent(json, 'style'),\n name: parseStringIfPresent(json, 'name'),\n photoUrl: parseStringIfPresent(json, 'photoUrl'),\n cwUrl: parseStringIfPresent(json, 'cwUrl'),\n layer: parseString(json, 'layer'),\n year: parseNumberIfPresent(json, 'year'),\n url: parseStringIfPresent(json, 'url'),\n copyrights: parseStringIfPresent(json, 'copyrights'),\n wikipediaUrl: parseStringIfPresent(json, 'wikipediaUrl'),\n border: parseArray(json, 'border').map((el) => parseGeoPoint(el)),\n center: parseGeoPoint(json, 'center'),\n distanceMeters: parseNumber(json, 'distanceMeters'),\n }\n}\n\nexport interface Compilation {\n readonly id: ID\n readonly channelId: ID\n readonly name: string\n readonly authorId: ID\n}\n\n// обратная операция к JSON.stringify()\n\nexport function parseCompilation(json: any): Compilation {\n return {\n id: parseNumber(json, 'id'),\n channelId: parseNumber(json, 'channelId'),\n name: parseString(json, 'name'),\n authorId: parseNumber(json, 'authorId'),\n }\n}\n\nexport function parseMarker(json: any): Marker {\n return {\n ...parseMarkerView(json),\n ...parseUserMarkerContent(json),\n channelId: parseNumber(json, 'channelId'),\n authorId: parseNumber(json, 'authorId'),\n createdAt: parseDate(json, 'createdAt'),\n updatedAt: parseDate(json, 'updatedAt'),\n sourceUrl: parseStringIfPresent(json, 'sourceUrl'),\n ticketUrl: parseStringIfPresent(json, 'ticketUrl'),\n author: parseUser(json, 'author'),\n viewerLiked: parseBoolean(json, 'viewerLiked'),\n likesTotal: parseNumber(json, 'likesTotal'),\n commentsEnabled: parseBoolean(json, 'commentsEnabled'),\n commentsTotal: parseNumber(json, 'commentsTotal'),\n contentHTML: parseString(json, 'contentHTML'),\n }\n}\n\nexport interface User {\n readonly id: number\n readonly login: string\n readonly isAdmin: boolean\n readonly name?: string\n readonly avatarUrl?: string\n readonly isBanned: boolean\n readonly email?: string\n}\n\nexport function parseUser(json: any, key?: string): User {\n if (key) {\n return parseUser(requireField(json, key))\n }\n return {\n id: parseNumber(json, 'id'),\n login: parseString(json, 'login'),\n isAdmin: parseBoolean(json, 'isAdmin'),\n name: parseStringIfPresent(json, 'name'),\n avatarUrl: parseStringIfPresent(json, 'avatarUrl'),\n isBanned: parseBoolean(json, 'isBanned'),\n email: parseStringIfPresent(json, 'email'),\n }\n}\n\nexport interface CommentData {\n readonly text: string\n readonly imageUrl?: string\n}\n\nexport function parseCommentData(json: any): CommentData {\n return {\n text: parseString(json, 'text'),\n imageUrl: parseStringIfPresent(json, 'imageUrl'),\n }\n}\n\nexport interface Comment extends CommentData {\n readonly id: ID\n readonly markerId: ID\n readonly user: User\n readonly date: Date\n readonly viewerLiked: boolean\n readonly likesTotal: number\n}\n\nexport function parseComment(json: any): Comment {\n return {\n ...parseCommentData(json),\n id: parseNumber(json, 'id'),\n markerId: parseNumber(json, 'markerId'),\n user: parseUser(json, 'user'),\n date: parseDate(json, 'date'),\n viewerLiked: parseBoolean(json, 'viewerLiked'),\n likesTotal: parseNumber(json, 'likesTotal'),\n }\n}\n\nexport function parseDraftPoint(row: any): InteractiveMapDraftPoint {\n return {\n id: parseNumber(row, 'id'),\n geoPoint: parseGeoPoint(row, 'geoPoint'),\n imagePoint: parsePoint(row, 'imagePoint'),\n mapId: parseNumber(row, 'mapId'),\n authorId: parseNumber(row, 'authorId'),\n }\n}\n\nexport function parseSnapshot(row: any): InteractiveMapModelSnapshot {\n return {\n id: parseNumber(row, 'id'),\n name: parseString(row, 'name'),\n image: parseImageWithSize(row, 'image'),\n mapId: parseNumber(row, 'mapId'),\n model: parseDelaunayModel(requireField(row, 'model')),\n viewerCanEdit: parseBoolean(row, 'viewerCanEdit'),\n }\n}\n\nexport function parseInteractiveMap(row: any): InteractiveMap {\n return {\n id: parseNumber(row, 'id'),\n name: parseString(row, 'name'),\n image: parseImageWithSize(row, 'image'),\n mapThumbnailUrl: parseString(row, 'mapThumbnailUrl'),\n activeSnapshotId: parseNumberIfPresent(row, 'activeSnapshotId'),\n }\n}\n\nexport interface ReportCause {\n readonly id: ID\n readonly name: string // TODO: deprecated\n readonly localizedName: LocalizedString\n}\n\nexport function parseReportCause(json: any): ReportCause {\n return {\n id: parseNumber(json, 'id'),\n name: parseString(json, 'name'),\n localizedName: parseDictionary(json, 'localizedName'),\n }\n}\n\nexport interface ComplainStatus {\n readonly id: ID\n readonly name: string // TODO: deprecated\n readonly localizedName: LocalizedString\n readonly entityType: string\n readonly pinzmeAdminVerification?: boolean\n}\n\nexport function parseComplainStatus(json: any): ComplainStatus {\n return {\n id: parseNumber(json, 'id'),\n name: parseString(json, 'name'),\n localizedName: parseDictionary(json, 'localizedName'),\n entityType: parseString(json, 'entityType'),\n pinzmeAdminVerification: parseBooleanIfPresent(json, 'pinzmeAdminVerification'),\n }\n}\n\nexport interface ComplainEntity {\n readonly type: string\n readonly id: ID\n}\n\nexport function parseComplainEntity(json: any): ComplainEntity {\n return {\n type: parseNonEmptyString(json, 'type'),\n id: parseNumber(json, 'id'),\n }\n}\n\nexport interface ShareItem {\n readonly filePath?: string\n readonly text?: string\n readonly weblink?: string\n readonly mimeType?: string\n readonly contentUri?: string\n readonly fileName?: string\n readonly extension?: string\n}\n\nexport function parseShareItem(json: any): ShareItem {\n return {\n filePath: parseStringIfPresent(json, 'filePath'),\n text: parseStringIfPresent(json, 'text'),\n weblink: parseStringIfPresent(json, 'weblink'),\n mimeType: parseStringIfPresent(json, 'mimeType'),\n contentUri: parseStringIfPresent(json, 'contentUri'),\n fileName: parseStringIfPresent(json, 'fileName'),\n extension: parseStringIfPresent(json, 'extension'),\n }\n}\n","import { CommonStringKeys } from './common-strings'\nimport { parseArray, parseNonEmptyString } from './parsing'\n\nexport class BackendError extends Error {\n // see LocalizedStringsMethods.formatString\n constructor(public readonly errorKey: CommonStringKeys, public readonly params: string[] = []) {\n super(errorKey)\n // Set the prototype explicitly.\n Object.setPrototypeOf(this, BackendError.prototype)\n }\n\n public static parse(errorMessage: string): BackendError | undefined {\n try {\n const errorJson = JSON.parse(errorMessage)\n const errorKey = parseNonEmptyString(errorJson, 'errorKey')\n const params = parseArray(errorJson, 'params').map((param) => param as string)\n return new BackendError(errorKey as CommonStringKeys, params)\n } catch (e) {\n return undefined\n }\n }\n}\n\nexport class UnauthorizedError extends Error {\n constructor() {\n super()\n // Set the prototype explicitly.\n Object.setPrototypeOf(this, UnauthorizedError.prototype)\n }\n}\n","/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\nimport { GeoPoint, ID, Point } from '../model'\nimport { parseArray } from '../parsing'\nimport { InteractiveMapModel, parsePointMapping, PointMapping } from '../map-model'\nimport { Delaunay } from 'd3-delaunay'\nimport { InteractiveLinearMapModel, trainModel } from './linear-map-model'\n\nexport interface DelaunayModel {\n readonly points: PointMapping[]\n}\n\nexport function parseDelaunayModel(json: any): DelaunayModel {\n return {\n points: parseArray(json, 'points').map((el) => parsePointMapping(el)),\n }\n}\n\nexport class DelaunayMapModel implements InteractiveMapModel {\n private readonly delaunay: Delaunay\n\n constructor(private readonly model: DelaunayModel) {\n this.delaunay = Delaunay.from(\n model.points,\n (p) => p.geoPoint.latitude,\n (p) => p.geoPoint.longitude,\n )\n }\n\n apply(geoPoint: GeoPoint): Point {\n const triangle = this.findTriangle(geoPoint)\n const points = triangle.map((v) => this.model.points[v])\n const linearModel = trainModel(points)\n return new InteractiveLinearMapModel(linearModel).apply(geoPoint)\n }\n\n private findTriangle(geoPoint: GeoPoint): ID[] {\n const n = Math.floor(this.delaunay.triangles.length / 3)\n for (let i = 0; i < n; i++) {\n const [v1, v2, v3] = this.getTriangle(i)\n const [p1, p2, p3] = [v1, v2, v3].map((v) => this.getPoint(v))\n if (this.pointInTriangle(this.convert(geoPoint), p1, p2, p3)) {\n return [v1, v2, v3]\n }\n }\n const closest = this.delaunay.find(geoPoint.latitude, geoPoint.longitude)\n const e = this.delaunay.inedges[closest]\n const t = Math.floor(e / 3)\n return this.getTriangle(t)\n }\n\n private convert(geoPoint: GeoPoint): Point {\n return {\n x: geoPoint.latitude,\n y: geoPoint.longitude,\n }\n }\n\n private getPoint(i: ID): Point {\n const [x, y] = Array.from(this.delaunay.points).slice(2 * i, 2 * i + 2)\n return { x, y }\n }\n\n private getTriangle(i: ID): ID[] {\n return Array.from(this.delaunay.triangles.slice(3 * i, 3 * i + 3))\n }\n\n private sign(p1: Point, p2: Point, p3: Point): number {\n return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y)\n }\n\n private pointInTriangle(pt: Point, v1: Point, v2: Point, v3: Point): boolean {\n const d1 = this.sign(pt, v1, v2)\n const d2 = this.sign(pt, v2, v3)\n const d3 = this.sign(pt, v3, v1)\n const hasNeg = d1 < 0 || d2 < 0 || d3 < 0\n const hasPos = d1 > 0 || d2 > 0 || d3 > 0\n return !(hasNeg && hasPos)\n }\n}\n","/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\n// why are properties readonly here and how does it all come together?\n// https://www.typescriptlang.org/docs/handbook/2/objects.html#readonly-properties\nimport { GeoPoint, ID, ImageWithSize, parseGeoPoint, parsePoint, Point } from './model'\nimport { parseNumber, parseString } from './parsing'\nimport { DelaunayModel } from './interactive-map/delaunay-model'\n\nexport interface InteractiveMapModel {\n apply(geoPoint: GeoPoint): Point\n}\n\nexport interface PointMapping {\n readonly geoPoint: GeoPoint\n readonly imagePoint: Point\n}\n\nexport function parsePointMapping(json: any): PointMapping {\n return {\n geoPoint: parseGeoPoint(json, 'geoPoint'),\n imagePoint: parsePoint(json, 'imagePoint'),\n }\n}\n\nexport interface UserPoint extends PointMapping {\n readonly authorId: ID\n}\n\nexport interface InteractiveMapDraftPoint extends UserPoint {\n readonly id: ID\n readonly mapId: ID\n}\n\nexport interface InteractiveMapContent {\n readonly name: string\n readonly image: ImageWithSize\n}\n\nexport interface InteractiveMap extends InteractiveMapContent {\n readonly id: ID\n readonly activeSnapshotId?: ID\n readonly mapThumbnailUrl: string\n}\n\nexport interface InteractiveMapModelSnapshot extends InteractiveMapContent {\n readonly id: ID\n readonly model: DelaunayModel\n readonly mapId: ID\n readonly viewerCanEdit: boolean\n}\n\nexport interface InteractiveMapModelSnapshotPoints extends InteractiveMapModelSnapshot {\n readonly points: UserPoint[]\n}\n\nexport interface InteractiveMapView {\n readonly id: ID\n readonly name: string\n readonly centerPosition: GeoPoint\n readonly thumbnailUrl: string\n readonly snapshotId: ID\n}\n\nexport function parseInteractiveMapView(row: any): InteractiveMapView {\n return {\n id: parseNumber(row, 'id'),\n name: parseString(row, 'name'),\n centerPosition: parseGeoPoint(row, 'centerPosition'),\n thumbnailUrl: parseString(row, 'thumbnailUrl'),\n snapshotId: parseNumber(row, 'snapshotId'),\n }\n}\n","import { ActivityIndicator, View } from 'react-native'\nimport { pinzmeBaseColor } from '@pinzme/components/src/common-components-utils'\nimport { ReactElement } from 'react'\n\nexport function centeredActivityIndicator(): ReactElement {\n return (\n \n \n \n )\n}\n","import ReactDOM from 'react-dom'\nimport './index.css'\nimport App from './app'\nimport reportWebVitals from './reportWebVitals'\nimport { HashRouter } from 'react-router-dom'\n\nReactDOM.render(\n \n \n ,\n document.getElementById('root'),\n)\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals()\n","import { ReactElement } from 'react'\nimport './app.css'\nimport { WebInteractiveMapScreen } from './web-interactive-map-screen'\nimport { Route, Switch } from 'react-router-dom'\nimport { MapScreenComponent } from './map-screen'\nimport { MordaComponent } from './morda-component'\n\nfunction App(): ReactElement {\n return (\n \n \n \n \n \n \n )\n}\n\nexport default App\n","import { Image, Linking, StyleSheet, Text, TouchableOpacity, View } from 'react-native'\nimport { ReactElement, useEffect, useState } from 'react'\nimport { ID } from '@pinzme/common/src/model'\nimport { pinzmeWeb } from '@pinzme/components/src/registry'\nimport { InteractiveMap } from '@pinzme/common/src/map-model'\nimport { WebInteractiveMapComponent } from './web-interactive-map-component'\nimport {\n appStoreMarketImageUrl,\n appStorePinzMeUrl,\n googlePlayMarketImageUrl,\n googlePlayPinzMeUrl,\n} from '@pinzme/components/src/common-components-utils'\nimport { centeredActivityIndicator } from './web-utils'\n\ninterface MapMatchParams {\n id: ID\n}\n\ninterface MapMatch {\n params: MapMatchParams\n}\n\nexport function WebInteractiveMapScreen({ match }: { match: MapMatch }): ReactElement {\n const [map, setMap] = useState()\n\n useEffect(() => {\n void pinzmeWeb.getInteractiveMapById(match.params.id).then(setMap)\n }, [match.params.id])\n\n if (!map?.activeSnapshotId) {\n return centeredActivityIndicator()\n }\n\n return (\n \n \n \n {map.name}\n \n \n \n Это и многое другое в приложении\n \n \n \n {\n void Linking.openURL(appStorePinzMeUrl)\n }}\n >\n \n \n {\n void Linking.openURL(googlePlayPinzMeUrl)\n }}\n >\n \n \n \n \n \n \n \n )\n}\n\nconst styles = StyleSheet.create({\n imageMarket: {\n width: 646 / 6,\n height: 250 / 6,\n },\n})\n","/* eslint-disable @typescript-eslint/no-unsafe-return,@typescript-eslint/explicit-module-boundary-types */\n\nimport { BackendError } from './error'\nimport { CommonStringKeys } from './common-strings'\n\nexport function hasField(json: any, key: string): boolean {\n const value = json[key]\n return value !== undefined && value !== null\n}\n\nexport function requireField(json: any, key: string): any {\n if (hasField(json, key)) {\n return json[key]\n }\n throw new BackendError(CommonStringKeys.noRequiredField, [key])\n}\n\nexport function parseNumber(json: any, key: string): number {\n const value = requireField(json, key)\n if (typeof value === 'number') {\n return value\n }\n if (typeof value === 'string') {\n return +value\n }\n throw new BackendError(CommonStringKeys.invalidNumberJsonValue, [key, typeof value])\n}\n\nexport function parseNumberIfPresent(json: any, key: string): number | undefined {\n return hasField(json, key) ? parseNumber(json, key) : undefined\n}\n\nexport function parseString(json: any, key: string): string {\n const value = requireField(json, key)\n if (typeof value === 'string') {\n return value\n }\n throw new BackendError(CommonStringKeys.invalidStringJsonValue, [key, typeof value])\n}\n\nexport function parseStringIfPresent(json: any, key: string): string | undefined {\n return hasField(json, key) ? parseString(json, key) : undefined\n}\n\nexport function parseStringIfNonEmpty(json: any, key: string): string | undefined {\n const value = parseStringIfPresent(json, key)\n return value?.trim().length ? value : undefined\n}\n\nexport function parseBoolean(json: any, key: string): boolean {\n const value = requireField(json, key)\n if (typeof value === 'boolean') {\n return value\n }\n if (value === 'true') {\n return true\n }\n if (value === 'false') {\n return false\n }\n throw new BackendError(CommonStringKeys.invalidBooleanJsonValue, [key, typeof value])\n}\n\nexport function parseBooleanIfPresent(json: any, key: string): boolean | undefined {\n return hasField(json, key) ? parseBoolean(json, key) : undefined\n}\n\nexport function parseDate(json: any, key: string): Date {\n const value = requireField(json, key)\n if (value instanceof Date) {\n return value\n }\n return new Date(parseString(json, key))\n}\n\nexport function parseDateIfPresent(json: any, key: string): Date | undefined {\n return hasField(json, key) ? parseDate(json, key) : undefined\n}\n\nexport function parseNonEmptyString(json: any, key: string): string {\n const value = parseString(json, key)\n if (!value.trim().length) {\n throw new BackendError(CommonStringKeys.expectedNotEmptyString, [key])\n }\n return value\n}\n\nexport function parseIntIfPresent(s?: string): number | undefined {\n return s ? parseInt(s, 10) : undefined\n}\n\nexport function parseArray(json: any, key: string): any[] {\n const array = requireField(json, key)\n if (!Array.isArray(array)) {\n throw new BackendError(CommonStringKeys.shouldBeArrayField, [key])\n }\n return array\n}\n\nexport function parseDictionary(json: any, key: string): { [key: string]: any } {\n const dict = requireField(json, key)\n if (dict.constructor !== Object) {\n throw new BackendError(CommonStringKeys.shouldBeDictionaryField, [key])\n }\n return dict\n}\n","import {\n ChannelParticipant,\n ChannelView,\n Comment,\n CommentData,\n Compilation,\n ComplainStatus,\n GeoPoint,\n ID,\n Marker,\n MarkerView,\n parseChannel,\n parseChannelParticipant,\n parseComment,\n parseCompilation,\n parseComplainStatus,\n parseInteractiveMap,\n parseMarker,\n parseMarkerView,\n parseReportCause,\n parseUser,\n ReportCause,\n User,\n UserChannelInfo,\n UserMarkerContent,\n parseDraftPoint,\n Point,\n parseSnapshot,\n ComplainEntity,\n ShareItem,\n UserMarkerContentData,\n parseUserMarkerContentData,\n MetrofanObjectView,\n parseMetrofanObjectView,\n} from './model'\nimport { TokenProvider } from './token-provider'\nimport { parseArray, parseBoolean, parseNonEmptyString, parseNumber, parseString, requireField } from './parsing'\nimport { PinzMe } from './pinzme'\nimport { InteractiveMap, InteractiveMapModelSnapshot, InteractiveMapView, parseInteractiveMapView } from './map-model'\nimport { InteractiveMapDraftPoint } from './map-model'\nimport { BackendError, UnauthorizedError } from './error'\nimport { AppInfo, serializeToHeaders } from './app-info'\n\nexport class PinzmeClient implements PinzMe {\n constructor(\n private readonly baseUrl: string,\n private readonly tokenProvider: TokenProvider,\n private readonly appInfo: AppInfo,\n ) {}\n\n public async changePassword(oldPassword: string, password: string): Promise {\n await this.postRequest('/user/changePassword', { oldPassword, password })\n }\n\n public async changePasswordByEncryptedUser(newPassword: string, token: string): Promise {\n await this.postRequest('/user/changePasswordByEncryptedUser', { newPassword, token })\n }\n\n public async login(login: string, password: string): Promise {\n const json = await this.postRequest('/login', { login, password }, true)\n const token = parseNonEmptyString(json, 'token')\n await this.tokenProvider.setToken(token)\n return token\n }\n\n public async restore(email: string): Promise {\n await this.postRequest('/restore', { email })\n }\n\n public async isAuthorized(): Promise {\n const token = await this.tokenProvider.provideToken()\n return token !== undefined\n }\n\n public async whoami(): Promise {\n const json = await this.getRequest('/whoami')\n return parseUser(json)\n }\n\n public async register(login: string, password: string, recaptchaToken: string): Promise {\n const json = await this.postRequest('/register', { login, password, recaptchaToken })\n return parseNumber(json, 'id')\n }\n\n public async updateName(name: string): Promise {\n await this.postRequest('/user/update-name', { name }, true)\n }\n\n public async updateLogin(login: string): Promise {\n await this.postRequest('/user/update-login', { login }, true)\n }\n\n public async updateEmail(email?: string): Promise {\n await this.postRequest('/user/update-email', { email }, true)\n }\n\n public async updateNotificationToken(notificationToken: string): Promise {\n await this.postRequest(\n '/notification/token',\n {\n notificationToken,\n },\n true,\n )\n }\n\n public async logout(): Promise {\n await this.getRequest('/logout')\n await this.tokenProvider.removeToken()\n }\n\n public async newInteractiveMap(name: string, imageUrl: string): Promise {\n const json = await this.postRequest('/map/add', { name, imageUrl })\n return parseNumber(json, 'mapId')\n }\n\n public async deleteInteractiveMap(id: ID): Promise {\n await this.deleteRequest(`/interactive-map/${id}`)\n }\n\n public async deleteDraft(mapId: ID): Promise {\n await this.postRequest('/draft/delete', { mapId })\n }\n\n public async getAllInteractiveMaps(): Promise {\n const json = await this.getRequest('/map/getAll')\n console.log(json)\n return parseArray(json, 'maps').map((el) => parseInteractiveMap(el))\n }\n\n public async getInteractiveMapById(mapId: ID): Promise {\n const json = await this.getRequest(`/map/get/id/${mapId}`)\n return parseInteractiveMap(requireField(json, 'map'))\n }\n\n public async editInteractiveMap(mapId: ID): Promise {\n await this.postRequest(`/map/edit/id/${mapId}`)\n }\n\n public async submitInteractiveMap(mapId: ID): Promise {\n const json = await this.postRequest(`/map/submit/id/${mapId}`)\n return parseNumber(json, 'snapshotId')\n }\n\n public async getSnapshotById(snapshotId: ID): Promise {\n const json = await this.getRequest(`/snapshot/get/${snapshotId}`)\n return parseSnapshot(requireField(json, 'snapshot'))\n }\n\n public async addDraftPoint(geoPoint: GeoPoint, imagePoint: Point, mapId: ID): Promise {\n const json = await this.postRequest('/draft/point/add', { geoPoint, imagePoint, mapId })\n return parseNumber(json, 'pointId')\n }\n\n public async editDraftPoint(pointId: ID, geoPoint: GeoPoint, imagePoint: Point): Promise {\n await this.postRequest('/draft/point/edit', { pointId, geoPoint, imagePoint })\n }\n\n public async deleteDraftPoint(pointId: ID): Promise {\n await this.postRequest('/draft/point/delete', { pointId })\n }\n\n public async getAllDraftPoints(mapId: ID): Promise {\n const json = await this.getRequest(`/draft/${mapId}/getAll`)\n return parseArray(json, 'points').map((el) => parseDraftPoint(el))\n }\n\n public async getChannelInteractiveMaps(channelId: ID): Promise {\n const json = await this.getRequest(`/channel/${channelId}/interactive-maps`)\n return parseArray(json, 'interactiveMaps').map((el) => parseInteractiveMapView(el))\n }\n\n private parseCommentsJson(commentsJson: any[]): Comment[] {\n return commentsJson.map((comment) => parseComment(comment))\n }\n\n private parseMarkersJson(markersJson: any[]): Marker[] {\n return markersJson.map(parseMarker)\n }\n\n private parseMarkerViewsJson(markersViewsJson: any[]): MarkerView[] {\n return markersViewsJson.map((markerView) => parseMarkerView(markerView))\n }\n\n private parseChannelParticipantsJson(channelParticipants: any[]): ChannelParticipant[] {\n return channelParticipants.map((channelParticipant) => parseChannelParticipant(channelParticipant))\n }\n\n private parseCompilations(compsJson: any[]): Compilation[] {\n return compsJson.map((comp) => parseCompilation(comp))\n }\n\n private parseChannels(channelsJson: any[]): ChannelView[] {\n return channelsJson.map((channel) => parseChannel(channel))\n }\n\n public async validateLogin(login: string): Promise {\n const json = await this.postRequest('/login/validate', { login }, true)\n return parseBoolean(json, 'ok')\n }\n\n public async validateChannelKey(key: string, channelId?: ID): Promise {\n if (!key.trim().length) {\n return false\n }\n const json = await this.postRequest(\n '/channel/validate',\n {\n channelKey: key,\n channelId,\n },\n true,\n )\n return parseBoolean(json, 'valid')\n }\n\n public async getUncheckedMarkers(channelId: ID): Promise {\n const markersJson = await this.getRequest(`/markers/get-unchecked/${channelId}`)\n return this.parseMarkersJson(markersJson)\n }\n\n public async getComplainedMarkers(): Promise {\n const markersJson = await this.getRequest('/markers/complained')\n return this.parseMarkersJson(markersJson)\n }\n\n public async approveMarker(id: ID): Promise {\n await this.put(`/marker/${id}/approve`)\n }\n\n public async declineMarker(id: ID): Promise {\n await this.deleteRequest(`/marker/${id}/approve`)\n }\n\n public async getMarkerById(id: ID): Promise {\n const markerJson = await this.getRequest(`/marker/${id}`)\n return parseMarker(markerJson)\n }\n\n public async uploadPhoto(base64: string): Promise {\n const url = await this.postRequest('/upload', {\n data: base64,\n })\n return parseString(url, 'imageUrl')\n }\n\n public async setAvatar(url: string): Promise {\n await this.postRequest('/user/set-avatar', { url })\n return url\n }\n\n public async addMarker(channelId: ID, marker: UserMarkerContent): Promise {\n const json = await this.put(`/channel/${channelId}/marker`, marker, true)\n return parseNumber(json, 'markerId')\n }\n\n public async modifyMarkerGeoPoint(markerId: ID, geoPoint: GeoPoint): Promise {\n const json = await this.postRequest(`/marker/${markerId}/location`, geoPoint, true)\n return parseNumber(json, 'markerId')\n }\n\n public async modifyMarker(markerId: ID, marker: UserMarkerContent): Promise {\n const json = await this.postRequest(`/marker/${markerId}`, marker, true)\n return parseNumber(json, 'markerId')\n }\n\n public async deleteMarker(markerId: ID): Promise {\n await this.deleteRequest(`/marker/${markerId}`)\n }\n\n public async like(markerId: ID): Promise {\n await this.put(`/marker/${markerId}/like`)\n }\n\n public async unlike(markerId: ID): Promise {\n await this.deleteRequest(`/marker/${markerId}/like`)\n }\n\n public async getMyLikes(): Promise {\n const json = await this.getRequest('/likes/get-markers')\n return this.parseMarkersJson(json)\n }\n\n public async getComments(markerId: ID): Promise {\n const json = await this.getRequest(`/comments?marker=${markerId}`)\n return this.parseCommentsJson(json)\n }\n\n public async comment(markerId: ID, data: CommentData): Promise {\n const json = await this.put(`/marker/${markerId}/comment`, data)\n return parseNumber(json, 'commentId')\n }\n\n public async deleteComment(commentId: ID): Promise {\n await this.deleteRequest(`/comment/${commentId}`)\n }\n\n public async editComment(commentId: ID, text: string): Promise {\n await this.postRequest(`/comment/${commentId}`, { text })\n }\n\n public async likeComment(commentId: ID): Promise {\n await this.put(`/comment/${commentId}/like`)\n }\n\n public async unlikeComment(commentId: ID): Promise {\n await this.deleteRequest(`/comment/${commentId}/like`)\n }\n\n public async createCompilation(channelId: ID, compilationName: string): Promise {\n const json = await this.postRequest('/compilation/add', {\n channelId,\n name: compilationName,\n })\n return parseNumber(json, 'id')\n }\n\n public async deleteCompilation(compilationId: ID): Promise {\n await this.deleteRequest('/compilation/delete', { id: compilationId })\n }\n\n public async getChannelCompilations(channelId: ID): Promise {\n const json = await this.getRequest(`/compilation/channel/${channelId}`)\n return this.parseCompilations(json.compilations)\n }\n\n public async getCompilationMarkers(compilationId: ID): Promise {\n const json = await this.getRequest(`/compilation/${compilationId}/info`)\n return this.parseMarkerViewsJson(json.compilation)\n }\n\n public async getChannelMarkers(channelId: ID, unread?: boolean): Promise {\n let url = `/channel/markers/${channelId}`\n if (unread !== undefined) {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n url += `?unread=${unread}`\n }\n const json = await this.getRequest(url)\n return this.parseMarkerViewsJson(json.markers)\n }\n\n public async getMetrofanObjects(center: GeoPoint): Promise {\n const json = await this.postRequest('/metrofan/objects', center)\n const objects = parseArray(json, 'objects')\n return objects.map((o) => parseMetrofanObjectView(o))\n }\n\n public async addMarkerToCompilation(compId: ID, markerId: ID): Promise {\n await this.postRequest('/compilation/marker/add', { compilation: compId, marker: markerId })\n }\n\n public async deleteMarkerFromCompilation(compId: ID, markerId: ID): Promise {\n await this.deleteRequest('/compilation/marker/delete', { compilation: compId, marker: markerId })\n }\n\n public async getUserChannels(): Promise {\n const json = await this.getRequest('/channel/user/')\n return this.parseChannels(parseArray(json, 'channels'))\n }\n\n public async getChannelsToPostMarker(): Promise {\n const json = await this.getRequest('/channels/post')\n return this.parseChannels(parseArray(json, 'channels'))\n }\n\n public async cloneCompilation(compilationId: ID, destinationChannelId: ID): Promise {\n const json = await this.postRequest('/compilation/clone', { id: compilationId, destinationChannelId })\n return parseNumber(json, 'id')\n }\n\n public async searchChannels(channelPrefix: string): Promise {\n const json = await this.postRequest('/search/channels', {\n prefix: channelPrefix,\n })\n return this.parseChannels(json)\n }\n\n public async getCompilationByMarker(markerId: ID): Promise {\n const json = await this.getRequest(`/marker/${markerId}/compilation`)\n if (parseString(json, 'status') !== 'ok') {\n return\n }\n return parseCompilation(json.compilation)\n }\n\n public async cloneMarker(markerId: ID, destinationChannelId: ID): Promise {\n const json = await this.postRequest(`/marker/${markerId}/clone`, { destinationChannelId })\n return parseNumber(json, 'id')\n }\n\n public async createChannel(info: UserChannelInfo): Promise {\n const json = await this.postRequest('/channel/add', info)\n return parseNumber(json, 'id')\n }\n\n public async modifyChannel(channelId: ID, info: UserChannelInfo): Promise {\n const body = { id: channelId, info }\n await this.postRequest('/channel/modify', body, true)\n }\n\n public async joinChannel(channelKey: string): Promise {\n const json = await this.postRequest('/channel/join', { channelKey }, true)\n return parseNumber(json, 'id')\n }\n\n public async leaveChannel(channelId: ID): Promise {\n await this.postRequest(`/channel/${channelId}/leave`, true)\n }\n\n public async getOrGenerateChannelKey(channelId?: ID): Promise {\n const json = await this.postRequest(\n '/channel/key',\n {\n channelId,\n },\n true,\n )\n return parseNonEmptyString(json, 'channelKey')\n }\n\n public async getChannelUsers(channelId: ID, offset: number, limit: number): Promise {\n const body = { limit, offset }\n const json = await this.postRequest(`/channel/get-users/${channelId}`, body)\n return this.parseChannelParticipantsJson(json.users)\n }\n\n public async getChannelById(channelId: ID): Promise {\n const json = await this.getRequest(`/channel/get/${channelId}`)\n return parseChannel(json.channel)\n }\n\n async mute(channelId: ID): Promise {\n await this.postRequest(`/channel/${channelId}/notify?notify=false`, true)\n }\n\n async unmute(channelId: ID): Promise {\n await this.postRequest(`/channel/${channelId}/notify?notify=true`, true)\n }\n\n async read(markerId: ID): Promise {\n await this.postRequest(`/marker/${markerId}/read`, true)\n }\n\n async getComplainCauses(): Promise {\n const json = await this.getRequest('/report-causes')\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-return\n return json.map(parseReportCause)\n }\n\n async reportComplain(markerId: ID, causeId: ID): Promise {\n const json = await this.postRequest(`/marker/${markerId}/report`, {\n complainCauseId: causeId,\n })\n return parseNumber(json, 'id')\n }\n\n async reportCommentComplain(commentId: ID, causeId: ID): Promise {\n const json = await this.postRequest(`/comment/${commentId}/report`, {\n complainCauseId: causeId,\n })\n return parseNumber(json, 'id')\n }\n\n async reportEntityComplain(entity: ComplainEntity, causeId: ID): Promise {\n const json = await this.postRequest(`/report-cause/${causeId}/report`, entity)\n return parseNumber(json, 'id')\n }\n\n async getMyComplains(): Promise {\n const json = (await this.getRequest('/complains')) as any[]\n return json.map((element) => parseComplainStatus(element))\n }\n\n async isBlocked(abuserId: ID): Promise {\n const json = await this.getRequest(`/user/block/${abuserId}`)\n return parseBoolean(json, 'doesViewerBlocked')\n }\n\n async block(abuserId: ID): Promise {\n await this.postRequest(`/user/block/${abuserId}`)\n }\n\n async unblock(abuserId: ID): Promise {\n await this.postRequest(`/user/unblock/${abuserId}`)\n }\n\n async hideMarker(markerId: ID): Promise {\n await this.postRequest(`/marker/${markerId}/hide`)\n }\n\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n async log(data: any): Promise {\n await this.postRequest('/log', data)\n }\n\n async computeMarker(shareItems: ShareItem[]): Promise {\n const json = await this.postRequest('/compute-marker', { shareItems }, true)\n return parseUserMarkerContentData(json)\n }\n\n async deleteAccount(): Promise {\n await this.postRequest('/delete-account')\n }\n\n public async ping(): Promise {\n await this.getRequest('/ping')\n }\n\n private async getRequest(url: string): Promise {\n return this.request('GET', url, undefined, true)\n }\n\n private async put(url: string, body?: any, canRetry?: boolean): Promise {\n return this.request('PUT', url, body, canRetry)\n }\n\n private async postRequest(url: string, body?: any, canRetry?: boolean): Promise {\n return this.request('POST', url, body, canRetry)\n }\n\n private async deleteRequest(url: string, body?: any): Promise {\n return this.request('DELETE', url, body)\n }\n\n private async request(method: string, url: string, body?: any, canRetry?: boolean): Promise {\n const fullUrl = `${this.baseUrl}/api${url}`\n const headers: { [key: string]: string } = {\n Accept: 'application/json',\n }\n if (body) {\n headers['Content-Type'] = 'application/json'\n }\n const token: string | undefined = await this.tokenProvider.provideToken()\n if (token) {\n headers.Authorization = `OAuth ${token}`\n }\n for (const [name, value] of Object.entries(serializeToHeaders(this.appInfo))) {\n headers[name] = value\n }\n\n console.log(`curl -X ${method} '${fullUrl}'`)\n const response = await this.fetchPlus(\n fullUrl,\n {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n },\n canRetry ? 3 : 1,\n )\n if (response.status === 404) {\n throw new Error('Такого метода нет на бэкенде')\n }\n const status = Math.floor(response.status / 100)\n if (status === 2) {\n console.log(`Request ${fullUrl} finished successfully`)\n return response.json()\n }\n const errorMessage = await response.text()\n console.error(`Request ${fullUrl} failed with status ${response.status} and text ${errorMessage}`)\n if (response.status === 401) {\n throw new UnauthorizedError()\n }\n const backendError = BackendError.parse(errorMessage)\n if (backendError) {\n throw backendError\n }\n throw new Error(errorMessage)\n }\n\n private async fetchPlus(url: string, options: RequestInit, tries: number): Promise {\n try {\n const response = await fetch(url, options)\n if (response.status / 100 !== 5 || tries === 1) {\n return response\n }\n } catch (err) {\n console.error(err)\n if (tries === 1) {\n throw err\n }\n }\n return this.fetchPlus(url, options, tries - 1)\n }\n}\n","// eslint-disable-next-line no-shadow\nexport enum CommonStringKeys {\n tokenExpired = 'tokenExpired',\n youAreNotAuthorized = 'youAreNotAuthorized',\n youAreBanned = 'youAreBanned',\n youShouldBePinzmeAdmin = 'youShouldBePinzmeAdmin',\n notEnoughRightsToEditMarker = 'notEnoughRightsToEditMarker',\n onlyAuthorCanEditComment = 'onlyAuthorCanEditComment',\n youShouldBeChannelAdmin = 'youShouldBeChannelAdmin',\n youShouldBeAuthorizedToChannelAccess = 'youShouldBeAuthorizedToChannelAccess',\n youShouldBeChannelParticipant = 'youShouldBeChannelParticipant',\n notAbleToCloneInSameChannel = 'notAbleToCloneInSameChannel',\n incorrectLoginOrPassword = 'incorrectLoginOrPassword',\n incorrectLogin = 'incorrectLogin',\n incorrectPassword = 'incorrectPassword',\n youAreRobot = 'youAreRobot',\n moreComplexPassword = 'moreComplexPassword',\n badToken = 'badToken',\n newPasswordShouldBeDifferent = 'newPasswordShouldBeDifferent',\n currentInvalidPassword = 'currentInvalidPassword',\n notEmptyName = 'notEmptyName',\n unavailableLogin = 'unavailableLogin',\n unavailableEmail = 'unavailableEmail',\n unavailableChannelLogin = 'unavailableChannelLogin',\n\n noRequiredField = 'noRequiredField',\n expectedNotEmptyString = 'expectedNotEmptyString',\n shouldBeArrayField = 'shouldBeArrayField',\n shouldBeDictionaryField = 'shouldBeDictionaryField',\n invalidBooleanJsonValue = 'invalidBooleanJsonValue',\n invalidStringJsonValue = 'invalidStringJsonValue',\n invalidNumberJsonValue = 'invalidNumberJsonValue',\n\n unableToSendEmail = 'unableToSendEmail',\n}\n\nexport const CommonStrings = {\n en: {\n [CommonStringKeys.tokenExpired]: 'Your token is rotten. Please login again',\n [CommonStringKeys.youAreNotAuthorized]: \"You're not authorized\",\n [CommonStringKeys.youAreBanned]: 'Your account has been banned. To unblock it, contact support@pinz.me\"',\n [CommonStringKeys.youShouldBePinzmeAdmin]: 'You must be a PinzMe administrator',\n [CommonStringKeys.notEnoughRightsToEditMarker]: 'Insufficient rights to edit marker',\n [CommonStringKeys.onlyAuthorCanEditComment]:\n \"Only the author of the comment or marker's author can edit the comment\",\n [CommonStringKeys.youShouldBeChannelAdmin]: 'You must be a channel admin',\n [CommonStringKeys.youShouldBeAuthorizedToChannelAccess]: 'You must be signed in to open the channel',\n [CommonStringKeys.youShouldBeChannelParticipant]: 'You must be a member of this channel to open it',\n [CommonStringKeys.notAbleToCloneInSameChannel]: 'Cannot be cloned into the same channel',\n [CommonStringKeys.incorrectLoginOrPassword]: 'Incorrect login or password',\n [CommonStringKeys.incorrectLogin]: 'Incorrect login',\n [CommonStringKeys.incorrectPassword]: 'Incorrect password',\n [CommonStringKeys.youAreRobot]: 'You have not passed the Robot Test',\n [CommonStringKeys.moreComplexPassword]: 'Come up with a more complex password',\n [CommonStringKeys.badToken]: 'Unable to verify user',\n [CommonStringKeys.newPasswordShouldBeDifferent]: 'The new password must be different from the old password',\n [CommonStringKeys.currentInvalidPassword]: 'The current password was entered incorrectly',\n [CommonStringKeys.notEmptyName]: 'Username must contain text',\n [CommonStringKeys.unavailableLogin]: 'Invalid login',\n [CommonStringKeys.unavailableEmail]: 'Invalid address',\n [CommonStringKeys.unavailableChannelLogin]: 'Invalid channel login',\n [CommonStringKeys.noRequiredField]: 'Required field \"{0}\" is missing',\n [CommonStringKeys.expectedNotEmptyString]: 'The value of the field \"{0}\" cannot be an empty string',\n [CommonStringKeys.shouldBeArrayField]: 'The value of the field \"{0}\" must be an array',\n [CommonStringKeys.shouldBeDictionaryField]: 'The value of the field \"{0}\" must be a dictionary',\n [CommonStringKeys.invalidBooleanJsonValue]: 'Expected true / false for key \"{0}\", but found {1}',\n [CommonStringKeys.invalidStringJsonValue]: 'Expected string by key \"{0}\", but found {1}',\n [CommonStringKeys.invalidNumberJsonValue]: 'Expected number by key \"{0}\", but found {1}',\n [CommonStringKeys.unableToSendEmail]: 'Unable to send email',\n },\n ru: {\n [CommonStringKeys.tokenExpired]: 'Ваш токен протух. Залогиньтесь заново',\n [CommonStringKeys.youAreNotAuthorized]: 'Вы не авторизованы',\n [CommonStringKeys.youAreBanned]:\n 'Ваш аккаунт забанен. Для его разблокировки обратитесь в поддержку support@pinz.me',\n [CommonStringKeys.youShouldBePinzmeAdmin]: 'Вы должны быть администратором PinzMe',\n [CommonStringKeys.notEnoughRightsToEditMarker]: 'Недостаточно прав для редактирования точки',\n [CommonStringKeys.onlyAuthorCanEditComment]: 'Только автор комментария или точки может редактировать комментарий',\n [CommonStringKeys.youShouldBeChannelAdmin]: 'Вы должны быть администратором канала',\n [CommonStringKeys.youShouldBeAuthorizedToChannelAccess]: 'Вы должны быть авторизованы для просмотра канала',\n [CommonStringKeys.youShouldBeChannelParticipant]: 'Вы должны быть участником этого канала для его просмотра',\n [CommonStringKeys.notAbleToCloneInSameChannel]: 'Нельзя клонировать в тот же канал',\n [CommonStringKeys.incorrectLoginOrPassword]: 'Неверный логин или пароль',\n [CommonStringKeys.incorrectLogin]: 'Недопустимый логин',\n [CommonStringKeys.incorrectPassword]: 'Недопустимый пароль',\n [CommonStringKeys.youAreRobot]: 'Вы не прошли проверку на робота',\n [CommonStringKeys.moreComplexPassword]: 'Придумайте более сложный пароль',\n [CommonStringKeys.badToken]: 'Невозможно верифицировать пользователя',\n [CommonStringKeys.newPasswordShouldBeDifferent]: 'Новый пароль должен отличаться от старого пароля',\n [CommonStringKeys.currentInvalidPassword]: 'Текущий пароль введен неверно',\n [CommonStringKeys.notEmptyName]: 'Имя пользователя должно содержать текст',\n [CommonStringKeys.unavailableLogin]: 'Недопустимый логин',\n [CommonStringKeys.unavailableEmail]: 'Недопустимый адрес',\n [CommonStringKeys.unavailableChannelLogin]: 'Недопустимый логин канала',\n [CommonStringKeys.noRequiredField]: 'Нет необходимого поля \"{0}\"',\n [CommonStringKeys.expectedNotEmptyString]: 'Значение поля \"{0}\" не может быть пустой строкой',\n [CommonStringKeys.shouldBeArrayField]: 'Значение поля \"{0}\" должно быть массивом',\n [CommonStringKeys.shouldBeDictionaryField]: 'Значение поля \"{0}\" должно быть словарем',\n [CommonStringKeys.invalidBooleanJsonValue]: 'Ожидается true/false по ключу \"{0}\", но найден {1}',\n [CommonStringKeys.invalidStringJsonValue]: 'Ожидается строка по ключу \"{0}\", но найден {1}',\n [CommonStringKeys.invalidNumberJsonValue]: 'Ожидается число по ключу \"{0}\", но найден {1}',\n [CommonStringKeys.unableToSendEmail]: 'Не удалось отправить письмо',\n },\n}\n","/* eslint-disable */\nimport { GeoPoint, Point } from '../model'\nimport { InteractiveMapModel, PointMapping } from \"../map-model\";\nimport { parseNumber, requireField } from '../parsing'\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport { multiply, inv, jStat } from 'jstat'\n\nexport interface LinearModel {\n readonly a: number\n readonly b: number\n readonly c: number\n}\n\nexport interface LinearMapModel {\n readonly xModel: LinearModel\n readonly yModel: LinearModel\n}\n\nexport class InteractiveLinearMapModel implements InteractiveMapModel {\n constructor(private readonly lMM: LinearMapModel) {}\n\n public apply(geoPoint: GeoPoint): Point {\n return {\n x: this.applyModel(geoPoint, this.lMM.xModel),\n y: this.applyModel(geoPoint, this.lMM.yModel),\n }\n }\n\n private applyModel(geoPoint: GeoPoint, model: LinearModel): number {\n return geoPoint.latitude * model.a + geoPoint.longitude * model.b + model.c\n }\n}\n\nfunction parseLinearModel(json: any): LinearModel {\n return {\n a: parseNumber(json, 'a'),\n b: parseNumber(json, 'b'),\n c: parseNumber(json, 'c'),\n }\n}\n\nexport function parseLinearMapModel(json: any): LinearMapModel {\n return {\n xModel: parseLinearModel(requireField(json, 'xModel')),\n yModel: parseLinearModel(requireField(json, 'yModel')),\n }\n}\n\n\n/**\n * Train a linear model based on all points of a map.\n *\n * Uses the following formula:\n * x = (A^T * A)^-1 * A^T * b\n * where A = [[lat1, lon1, 1], [lat2, lon2, 1], ...]\n * b = [x1, x2, ...]\n * x = [a, b, c] -- the resulting linear model\n *\n * Should not be applied to two points\n * @param allPoints - точки для обучения модели\n */\nexport function trainModel(allPoints: PointMapping[]): LinearMapModel {\n const stub: number[][] = []\n const bX: number[][] = []\n const bY: number[][] = []\n allPoints.forEach((point) => {\n stub.push([point.geoPoint.latitude, point.geoPoint.longitude, 1])\n bX.push([point.imagePoint.x])\n bY.push([point.imagePoint.y])\n })\n const A = jStat(stub)\n const AT = A.transpose()\n const tmp = jStat(multiply(inv(multiply(AT, A)), AT))\n const ansX = multiply(tmp, bX)\n const ansY = multiply(tmp, bY)\n\n return {\n xModel: { a: ansX[0][0], b: ansX[1][0], c: ansX[2][0] },\n yModel: { a: ansY[0][0], b: ansY[1][0], c: ansY[2][0] },\n }\n}\n","import { kebabize } from './common-utils'\nimport { parseBoolean, parseString } from './parsing'\n\nexport interface AppInfo {\n applicationName: string\n brand: string\n buildNumber: string\n bundleId: string\n deviceId: string\n deviceType: string\n systemVersion: string\n systemName: string\n uniqueId: string\n version: string\n hasNotch: boolean\n isLandscape: boolean\n isTablet: boolean\n}\n\nexport function serializeToHeaders(appInfo: AppInfo): { [name: string]: string } {\n const result: { [name: string]: string } = {}\n for (const [name, value] of Object.entries(appInfo)) {\n result[toHeaderName(name)] = value\n }\n return result\n}\n\nexport function deserializeFromHeaders(headers: { [key: string]: string | string[] | undefined }): AppInfo {\n return {\n applicationName: parseString(headers, toHeaderName('applicationName')),\n brand: parseString(headers, toHeaderName('brand')),\n buildNumber: parseString(headers, toHeaderName('buildNumber')),\n bundleId: parseString(headers, toHeaderName('bundleId')),\n deviceId: parseString(headers, toHeaderName('deviceId')),\n deviceType: parseString(headers, toHeaderName('deviceType')),\n systemVersion: parseString(headers, toHeaderName('systemVersion')),\n systemName: parseString(headers, toHeaderName('systemName')),\n uniqueId: parseString(headers, toHeaderName('uniqueId')),\n version: parseString(headers, toHeaderName('version')),\n hasNotch: parseBoolean(headers, toHeaderName('hasNotch')),\n isLandscape: parseBoolean(headers, toHeaderName('isLandscape')),\n isTablet: parseBoolean(headers, toHeaderName('isTablet')),\n }\n}\n\nfunction toHeaderName(key: string): string {\n return `x-${kebabize(key)}`\n}\n","export function sleep(ms: number): Promise {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nexport function average(arr: number[]): number {\n return arr.reduce((p, c) => p + c, 0) / arr.length\n}\n\n// https://stackoverflow.com/a/63116134\nexport function kebabize(str: string): string {\n return str\n .split('')\n .map((letter, idx) => {\n return letter.toUpperCase() === letter ? `${idx !== 0 ? '-' : ''}${letter.toLowerCase()}` : letter\n })\n .join('')\n}\n\nexport function generateRandomString(length = 24): string {\n // https://stackoverflow.com/a/1349426\n let result = ''\n const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'\n const charactersLength = characters.length\n for (let i = 0; i < length; i++) {\n result += characters.charAt(Math.floor(Math.random() * charactersLength))\n }\n return result\n}\n\nexport function tomorrow(): Date {\n return new Date(Date.now() + 24 * 3600 * 1000)\n}\n","import { ID, Point } from '@pinzme/common/src/model'\nimport { ReactElement, useEffect, useRef, useState } from 'react'\nimport { pinzmeWeb } from '@pinzme/components/src/registry'\nimport {\n Image,\n ImageBackground,\n Dimensions,\n View,\n Modal,\n StyleSheet,\n Pressable,\n Text,\n TouchableOpacity,\n Animated,\n Easing,\n} from 'react-native'\nimport { InteractiveMapModelSnapshot } from '@pinzme/common/src/map-model'\nimport { DelaunayMapModel } from '@pinzme/common/src/interactive-map/delaunay-model'\nimport { watchPosition } from '@pinzme/components/src/utils'\nimport {\n computeImageScreenHeight,\n computePointPosition,\n pointImageUrl,\n} from '@pinzme/components/src/common-components-utils'\nimport { centeredActivityIndicator } from './web-utils'\n\nexport function WebInteractiveMapComponent({ snapshotId }: { snapshotId: ID }): ReactElement {\n const [snapshot, setSnapshot] = useState()\n\n const [currentPosition, setCurrentPosition] = useState()\n const animatedPosition = useRef(new Animated.ValueXY()).current\n\n useEffect(() => {\n const listenerId = animatedPosition.addListener(setCurrentPosition)\n return () => {\n animatedPosition.removeListener(listenerId)\n }\n }, [])\n\n const [showPositionRequestHint, setShowPositionRequestHint] = useState(false)\n const [locationEnabled, setLocationEnabled] = useState()\n const [userAgreed, setUserAgreed] = useState(false)\n\n useEffect(() => {\n void pinzmeWeb.getSnapshotById(snapshotId).then(setSnapshot)\n }, [snapshotId])\n\n useEffect(() => {\n if (!snapshot || !(locationEnabled || userAgreed)) {\n return\n }\n const lm = new DelaunayMapModel(snapshot.model)\n return watchPosition(\n (geoPosition) => {\n const imagePosition = lm.apply(geoPosition)\n Animated.timing(animatedPosition, {\n toValue: imagePosition,\n duration: 1000,\n useNativeDriver: false,\n easing: Easing.linear,\n }).start()\n },\n (error) => {\n console.error(error)\n },\n )\n }, [snapshot, locationEnabled, userAgreed])\n\n useEffect(() => {\n if (!navigator.permissions) {\n // в safari не проверить пермишен на геопозицию без ее запроса\n // поэтому мы всегда показываем popup\n // TODO: сохранять показ popup где-то в куках?\n setLocationEnabled(false)\n return\n }\n void navigator.permissions.query({ name: 'geolocation' }).then((result) => {\n setLocationEnabled(result.state === 'granted')\n })\n }, [])\n\n useEffect(() => {\n if (locationEnabled !== false) {\n return\n }\n setShowPositionRequestHint(true)\n }, [locationEnabled])\n\n if (!snapshot) {\n return centeredActivityIndicator()\n }\n\n const image = snapshot.image\n const imageScreenWidth = Dimensions.get('window').width\n const imageScreenHeight = computeImageScreenHeight(imageScreenWidth, image.size)\n\n return (\n \n \n {\n setShowPositionRequestHint(false)\n setUserAgreed(true)\n }}\n style={styles.centeredView}\n >\n \n \n Если вы разрешите использовать геопозцию, то мы сможем в режиме реального времени показывать таким\n значком, где вы сейчас на этой карте.\n \n \n {\n setShowPositionRequestHint(false)\n setUserAgreed(true)\n }}\n >\n Хорошо\n \n \n \n \n \n {currentPosition ? (\n \n ) : undefined}\n \n )\n}\n\nconst styles = StyleSheet.create({\n centeredView: {\n flex: 1,\n justifyContent: 'center',\n alignItems: 'center',\n marginTop: 22,\n },\n modalView: {\n margin: 20,\n backgroundColor: 'white',\n borderRadius: 20,\n padding: 35,\n alignItems: 'center',\n shadowColor: '#000',\n shadowOffset: {\n width: 0,\n height: 2,\n },\n shadowOpacity: 0.25,\n shadowRadius: 4,\n elevation: 5,\n },\n})\n","import { GeoPoint } from '@pinzme/common/src/model'\nimport Geolocation, { GeolocationError, GeolocationResponse } from '@react-native-community/geolocation'\n\nexport function getCurrentPosition(): Promise {\n return new Promise((resolve, reject) => {\n Geolocation.getCurrentPosition(\n (position) => resolve(position.coords),\n (error: GeolocationError) => {\n reject(error)\n },\n {\n maximumAge: 1000,\n },\n )\n })\n}\n\nexport function watchPosition(\n success: (position: GeoPoint) => void,\n onGeolocationError: (error: GeolocationError) => void,\n): () => void {\n const watchId = Geolocation.watchPosition(\n (position: GeolocationResponse) => {\n success({\n latitude: position.coords.latitude,\n longitude: position.coords.longitude,\n })\n },\n (error) => {\n onGeolocationError(error)\n },\n {\n distanceFilter: 30,\n },\n )\n return () => {\n Geolocation.clearWatch(watchId)\n }\n}\n","import { ReactElement, useEffect, useState } from 'react'\nimport { Marker, MapContainer, TileLayer, Tooltip, useMap } from 'react-leaflet'\nimport 'leaflet/dist/leaflet.css'\nimport 'leaflet/dist/images/marker-shadow.png'\nimport 'leaflet/dist/images/marker-icon.png'\n\nimport L from 'leaflet'\nimport { Dimensions, StyleSheet, View, Text } from 'react-native'\nimport { ChannelView, ID, MarkerMapView } from '@pinzme/common/src/model'\nimport { pinzmeWeb } from '@pinzme/components/src/registry'\nimport { MarkerPopupComponent } from './marker-popup-component'\n\ninterface MapMatchParams {\n channelId?: string\n markerId?: string\n}\n\ninterface MapMatch {\n params: MapMatchParams\n}\n\nconst popupRightPadding = 30\nconst popupWidth = Math.min(Dimensions.get('window').width - 2 * popupRightPadding, 500)\n\nconst originalIconSize = new L.Point(62, 100)\nconst iconScale = 2\nconst iconSize = new L.Point(originalIconSize.x / iconScale, originalIconSize.y / iconScale)\n\nfunction LeafletMarker({\n marker,\n onClick,\n panTo,\n}: {\n marker: MarkerMapView\n onClick: () => void\n panTo?: boolean\n}): ReactElement {\n const iconPerson = new L.Icon({\n iconUrl: marker.mapImageUrl,\n iconAnchor: new L.Point(iconSize.x / 2, iconSize.y),\n iconSize,\n })\n\n const map = useMap()\n\n function panToMarker(): void {\n const p = map.project([marker.geoPoint.latitude, marker.geoPoint.longitude])\n p.x += popupWidth / 2\n map.panTo(map.unproject(p))\n }\n\n if (panTo) {\n panToMarker()\n }\n\n return (\n {\n panToMarker()\n onClick()\n },\n }}\n >\n {marker.title}\n \n )\n}\n\nexport function MapScreenComponent({ match }: { match: MapMatch }): ReactElement {\n const channelId = match.params.channelId ? parseInt(match.params.channelId, 10) : undefined\n const markerId = match.params.markerId ? parseInt(match.params.markerId, 10) : undefined\n const [showMarkerId, setShowMarkerId] = useState(markerId)\n\n const [channel, setChannel] = useState()\n const [markers, setMarkers] = useState()\n\n async function loadMarkers(): Promise {\n let realChannelId: number\n if (!channelId) {\n if (!markerId) {\n return\n }\n const marker = await pinzmeWeb.getMarkerById(markerId)\n realChannelId = marker.channelId\n } else {\n realChannelId = channelId\n }\n void pinzmeWeb.getChannelById(realChannelId).then(setChannel)\n void pinzmeWeb.getChannelMarkers(realChannelId).then(setMarkers)\n }\n\n useEffect(() => {\n void loadMarkers()\n }, [channelId, setChannel, setMarkers])\n\n return (\n \n \n \n {markers?.map((m: MarkerMapView) => {\n const id = m.id\n if (!id) {\n return <>\n }\n return (\n {\n setShowMarkerId(id)\n window.history.replaceState(null, m.title, `#/marker/${id}`)\n }}\n panTo={markerId === id}\n />\n )\n })}\n \n {showMarkerId && (\n \n setShowMarkerId(undefined)} />\n \n )}\n \n {channel?.name}\n \n \n )\n}\n\nconst styles = StyleSheet.create({\n rightView: {\n flex: 1,\n // position: 'absolute',\n // right: 0,\n alignSelf: 'flex-end',\n flexDirection: 'row',\n // top: '50%',\n marginTop: 100,\n marginBottom: 100,\n marginRight: 30,\n backgroundColor: 'white',\n borderRadius: 30,\n paddingHorizontal: popupRightPadding,\n paddingVertical: 10,\n shadowColor: '#000',\n shadowOffset: {\n width: 0,\n height: 2,\n },\n shadowOpacity: 0.25,\n shadowRadius: 3.84,\n elevation: 2000,\n zIndex: 2000,\n width: popupWidth,\n },\n})\n","import { ID, Marker } from '@pinzme/common/src/model'\nimport { ReactElement, useEffect, useState } from 'react'\nimport { ActivityIndicator, TouchableOpacity, View } from 'react-native'\nimport { MarkerViewComponent } from './marker-view-component'\nimport { pinzmeWeb } from '@pinzme/components/src/registry'\nimport { MdClose } from 'react-icons/md'\n\nexport function MarkerPopupComponent({ markerId, onClose }: { markerId: ID; onClose: () => void }): ReactElement {\n const [marker, setMarker] = useState()\n\n useEffect(() => {\n void pinzmeWeb.getMarkerById(markerId).then(setMarker)\n }, [markerId])\n\n return (\n \n {!marker ? (\n \n ) : (\n \n )}\n \n \n \n \n )\n}\n","import { ReactElement, useState } from 'react'\nimport { View, StyleSheet, Text, ScrollView, Image } from 'react-native'\nimport { Marker } from '@pinzme/common/src/model'\nimport { pinzmeBaseColor } from '@pinzme/components/src/common-components-utils'\n\nexport function MarkerViewComponent({ marker }: { marker: Marker }): ReactElement {\n const [imageHeight, setImageHeight] = useState()\n\n return (\n \n \n {marker.title}\n {marker.contentHTML.trim().length ? (\n \n
\n \n ) : (\n \n )}\n {marker.imageUrl && (\n {\n setImageHeight(event.nativeEvent.layout.height)\n }}\n >\n \n \n )}\n \n \n {marker.author ? (\n {'@' + marker.author.login}\n ) : null}\n {marker.createdAt.toLocaleString('ru')}\n \n \n \n \n {marker.likesTotal ? {marker.likesTotal} : <>}\n \n \n \n )\n}\n\nconst styles = StyleSheet.create({\n titleView: {\n color: 'black',\n fontSize: 16,\n textAlign: 'center',\n fontWeight: 'bold',\n justifyContent: 'center',\n },\n container: {\n flexDirection: 'row',\n flexWrap: 'wrap',\n justifyContent: 'space-between',\n },\n imageView: {\n height: '100%',\n borderRadius: 10,\n },\n iconGroup: {\n flexDirection: 'row',\n justifyContent: 'space-between',\n },\n likeIcon: {\n flexDirection: 'row-reverse',\n alignItems: 'center',\n },\n createdAt: {\n alignSelf: 'center',\n },\n})\n","import { Point, Size } from '@pinzme/common/src/model'\n\nexport const pinzmeBaseColor = '#267578'\n\nexport const appStoreMarketImageUrl =\n 'https://storage.yandexcloud.net/www.pinz.me/img/%D0%97%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%B8%D1%82%D0%B5_App_Store.png'\nexport const googlePlayMarketImageUrl = 'https://storage.yandexcloud.net/www.pinz.me/img/ru_badge_web_generic.png'\nexport const appStorePinzMeUrl = 'https://apps.apple.com/us/app/pinz-me/id1544173088'\nexport const googlePlayPinzMeUrl = 'https://play.google.com/store/apps/details?id=me.pinz'\n\nexport const pointImageUrl = 'https://storage.yandexcloud.net/www.pinz.me/img/point.png'\n// сюда надо записать размеры pointImageUrl\nconst originalPointWidth = 126\nconst originalPointHeight = 193\n// сюда надо записать, во скоклько раз надо уменьшить в размерах на карте\nconst decreaseScale = 4\n\nexport function computePointPosition(\n point: Point,\n zoomScale: number,\n imageSize: Size,\n imageScreenWidth: number,\n imageScreenHeight: number,\n): any {\n const scale = zoomScale * decreaseScale\n const scaledPointWidth = originalPointWidth / scale\n const scaledPointHeight = originalPointHeight / scale\n return {\n position: 'absolute',\n left: (imageScreenWidth * point.x) / imageSize.width - scaledPointWidth / 2,\n top: (imageScreenHeight * point.y) / imageSize.height - scaledPointHeight / 2,\n width: scaledPointWidth,\n height: scaledPointHeight,\n zIndex: 1,\n }\n}\n\nexport function computeImageScreenHeight(imageScreenWidth: number, imageSize: Size): number {\n return (imageScreenWidth * imageSize.height) / imageSize.width\n}\n","import { ReactElement } from 'react'\nimport { View, Text, Image, Dimensions, StyleSheet, TouchableOpacity, Linking } from 'react-native'\nimport {\n appStoreMarketImageUrl,\n appStorePinzMeUrl,\n googlePlayMarketImageUrl,\n googlePlayPinzMeUrl,\n} from '@pinzme/components/src/common-components-utils'\n\nexport function MordaComponent(): ReactElement {\n return (\n \n Pinz.Me\n \n \n \n С помощью нашего приложения вы сможете делиться своими интересными точками с друзьями и близкими на карте\n \n \n Исследуйте интересные места и делитесь ими с друзьями и близкими! Это очень просто!\n \n \n Наше приложение - это карта, которую заполняете Вы, ваши друзья или близкие, чтобы поделиться интересными\n местами или ситуациями. Приложение включает в себя поиск и нахождение интересных мест в городе, просмотр\n каналов, добавление своих собственных меток на карту и возможность узнать о событиях вокруг.\n \n \n {\n void Linking.openURL(appStorePinzMeUrl)\n }}\n style={styles.imageLink}\n >\n \n \n {\n void Linking.openURL(googlePlayPinzMeUrl)\n }}\n style={styles.imageLink}\n >\n \n \n {/* Pinz.Me*/}\n \n )\n}\n\nconst styles = StyleSheet.create({\n title: {\n alignSelf: 'center',\n fontWeight: 'bold',\n fontSize: 40,\n fontFamily: 'monospace',\n },\n image: {\n alignSelf: 'center',\n width: 0.5 * Dimensions.get('window').width,\n height: 0.2 * Dimensions.get('window').height,\n padding: 1,\n },\n description: {\n alignSelf: 'center',\n backgroundColor: '#03989e',\n color: 'white',\n padding: 20,\n marginLeft: 0.02 * Dimensions.get('window').width,\n marginRight: 0.02 * Dimensions.get('window').width,\n fontFamily: 'monospace',\n },\n bodyText: {\n alignSelf: 'center',\n marginLeft: 0.05 * Dimensions.get('window').width,\n marginRight: 0.05 * Dimensions.get('window').width,\n marginTop: 0.02 * Dimensions.get('window').height,\n fontFamily: 'monospace',\n padding: 10,\n },\n imageMarket: {\n width: 0.5 * Dimensions.get('window').width,\n height: 0.1 * Dimensions.get('window').height,\n padding: 1,\n },\n imageLink: {\n alignSelf: 'center',\n margin: 1,\n },\n link: {\n fontFamily: 'monospace',\n alignSelf: 'center',\n fontStyle: 'normal',\n fontSize: 12,\n },\n border: {\n borderBottomWidth: 2,\n borderStyle: 'dotted',\n borderBottomColor: '#03989e',\n padding: 1,\n marginLeft: 0.03 * Dimensions.get('window').width,\n marginRight: 0.03 * Dimensions.get('window').width,\n marginBottom: 0.03 * Dimensions.get('window').height,\n },\n})\n","// eslint-disable-next-line\nimport { ReportHandler } from 'web-vitals'\n\nconst reportWebVitals = (onPerfEntry?: ReportHandler): void => {\n if (onPerfEntry && onPerfEntry instanceof Function) {\n void import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n getCLS(onPerfEntry)\n getFID(onPerfEntry)\n getFCP(onPerfEntry)\n getLCP(onPerfEntry)\n getTTFB(onPerfEntry)\n })\n }\n}\n\nexport default reportWebVitals\n","import { PinzmeClient } from '@pinzme/common/src/pinzme-client'\nimport { TokenProvider } from '@pinzme/common/src/token-provider'\nimport { AppInfo } from '@pinzme/common/src/app-info'\n\nexport class EmptyTokenProvider implements TokenProvider {\n provideToken(): Promise {\n return Promise.resolve(undefined)\n }\n\n removeToken(): Promise {\n return Promise.resolve(undefined)\n }\n\n setToken(_: string): Promise {\n return Promise.resolve(undefined)\n }\n}\n\nconst emptyAppInfo: AppInfo = {\n applicationName: 'pizza',\n brand: '',\n buildNumber: '',\n bundleId: '',\n deviceId: '',\n deviceType: '',\n hasNotch: false,\n isLandscape: false,\n isTablet: false,\n systemName: '',\n systemVersion: '',\n uniqueId: '',\n version: '',\n}\n\nexport const pinzmeWeb = new PinzmeClient('https://api.pinz.me', new EmptyTokenProvider(), emptyAppInfo)\n"],"sourceRoot":""}