diff --git a/.gitignore b/.gitignore index 3c3629e..a152627 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ node_modules +frontend/node_modules +backend/node_modules \ No newline at end of file diff --git a/backend/.env b/backend/.env index ab6d3c9..0c0a68a 100644 --- a/backend/.env +++ b/backend/.env @@ -4,4 +4,7 @@ DB_PASSWORD=hitomisan DB_NAME=trainingsdiary DB_DIALECT=mysql JWT_SECRET=x9H7ggzio13P3DF -ENCRYPTION_KEY=x9H7ggzio13P3DF \ No newline at end of file +ENCRYPTION_KEY=daa9cf7ef5b8c5021b455721fedaf10bc1739897c6d9c6d40e4fa3013c4ac83b +EMAIL_USER=tsschulz2001@gmail.com +EMAIL_PASS=wiuo rhxq vmxe eyaj +BASE_URL=http://localhost:3000 \ No newline at end of file diff --git a/backend/config.js b/backend/config.js index 4809704..3910300 100644 --- a/backend/config.js +++ b/backend/config.js @@ -3,9 +3,9 @@ import dotenv from 'dotenv'; dotenv.config(); export const development = { - username: process.env.DB_USER, - password: process.env.DB_PASSWORD, - database: process.env.DB_NAME, + username: process.env.DB_USER || 'root', + password: process.env.DB_PASSWORD || 'hitomisan', + database: process.env.DB_NAME || 'trainingdiary', host: process.env.DB_HOST, dialect: process.env.DB_DIALECT, define: { @@ -14,3 +14,4 @@ export const development = { underscoredAll: true, }, }; + \ No newline at end of file diff --git a/backend/controllers/clubsController.js b/backend/controllers/clubsController.js index 6bd30fd..b33e62c 100644 --- a/backend/controllers/clubsController.js +++ b/backend/controllers/clubsController.js @@ -1,52 +1,77 @@ import Club from '../models/Club.js'; import UserClub from '../models/UserClub.js'; import User from '../models/User.js'; +import Member from '../models/Member.js'; import { Op, fn, where, col } from 'sequelize'; import { getUserByToken } from '../utils/userUtils.js'; const getClubs = async (req, res) => { - const clubs = await Club.findAll(); - res.status(200).json(clubs); + try { + console.log('[getClubs] - get clubs'); + const clubs = await Club.findAll(); + console.log('[getClubs] - prepare response'); + res.status(200).json(clubs); + console.log('[getClubs] - done'); + } catch (error) { + console.log('[getClubs] - error'); + console.log(error); + res.status(500).json({ error: "internalerror" }); + } }; const addClub = async (req, res) => { + console.log('[addClub] - Read out parameters'); const { authcode: token } = req.headers; const { name: clubName } = req.body; + console.log('[addClub] - find club by name'); const club = await Club.findOne({ where: where(fn('LOWER', col('name')), 'LIKE', `%${clubName.toLowerCase()}%`) }); + console.log('[addClub] - get user'); const user = await getUserByToken(token); + console.log('[addClub] - check if club already exists'); if (club) { res.status(409).json({ error: "alreadyexists" }); return; } - const newClub = Club.create({ name: clubName }); + console.log('[addClub] - create club'); + const newClub = await Club.create({ name: clubName }); + console.log('[addClub] - add user to new club'); UserClub.create({ userId: user.id, clubId: newClub.id, approved: true }); + console.log('[addClub] - prepare response'); res.status(200).json(newClub); + console.log('[addClub] - done'); } const getClub = async (req, res) => { - const { authcode: token } = req.headers; - const { clubid: clubId } = req.params; - console.log('load club', token) - const user = await getUserByToken(token); - console.log(user); - const access = await UserClub.findAll({ - where: { - userId: user.id, - clubId: clubId, - } - }); - if (access.length === 0 || !access[0].approved) { - res.status(403).json({ error: "noaccess", status: access.length === 0 ? "notrequested" : "requested" }); - return; - } + console.log('[getClub] - start'); try { + const { authcode: token } = req.headers; + const { clubid: clubId } = req.params; + console.log('[getClub] - get user'); + const user = await getUserByToken(token); + console.log('[getClub] - get users club'); + const access = await UserClub.findAll({ + where: { + userId: user.id, + clubId: clubId, + } + }); + console.log('[getClub] - check access'); + if (access.length === 0 || !access[0].approved) { + res.status(403).json({ error: "noaccess", status: access.length === 0 ? "notrequested" : "requested" }); + return; + } + console.log('[getClub] - get club'); const club = await Club.findByPk(clubId, { include: [ { model: Member, - as: 'Members', + as: 'members', + order: [ + ['lastName', 'ASC'], // Sortiere nach Nachname aufsteigend + ['firstName', 'ASC'] // Sortiere nach Vorname aufsteigend + ], }, { model: User, @@ -57,13 +82,15 @@ const getClub = async (req, res) => { } ] }); - + console.log('[getClub] - check club exists'); if (!club) { return res.status(404).json({ message: 'Club not found' }); } + console.log('[getClub] - set response'); res.status(200).json(club); + console.log('[getClub] - done'); } catch (error) { - console.error('err', error); + console.log(error); res.status(500).json({ message: 'Server error' }); } } @@ -106,7 +133,7 @@ const approveClubAccess = async (req, res) => { res.status(200).json({ status: 'ok' }); } -const requestClubAccess = async(req, res) => { +const requestClubAccess = async (req, res) => { const { authcode: token } = req.headers; const { clubid: clubId } = req.params; const user = await getUserByToken(token); @@ -114,16 +141,18 @@ const requestClubAccess = async(req, res) => { const access = await UserClub.findAll({ where: { userId: user.id, - clubId: clubId, + clubId: clubId, } }); if (access.length > 0) { - res.status(409).json({ err: "alreadyrequested"}); + res.status(409).json({ err: "alreadyrequested" }); return; } - const club = Club.findOne({ where: { - id: clubId - }}); + const club = Club.findOne({ + where: { + id: clubId + } + }); if (!club) { res.status(404).json({ err: "clubnotfound" }); return; diff --git a/backend/controllers/diaryController.js b/backend/controllers/diaryController.js new file mode 100644 index 0000000..d65c084 --- /dev/null +++ b/backend/controllers/diaryController.js @@ -0,0 +1,54 @@ +import DiaryService from '../services/diaryService.js'; +import HttpError from '../exceptions/HttpError.js'; + +const diaryService = new DiaryService(); + +const getDatesForClub = async (req, res) => { + try { + const { clubId } = req.params; + const { authcode: userToken } = req.headers; + const dates = await diaryService.getDatesForClub(userToken, clubId); + res.status(200).json(dates); + } catch (error) { + console.error('[getDatesForClub] - Error:', error); + res.status(error.statusCode || 500).json({ error: error.message }); + } +}; + +const createDateForClub = async (req, res) => { + try { + const { clubId } = req.params; + const { authcode: userToken } = req.headers; + const { date, trainingStart, trainingEnd } = req.body; + if (!date) { + throw new HttpError('The date field is required', 400); + } + if (isNaN(new Date(date).getTime())) { + throw new HttpError('Invalid date format', 400); + } + const newDate = await diaryService.createDateForClub(userToken, clubId, date, trainingStart, trainingEnd); + res.status(201).json(newDate); + } catch (error) { + console.error('[createDateForClub] - Error:', error); + res.status(error.statusCode || 500).json({ error: error.message }); + } +}; + + +const updateTrainingTimes = async (req, res) => { + try { + const { clubId } = req.params; + const { authcode: userToken } = req.headers; + const { date, trainingStart, trainingEnd } = req.body; + if (!date || !trainingStart || !trainingEnd) { + throw new HttpError('All fields (date, trainingStart, trainingEnd) are required', 400); + } + const updatedDate = await diaryService.updateTrainingTimes(userToken, clubId, date, trainingStart, trainingEnd); + res.status(200).json(updatedDate); + } catch (error) { + console.error('[updateTrainingTimes] - Error:', error); + res.status(error.statusCode || 500).json({ error: error.message }); + } +}; + +export { getDatesForClub, createDateForClub, updateTrainingTimes }; \ No newline at end of file diff --git a/backend/controllers/memberController.js b/backend/controllers/memberController.js index f4e7bbb..40a0833 100644 --- a/backend/controllers/memberController.js +++ b/backend/controllers/memberController.js @@ -1,19 +1,40 @@ import MemberService from "../services/memberService.js"; const getClubMembers = async(req, res) => { - const { clubid: clubId } = req.body; - res.status(200).json(MemberService.getClubMembers(clubId)); + try { + const { authcode: userToken } = req.headers; + const { id: clubId } = req.params; + console.log('[getClubMembers]', userToken, clubId); + res.status(200).json(await MemberService.getClubMembers(userToken, clubId)); + } catch(error) { + console.log('[getClubMembers] - Error: ', error); + res.status(500).json({ error: 'systemerror' }); + } } const getWaitingApprovals = async(req, res) => { try { - const { clubid: clubId } = req.params; - const { authcode: userToken} = req.headers; - const waitingApprovals = MemberService.getApprovalRequests(userToken, clubId); + console.log('[getWaitingApprovals] - Start'); + const { id: clubId } = req.params; + console.log('[getWaitingApprovals] - get token'); + const { authcode: userToken } = req.headers; + console.log('[getWaitingApprovals] - load for waiting approvals'); + const waitingApprovals = await MemberService.getApprovalRequests(userToken, clubId); + console.log('[getWaitingApprovals] - set response'); res.status(200).json(waitingApprovals); + console.log('[getWaitingApprovals] - done'); } catch(error) { + console.log('[getWaitingApprovals] - Error: ', error); res.status(403).json({ error: error }); } +} + +const setClubMembers = async(req, res) => { + const { id: memberId, firstname: firstName, lastname: lastName, street, city, birthdate, phone, email} = req.body; + const { id: clubId } = req.params; + const { authcode: userToken } = req.headers; + const addResult = await MemberService.setClubMember(userToken, clubId, memberId, firstName, lastName, street, city, birthdate, phone, email); + res.status(addResult.status || 500).json(addResult.response); } -export { getClubMembers, getWaitingApprovals }; \ No newline at end of file +export { getClubMembers, getWaitingApprovals, setClubMembers }; \ No newline at end of file diff --git a/backend/database.js b/backend/database.js index 7a9fd4b..babeab2 100644 --- a/backend/database.js +++ b/backend/database.js @@ -2,7 +2,7 @@ import { Sequelize } from 'sequelize'; import { development } from './config.js'; const sequelize = new Sequelize( - development.database, + development.database, development.username, development.password, { diff --git a/backend/exceptions/HttpError.js b/backend/exceptions/HttpError.js new file mode 100644 index 0000000..1592d88 --- /dev/null +++ b/backend/exceptions/HttpError.js @@ -0,0 +1,10 @@ +class HttpError extends Error { + constructor(message, statusCode) { + super(message); + this.name = this.constructor.name; + this.statusCode = statusCode; + Error.captureStackTrace(this, this.constructor); + } +} + +export default HttpError; diff --git a/backend/middleware/authMiddleware.js b/backend/middleware/authMiddleware.js index 4d7a961..6f23479 100644 --- a/backend/middleware/authMiddleware.js +++ b/backend/middleware/authMiddleware.js @@ -1,13 +1,17 @@ import User from '../models/User.js'; export const authenticate = async (req, res, next) => { - const { userid: userId, authcode: authCode } = req.headers; - if (!userId || !authCode) { - return res.status(401).json({ error: 'Unauthorized: Missing credentials' }); + try { + const { userid: userId, authcode: authCode } = req.headers; + if (!userId || !authCode) { + return res.status(401).json({ error: 'Unauthorized: Missing credentials' }); + } + const user = await User.findOne({ where: { email: userId, authCode: authCode } }); + if (!user) { + return res.status(401).json({ error: 'Unauthorized: Invalid credentials' }); + } + next(); + } catch(error) { + return res.status(500).json({ error: 'Internal Server Error at auth' }); } - const user = await User.findOne({ where: { email: userId, hashedId: authCode } }); - if (!user) { - return res.status(401).json({ error: 'Unauthorized: Invalid credentials' }); - } - next(); }; \ No newline at end of file diff --git a/backend/models/Club.js b/backend/models/Club.js index 3d60998..303125c 100644 --- a/backend/models/Club.js +++ b/backend/models/Club.js @@ -7,6 +7,10 @@ const Club = sequelize.define('Club', { allowNull: false, unique: true, }, +}, { + tableName: 'clubs', + underscored: true, + timestamps: true }); export default Club; diff --git a/backend/models/DiaryDates.js b/backend/models/DiaryDates.js new file mode 100644 index 0000000..b586365 --- /dev/null +++ b/backend/models/DiaryDates.js @@ -0,0 +1,34 @@ +import { DataTypes } from 'sequelize'; +import sequelize from '../database.js'; +import Club from './Club.js'; // Importiere das Club-Modell + +const DiaryDate = sequelize.define('DiaryDate', { + date: { + type: DataTypes.DATEONLY, + allowNull: false, + }, + clubId: { + type: DataTypes.INTEGER, + allowNull: false, + references: { + model: Club, + key: 'id' + }, + onDelete: 'CASCADE', + }, + trainingStart: { + type: DataTypes.TIME, + allowNull: true, + }, + trainingEnd: { + type: DataTypes.TIME, + allowNull: true, + } +}, { + tableName: 'diary_dates', + underscored: true, + timestamps: true +}); + + +export default DiaryDate; diff --git a/backend/models/Log.js b/backend/models/Log.js index e428aa9..7a6fcb6 100644 --- a/backend/models/Log.js +++ b/backend/models/Log.js @@ -7,20 +7,18 @@ const Log = sequelize.define('Log', { type: DataTypes.STRING, allowNull: false, }, - timestamp: { - type: DataTypes.DATE, - defaultValue: DataTypes.NOW, - }, userId: { type: DataTypes.INTEGER, + allowNull: false, references: { - model: User, + model: 'user', key: 'id', }, }, -}, -{ - underscored: true +}, { + underscored: true, + tableName: 'log', + timestamps: true }); export default Log; diff --git a/backend/models/Member.js b/backend/models/Member.js index 12beb5e..ada4ac6 100644 --- a/backend/models/Member.js +++ b/backend/models/Member.js @@ -1,12 +1,10 @@ -const { DataTypes, Model } = require('sequelize'); -const crypto = require('crypto'); -const sequelize = require('../database'); -const Club = require('./Club'); -const { encryptData, decryptData } = require('../utils/encrypt'); +import { DataTypes, Model } from 'sequelize'; +import crypto from 'crypto'; +import sequelize from '../database.js'; +import Club from './Club.js'; +import { encryptData, decryptData } from '../utils/encrypt.js'; -class Member extends Model {} - -Member.init({ +const Member = sequelize.define('User', { id: { type: DataTypes.INTEGER, primaryKey: true, @@ -18,18 +16,30 @@ Member.init({ unique: true, allowNull: false, defaultValue() { - return crypto.randomBytes(16).toString('hex'); + return crypto.randomBytes(64).toString('hex'); } }, - name: { + firstName: { type: DataTypes.STRING, allowNull: false, set(value) { const encryptedValue = encryptData(value); - this.setDataValue('name', encryptedValue); + this.setDataValue('firstName', encryptedValue); }, get() { - const encryptedValue = this.getDataValue('name'); + const encryptedValue = this.getDataValue('firstName'); + return decryptData(encryptedValue); + } + }, + lastName: { + type: DataTypes.STRING, + allowNull: false, + set(value) { + const encryptedValue = encryptData(value); + this.setDataValue('lastName', encryptedValue); + }, + get() { + const encryptedValue = this.getDataValue('lastName'); return decryptData(encryptedValue); } }, @@ -80,27 +90,50 @@ Member.init({ const encryptedValue = this.getDataValue('city'); return decryptData(encryptedValue); } + }, + email: { + type: DataTypes.STRING, + allowNull: false, + set(value) { + const encryptedValue = encryptData(value); + this.setDataValue('email', encryptedValue); + }, + get() { + const encryptedValue = this.getDataValue('email'); + return decryptData(encryptedValue); + } + }, + clubId: { + type: DataTypes.INTEGER, + allowNull: false, + }, + active: { + type: DataTypes.BOOLEAN, + allowNull: false, + default: true, } }, { underscored: true, sequelize, modelName: 'Member', - tableName: 'members', + tableName: 'member', timestamps: true, hooks: { - beforeCreate: (member) => { + afterCreate: (member) => { member.hashedId = crypto.createHash('sha256').update(String(member.id)).digest('hex'); + member.save(); }, - beforeUpdate: (member) => { - if (member.changed('id')) { - member.hashedId = crypto.createHash('sha256').update(String(member.id)).digest('hex'); - } - } } -}); +}, + { + underscored: true, + tableName: 'log', + timestamps: true + } +); -Member.belongsTo(Club); -Club.hasMany(Member); +Member.belongsTo(Club, { as: 'club' }); +Club.hasMany(Member, { as: 'members' }); -module.exports = Member; +export default Member; diff --git a/backend/models/User.js b/backend/models/User.js index 0aebccc..44fd973 100644 --- a/backend/models/User.js +++ b/backend/models/User.js @@ -3,6 +3,12 @@ import sequelize from '../database.js'; import bcrypt from 'bcrypt'; const User = sequelize.define('User', { + id: { + type: DataTypes.INTEGER, + primaryKey: true, + autoIncrement: true, + allowNull: false + }, hashedId: { type: DataTypes.STRING(1024), allowNull: true, @@ -16,6 +22,10 @@ const User = sequelize.define('User', { type: DataTypes.STRING, allowNull: false, }, + salt: { + type: DataTypes.STRING, + allowNull: true, + }, activationCode: { type: DataTypes.STRING, allowNull: true, @@ -30,20 +40,27 @@ const User = sequelize.define('User', { } }, { underscored: true, - table: 'user', + tableName: 'user', + timestamps: true, hooks: { beforeCreate: async (user) => { const salt = await bcrypt.genSalt(10); + user.salt = salt; + console.log(user); user.password = await bcrypt.hash(user.password, salt); }, beforeUpdate: async (user) => { if (user.changed('password')) { - const salt = await bcrypt.genSalt(10); - user.password = await bcrypt.hash(user.password, salt); + if (!user.password.startsWith('$2b$') && !user.password.startsWith('$2a$')) { + const salt = user.salt; + user.password = await bcrypt.hash(user.password, salt); + } } }, afterCreate: async (user) => { - user.hashedId = bcrypt.hash(user.id.toString()); + const salt = await bcrypt.genSalt(10); + user.hashedId = await bcrypt.hash(user.id.toString(), salt); + await user.save(); } }, }); diff --git a/backend/models/UserClub.js b/backend/models/UserClub.js index 1efecec..2bef85d 100644 --- a/backend/models/UserClub.js +++ b/backend/models/UserClub.js @@ -23,7 +23,9 @@ const UserClub = sequelize.define('UserClub', { defaultValue: false, }, }, { - underscored: true + underscored: true, + tableName: 'user_club', + timestamps: true }); User.belongsToMany(Club, { through: UserClub, foreignKey: 'userId' }); diff --git a/backend/models/index.js b/backend/models/index.js index a39efd9..7e7b66a 100644 --- a/backend/models/index.js +++ b/backend/models/index.js @@ -2,6 +2,7 @@ import User from './User.js'; import Log from './Log.js'; import Club from './Club.js'; import UserClub from './UserClub.js'; +import DiaryDate from './DiaryDates.js'; User.hasMany(Log, { foreignKey: 'userId' }); Log.belongsTo(User, { foreignKey: 'userId' }); @@ -9,4 +10,7 @@ Log.belongsTo(User, { foreignKey: 'userId' }); User.belongsToMany(Club, { through: UserClub, foreignKey: 'userId' }); Club.belongsToMany(User, { through: UserClub, foreignKey: 'clubId' }); +DiaryDate.belongsTo(Club, { foreignKey: 'clubId' }); +Club.hasMany(DiaryDate, { foreignKey: 'clubId' }); + export { User, Log, Club, UserClub }; diff --git a/backend/node_modules/.bin/color-support b/backend/node_modules/.bin/color-support deleted file mode 100644 index f77f9d5..0000000 --- a/backend/node_modules/.bin/color-support +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") - -case `uname` in - *CYGWIN*|*MINGW*|*MSYS*) - if command -v cygpath > /dev/null 2>&1; then - basedir=`cygpath -w "$basedir"` - fi - ;; -esac - -if [ -x "$basedir/node" ]; then - exec "$basedir/node" "$basedir/../color-support/bin.js" "$@" -else - exec node "$basedir/../color-support/bin.js" "$@" -fi diff --git a/backend/node_modules/.bin/color-support b/backend/node_modules/.bin/color-support new file mode 120000 index 0000000..fcbcb28 --- /dev/null +++ b/backend/node_modules/.bin/color-support @@ -0,0 +1 @@ +../color-support/bin.js \ No newline at end of file diff --git a/backend/node_modules/.bin/color-support.cmd b/backend/node_modules/.bin/color-support.cmd deleted file mode 100644 index 005f9a5..0000000 --- a/backend/node_modules/.bin/color-support.cmd +++ /dev/null @@ -1,17 +0,0 @@ -@ECHO off -GOTO start -:find_dp0 -SET dp0=%~dp0 -EXIT /b -:start -SETLOCAL -CALL :find_dp0 - -IF EXIST "%dp0%\node.exe" ( - SET "_prog=%dp0%\node.exe" -) ELSE ( - SET "_prog=node" - SET PATHEXT=%PATHEXT:;.JS;=;% -) - -endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\color-support\bin.js" %* diff --git a/backend/node_modules/.bin/color-support.ps1 b/backend/node_modules/.bin/color-support.ps1 deleted file mode 100644 index f5c9fe4..0000000 --- a/backend/node_modules/.bin/color-support.ps1 +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env pwsh -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent - -$exe="" -if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { - # Fix case when both the Windows and Linux builds of Node - # are installed in the same directory - $exe=".exe" -} -$ret=0 -if (Test-Path "$basedir/node$exe") { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "$basedir/node$exe" "$basedir/../color-support/bin.js" $args - } else { - & "$basedir/node$exe" "$basedir/../color-support/bin.js" $args - } - $ret=$LASTEXITCODE -} else { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "node$exe" "$basedir/../color-support/bin.js" $args - } else { - & "node$exe" "$basedir/../color-support/bin.js" $args - } - $ret=$LASTEXITCODE -} -exit $ret diff --git a/backend/node_modules/.bin/mime b/backend/node_modules/.bin/mime deleted file mode 100644 index 7751de3..0000000 --- a/backend/node_modules/.bin/mime +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") - -case `uname` in - *CYGWIN*|*MINGW*|*MSYS*) - if command -v cygpath > /dev/null 2>&1; then - basedir=`cygpath -w "$basedir"` - fi - ;; -esac - -if [ -x "$basedir/node" ]; then - exec "$basedir/node" "$basedir/../mime/cli.js" "$@" -else - exec node "$basedir/../mime/cli.js" "$@" -fi diff --git a/backend/node_modules/.bin/mime b/backend/node_modules/.bin/mime new file mode 120000 index 0000000..fbb7ee0 --- /dev/null +++ b/backend/node_modules/.bin/mime @@ -0,0 +1 @@ +../mime/cli.js \ No newline at end of file diff --git a/backend/node_modules/.bin/mime.cmd b/backend/node_modules/.bin/mime.cmd deleted file mode 100644 index 54491f1..0000000 --- a/backend/node_modules/.bin/mime.cmd +++ /dev/null @@ -1,17 +0,0 @@ -@ECHO off -GOTO start -:find_dp0 -SET dp0=%~dp0 -EXIT /b -:start -SETLOCAL -CALL :find_dp0 - -IF EXIST "%dp0%\node.exe" ( - SET "_prog=%dp0%\node.exe" -) ELSE ( - SET "_prog=node" - SET PATHEXT=%PATHEXT:;.JS;=;% -) - -endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\mime\cli.js" %* diff --git a/backend/node_modules/.bin/mime.ps1 b/backend/node_modules/.bin/mime.ps1 deleted file mode 100644 index 2222f40..0000000 --- a/backend/node_modules/.bin/mime.ps1 +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env pwsh -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent - -$exe="" -if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { - # Fix case when both the Windows and Linux builds of Node - # are installed in the same directory - $exe=".exe" -} -$ret=0 -if (Test-Path "$basedir/node$exe") { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "$basedir/node$exe" "$basedir/../mime/cli.js" $args - } else { - & "$basedir/node$exe" "$basedir/../mime/cli.js" $args - } - $ret=$LASTEXITCODE -} else { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "node$exe" "$basedir/../mime/cli.js" $args - } else { - & "node$exe" "$basedir/../mime/cli.js" $args - } - $ret=$LASTEXITCODE -} -exit $ret diff --git a/backend/node_modules/.bin/mkdirp b/backend/node_modules/.bin/mkdirp deleted file mode 100644 index 1ab9c81..0000000 --- a/backend/node_modules/.bin/mkdirp +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") - -case `uname` in - *CYGWIN*|*MINGW*|*MSYS*) - if command -v cygpath > /dev/null 2>&1; then - basedir=`cygpath -w "$basedir"` - fi - ;; -esac - -if [ -x "$basedir/node" ]; then - exec "$basedir/node" "$basedir/../mkdirp/bin/cmd.js" "$@" -else - exec node "$basedir/../mkdirp/bin/cmd.js" "$@" -fi diff --git a/backend/node_modules/.bin/mkdirp b/backend/node_modules/.bin/mkdirp new file mode 120000 index 0000000..017896c --- /dev/null +++ b/backend/node_modules/.bin/mkdirp @@ -0,0 +1 @@ +../mkdirp/bin/cmd.js \ No newline at end of file diff --git a/backend/node_modules/.bin/mkdirp.cmd b/backend/node_modules/.bin/mkdirp.cmd deleted file mode 100644 index a865dd9..0000000 --- a/backend/node_modules/.bin/mkdirp.cmd +++ /dev/null @@ -1,17 +0,0 @@ -@ECHO off -GOTO start -:find_dp0 -SET dp0=%~dp0 -EXIT /b -:start -SETLOCAL -CALL :find_dp0 - -IF EXIST "%dp0%\node.exe" ( - SET "_prog=%dp0%\node.exe" -) ELSE ( - SET "_prog=node" - SET PATHEXT=%PATHEXT:;.JS;=;% -) - -endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\mkdirp\bin\cmd.js" %* diff --git a/backend/node_modules/.bin/mkdirp.ps1 b/backend/node_modules/.bin/mkdirp.ps1 deleted file mode 100644 index 911e854..0000000 --- a/backend/node_modules/.bin/mkdirp.ps1 +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env pwsh -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent - -$exe="" -if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { - # Fix case when both the Windows and Linux builds of Node - # are installed in the same directory - $exe=".exe" -} -$ret=0 -if (Test-Path "$basedir/node$exe") { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "$basedir/node$exe" "$basedir/../mkdirp/bin/cmd.js" $args - } else { - & "$basedir/node$exe" "$basedir/../mkdirp/bin/cmd.js" $args - } - $ret=$LASTEXITCODE -} else { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "node$exe" "$basedir/../mkdirp/bin/cmd.js" $args - } else { - & "node$exe" "$basedir/../mkdirp/bin/cmd.js" $args - } - $ret=$LASTEXITCODE -} -exit $ret diff --git a/backend/node_modules/.bin/node-pre-gyp b/backend/node_modules/.bin/node-pre-gyp deleted file mode 100644 index d1619e4..0000000 --- a/backend/node_modules/.bin/node-pre-gyp +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") - -case `uname` in - *CYGWIN*|*MINGW*|*MSYS*) - if command -v cygpath > /dev/null 2>&1; then - basedir=`cygpath -w "$basedir"` - fi - ;; -esac - -if [ -x "$basedir/node" ]; then - exec "$basedir/node" "$basedir/../@mapbox/node-pre-gyp/bin/node-pre-gyp" "$@" -else - exec node "$basedir/../@mapbox/node-pre-gyp/bin/node-pre-gyp" "$@" -fi diff --git a/backend/node_modules/.bin/node-pre-gyp b/backend/node_modules/.bin/node-pre-gyp new file mode 120000 index 0000000..2946e6a --- /dev/null +++ b/backend/node_modules/.bin/node-pre-gyp @@ -0,0 +1 @@ +../@mapbox/node-pre-gyp/bin/node-pre-gyp \ No newline at end of file diff --git a/backend/node_modules/.bin/node-pre-gyp.cmd b/backend/node_modules/.bin/node-pre-gyp.cmd deleted file mode 100644 index a2fc508..0000000 --- a/backend/node_modules/.bin/node-pre-gyp.cmd +++ /dev/null @@ -1,17 +0,0 @@ -@ECHO off -GOTO start -:find_dp0 -SET dp0=%~dp0 -EXIT /b -:start -SETLOCAL -CALL :find_dp0 - -IF EXIST "%dp0%\node.exe" ( - SET "_prog=%dp0%\node.exe" -) ELSE ( - SET "_prog=node" - SET PATHEXT=%PATHEXT:;.JS;=;% -) - -endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\@mapbox\node-pre-gyp\bin\node-pre-gyp" %* diff --git a/backend/node_modules/.bin/node-pre-gyp.ps1 b/backend/node_modules/.bin/node-pre-gyp.ps1 deleted file mode 100644 index ed297ff..0000000 --- a/backend/node_modules/.bin/node-pre-gyp.ps1 +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env pwsh -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent - -$exe="" -if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { - # Fix case when both the Windows and Linux builds of Node - # are installed in the same directory - $exe=".exe" -} -$ret=0 -if (Test-Path "$basedir/node$exe") { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "$basedir/node$exe" "$basedir/../@mapbox/node-pre-gyp/bin/node-pre-gyp" $args - } else { - & "$basedir/node$exe" "$basedir/../@mapbox/node-pre-gyp/bin/node-pre-gyp" $args - } - $ret=$LASTEXITCODE -} else { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "node$exe" "$basedir/../@mapbox/node-pre-gyp/bin/node-pre-gyp" $args - } else { - & "node$exe" "$basedir/../@mapbox/node-pre-gyp/bin/node-pre-gyp" $args - } - $ret=$LASTEXITCODE -} -exit $ret diff --git a/backend/node_modules/.bin/nodemon b/backend/node_modules/.bin/nodemon deleted file mode 100644 index c477a18..0000000 --- a/backend/node_modules/.bin/nodemon +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") - -case `uname` in - *CYGWIN*|*MINGW*|*MSYS*) - if command -v cygpath > /dev/null 2>&1; then - basedir=`cygpath -w "$basedir"` - fi - ;; -esac - -if [ -x "$basedir/node" ]; then - exec "$basedir/node" "$basedir/../nodemon/bin/nodemon.js" "$@" -else - exec node "$basedir/../nodemon/bin/nodemon.js" "$@" -fi diff --git a/backend/node_modules/.bin/nodemon b/backend/node_modules/.bin/nodemon new file mode 120000 index 0000000..1056ddc --- /dev/null +++ b/backend/node_modules/.bin/nodemon @@ -0,0 +1 @@ +../nodemon/bin/nodemon.js \ No newline at end of file diff --git a/backend/node_modules/.bin/nodemon.cmd b/backend/node_modules/.bin/nodemon.cmd deleted file mode 100644 index 55acf8a..0000000 --- a/backend/node_modules/.bin/nodemon.cmd +++ /dev/null @@ -1,17 +0,0 @@ -@ECHO off -GOTO start -:find_dp0 -SET dp0=%~dp0 -EXIT /b -:start -SETLOCAL -CALL :find_dp0 - -IF EXIST "%dp0%\node.exe" ( - SET "_prog=%dp0%\node.exe" -) ELSE ( - SET "_prog=node" - SET PATHEXT=%PATHEXT:;.JS;=;% -) - -endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\nodemon\bin\nodemon.js" %* diff --git a/backend/node_modules/.bin/nodemon.ps1 b/backend/node_modules/.bin/nodemon.ps1 deleted file mode 100644 index d4e3f5d..0000000 --- a/backend/node_modules/.bin/nodemon.ps1 +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env pwsh -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent - -$exe="" -if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { - # Fix case when both the Windows and Linux builds of Node - # are installed in the same directory - $exe=".exe" -} -$ret=0 -if (Test-Path "$basedir/node$exe") { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "$basedir/node$exe" "$basedir/../nodemon/bin/nodemon.js" $args - } else { - & "$basedir/node$exe" "$basedir/../nodemon/bin/nodemon.js" $args - } - $ret=$LASTEXITCODE -} else { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "node$exe" "$basedir/../nodemon/bin/nodemon.js" $args - } else { - & "node$exe" "$basedir/../nodemon/bin/nodemon.js" $args - } - $ret=$LASTEXITCODE -} -exit $ret diff --git a/backend/node_modules/.bin/nodetouch b/backend/node_modules/.bin/nodetouch deleted file mode 100644 index 3e146b4..0000000 --- a/backend/node_modules/.bin/nodetouch +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") - -case `uname` in - *CYGWIN*|*MINGW*|*MSYS*) - if command -v cygpath > /dev/null 2>&1; then - basedir=`cygpath -w "$basedir"` - fi - ;; -esac - -if [ -x "$basedir/node" ]; then - exec "$basedir/node" "$basedir/../touch/bin/nodetouch.js" "$@" -else - exec node "$basedir/../touch/bin/nodetouch.js" "$@" -fi diff --git a/backend/node_modules/.bin/nodetouch b/backend/node_modules/.bin/nodetouch new file mode 120000 index 0000000..3409fdb --- /dev/null +++ b/backend/node_modules/.bin/nodetouch @@ -0,0 +1 @@ +../touch/bin/nodetouch.js \ No newline at end of file diff --git a/backend/node_modules/.bin/nodetouch.cmd b/backend/node_modules/.bin/nodetouch.cmd deleted file mode 100644 index 8298b91..0000000 --- a/backend/node_modules/.bin/nodetouch.cmd +++ /dev/null @@ -1,17 +0,0 @@ -@ECHO off -GOTO start -:find_dp0 -SET dp0=%~dp0 -EXIT /b -:start -SETLOCAL -CALL :find_dp0 - -IF EXIST "%dp0%\node.exe" ( - SET "_prog=%dp0%\node.exe" -) ELSE ( - SET "_prog=node" - SET PATHEXT=%PATHEXT:;.JS;=;% -) - -endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\touch\bin\nodetouch.js" %* diff --git a/backend/node_modules/.bin/nodetouch.ps1 b/backend/node_modules/.bin/nodetouch.ps1 deleted file mode 100644 index 5f68b4c..0000000 --- a/backend/node_modules/.bin/nodetouch.ps1 +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env pwsh -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent - -$exe="" -if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { - # Fix case when both the Windows and Linux builds of Node - # are installed in the same directory - $exe=".exe" -} -$ret=0 -if (Test-Path "$basedir/node$exe") { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "$basedir/node$exe" "$basedir/../touch/bin/nodetouch.js" $args - } else { - & "$basedir/node$exe" "$basedir/../touch/bin/nodetouch.js" $args - } - $ret=$LASTEXITCODE -} else { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "node$exe" "$basedir/../touch/bin/nodetouch.js" $args - } else { - & "node$exe" "$basedir/../touch/bin/nodetouch.js" $args - } - $ret=$LASTEXITCODE -} -exit $ret diff --git a/backend/node_modules/.bin/nopt b/backend/node_modules/.bin/nopt deleted file mode 100644 index 0808130..0000000 --- a/backend/node_modules/.bin/nopt +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") - -case `uname` in - *CYGWIN*|*MINGW*|*MSYS*) - if command -v cygpath > /dev/null 2>&1; then - basedir=`cygpath -w "$basedir"` - fi - ;; -esac - -if [ -x "$basedir/node" ]; then - exec "$basedir/node" "$basedir/../nopt/bin/nopt.js" "$@" -else - exec node "$basedir/../nopt/bin/nopt.js" "$@" -fi diff --git a/backend/node_modules/.bin/nopt b/backend/node_modules/.bin/nopt new file mode 120000 index 0000000..6b6566e --- /dev/null +++ b/backend/node_modules/.bin/nopt @@ -0,0 +1 @@ +../nopt/bin/nopt.js \ No newline at end of file diff --git a/backend/node_modules/.bin/nopt.cmd b/backend/node_modules/.bin/nopt.cmd deleted file mode 100644 index a7f38b3..0000000 --- a/backend/node_modules/.bin/nopt.cmd +++ /dev/null @@ -1,17 +0,0 @@ -@ECHO off -GOTO start -:find_dp0 -SET dp0=%~dp0 -EXIT /b -:start -SETLOCAL -CALL :find_dp0 - -IF EXIST "%dp0%\node.exe" ( - SET "_prog=%dp0%\node.exe" -) ELSE ( - SET "_prog=node" - SET PATHEXT=%PATHEXT:;.JS;=;% -) - -endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\nopt\bin\nopt.js" %* diff --git a/backend/node_modules/.bin/nopt.ps1 b/backend/node_modules/.bin/nopt.ps1 deleted file mode 100644 index 9d6ba56..0000000 --- a/backend/node_modules/.bin/nopt.ps1 +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env pwsh -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent - -$exe="" -if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { - # Fix case when both the Windows and Linux builds of Node - # are installed in the same directory - $exe=".exe" -} -$ret=0 -if (Test-Path "$basedir/node$exe") { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "$basedir/node$exe" "$basedir/../nopt/bin/nopt.js" $args - } else { - & "$basedir/node$exe" "$basedir/../nopt/bin/nopt.js" $args - } - $ret=$LASTEXITCODE -} else { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "node$exe" "$basedir/../nopt/bin/nopt.js" $args - } else { - & "node$exe" "$basedir/../nopt/bin/nopt.js" $args - } - $ret=$LASTEXITCODE -} -exit $ret diff --git a/backend/node_modules/.bin/rimraf b/backend/node_modules/.bin/rimraf deleted file mode 100644 index 6d6240a..0000000 --- a/backend/node_modules/.bin/rimraf +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") - -case `uname` in - *CYGWIN*|*MINGW*|*MSYS*) - if command -v cygpath > /dev/null 2>&1; then - basedir=`cygpath -w "$basedir"` - fi - ;; -esac - -if [ -x "$basedir/node" ]; then - exec "$basedir/node" "$basedir/../rimraf/bin.js" "$@" -else - exec node "$basedir/../rimraf/bin.js" "$@" -fi diff --git a/backend/node_modules/.bin/rimraf b/backend/node_modules/.bin/rimraf new file mode 120000 index 0000000..4cd49a4 --- /dev/null +++ b/backend/node_modules/.bin/rimraf @@ -0,0 +1 @@ +../rimraf/bin.js \ No newline at end of file diff --git a/backend/node_modules/.bin/rimraf.cmd b/backend/node_modules/.bin/rimraf.cmd deleted file mode 100644 index 13f45ec..0000000 --- a/backend/node_modules/.bin/rimraf.cmd +++ /dev/null @@ -1,17 +0,0 @@ -@ECHO off -GOTO start -:find_dp0 -SET dp0=%~dp0 -EXIT /b -:start -SETLOCAL -CALL :find_dp0 - -IF EXIST "%dp0%\node.exe" ( - SET "_prog=%dp0%\node.exe" -) ELSE ( - SET "_prog=node" - SET PATHEXT=%PATHEXT:;.JS;=;% -) - -endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\rimraf\bin.js" %* diff --git a/backend/node_modules/.bin/rimraf.ps1 b/backend/node_modules/.bin/rimraf.ps1 deleted file mode 100644 index 1716791..0000000 --- a/backend/node_modules/.bin/rimraf.ps1 +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env pwsh -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent - -$exe="" -if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { - # Fix case when both the Windows and Linux builds of Node - # are installed in the same directory - $exe=".exe" -} -$ret=0 -if (Test-Path "$basedir/node$exe") { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "$basedir/node$exe" "$basedir/../rimraf/bin.js" $args - } else { - & "$basedir/node$exe" "$basedir/../rimraf/bin.js" $args - } - $ret=$LASTEXITCODE -} else { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "node$exe" "$basedir/../rimraf/bin.js" $args - } else { - & "node$exe" "$basedir/../rimraf/bin.js" $args - } - $ret=$LASTEXITCODE -} -exit $ret diff --git a/backend/node_modules/.bin/semver b/backend/node_modules/.bin/semver deleted file mode 100644 index 97c5327..0000000 --- a/backend/node_modules/.bin/semver +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") - -case `uname` in - *CYGWIN*|*MINGW*|*MSYS*) - if command -v cygpath > /dev/null 2>&1; then - basedir=`cygpath -w "$basedir"` - fi - ;; -esac - -if [ -x "$basedir/node" ]; then - exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" -else - exec node "$basedir/../semver/bin/semver.js" "$@" -fi diff --git a/backend/node_modules/.bin/semver b/backend/node_modules/.bin/semver new file mode 120000 index 0000000..5aaadf4 --- /dev/null +++ b/backend/node_modules/.bin/semver @@ -0,0 +1 @@ +../semver/bin/semver.js \ No newline at end of file diff --git a/backend/node_modules/.bin/semver.cmd b/backend/node_modules/.bin/semver.cmd deleted file mode 100644 index 9913fa9..0000000 --- a/backend/node_modules/.bin/semver.cmd +++ /dev/null @@ -1,17 +0,0 @@ -@ECHO off -GOTO start -:find_dp0 -SET dp0=%~dp0 -EXIT /b -:start -SETLOCAL -CALL :find_dp0 - -IF EXIST "%dp0%\node.exe" ( - SET "_prog=%dp0%\node.exe" -) ELSE ( - SET "_prog=node" - SET PATHEXT=%PATHEXT:;.JS;=;% -) - -endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\semver\bin\semver.js" %* diff --git a/backend/node_modules/.bin/semver.ps1 b/backend/node_modules/.bin/semver.ps1 deleted file mode 100644 index 314717a..0000000 --- a/backend/node_modules/.bin/semver.ps1 +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env pwsh -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent - -$exe="" -if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { - # Fix case when both the Windows and Linux builds of Node - # are installed in the same directory - $exe=".exe" -} -$ret=0 -if (Test-Path "$basedir/node$exe") { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args - } else { - & "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args - } - $ret=$LASTEXITCODE -} else { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "node$exe" "$basedir/../semver/bin/semver.js" $args - } else { - & "node$exe" "$basedir/../semver/bin/semver.js" $args - } - $ret=$LASTEXITCODE -} -exit $ret diff --git a/backend/node_modules/.bin/uuid b/backend/node_modules/.bin/uuid deleted file mode 100644 index 0c2d469..0000000 --- a/backend/node_modules/.bin/uuid +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") - -case `uname` in - *CYGWIN*|*MINGW*|*MSYS*) - if command -v cygpath > /dev/null 2>&1; then - basedir=`cygpath -w "$basedir"` - fi - ;; -esac - -if [ -x "$basedir/node" ]; then - exec "$basedir/node" "$basedir/../uuid/dist/bin/uuid" "$@" -else - exec node "$basedir/../uuid/dist/bin/uuid" "$@" -fi diff --git a/backend/node_modules/.bin/uuid b/backend/node_modules/.bin/uuid new file mode 120000 index 0000000..588f70e --- /dev/null +++ b/backend/node_modules/.bin/uuid @@ -0,0 +1 @@ +../uuid/dist/bin/uuid \ No newline at end of file diff --git a/backend/node_modules/.bin/uuid.cmd b/backend/node_modules/.bin/uuid.cmd deleted file mode 100644 index 0f2376e..0000000 --- a/backend/node_modules/.bin/uuid.cmd +++ /dev/null @@ -1,17 +0,0 @@ -@ECHO off -GOTO start -:find_dp0 -SET dp0=%~dp0 -EXIT /b -:start -SETLOCAL -CALL :find_dp0 - -IF EXIST "%dp0%\node.exe" ( - SET "_prog=%dp0%\node.exe" -) ELSE ( - SET "_prog=node" - SET PATHEXT=%PATHEXT:;.JS;=;% -) - -endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\uuid\dist\bin\uuid" %* diff --git a/backend/node_modules/.bin/uuid.ps1 b/backend/node_modules/.bin/uuid.ps1 deleted file mode 100644 index 7804628..0000000 --- a/backend/node_modules/.bin/uuid.ps1 +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env pwsh -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent - -$exe="" -if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { - # Fix case when both the Windows and Linux builds of Node - # are installed in the same directory - $exe=".exe" -} -$ret=0 -if (Test-Path "$basedir/node$exe") { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "$basedir/node$exe" "$basedir/../uuid/dist/bin/uuid" $args - } else { - & "$basedir/node$exe" "$basedir/../uuid/dist/bin/uuid" $args - } - $ret=$LASTEXITCODE -} else { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "node$exe" "$basedir/../uuid/dist/bin/uuid" $args - } else { - & "node$exe" "$basedir/../uuid/dist/bin/uuid" $args - } - $ret=$LASTEXITCODE -} -exit $ret diff --git a/backend/node_modules/@mapbox/node-pre-gyp/bin/node-pre-gyp b/backend/node_modules/@mapbox/node-pre-gyp/bin/node-pre-gyp old mode 100644 new mode 100755 diff --git a/backend/node_modules/@types/debug/README.md b/backend/node_modules/@types/debug/README.md index b67a4dc..e9563de 100644 --- a/backend/node_modules/@types/debug/README.md +++ b/backend/node_modules/@types/debug/README.md @@ -1,13 +1,13 @@ -# Installation -> `npm install --save @types/debug` - -# Summary -This package contains type definitions for debug (https://github.com/debug-js/debug). - -# Details -Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/debug. -## [index.d.ts](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/debug/index.d.ts) -````ts +# Installation +> `npm install --save @types/debug` + +# Summary +This package contains type definitions for debug (https://github.com/debug-js/debug). + +# Details +Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/debug. +## [index.d.ts](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/debug/index.d.ts) +````ts declare var debug: debug.Debug & { debug: debug.Debug; default: debug.Debug }; export = debug; @@ -58,12 +58,12 @@ declare namespace debug { extend: (namespace: string, delimiter?: string) => Debugger; } } - -```` - -### Additional Details - * Last updated: Thu, 09 Nov 2023 03:06:57 GMT - * Dependencies: [@types/ms](https://npmjs.com/package/@types/ms) - -# Credits -These definitions were written by [Seon-Wook Park](https://github.com/swook), [Gal Talmor](https://github.com/galtalmor), [John McLaughlin](https://github.com/zamb3zi), [Brasten Sager](https://github.com/brasten), [Nicolas Penin](https://github.com/npenin), [Kristian Brünn](https://github.com/kristianmitk), and [Caleb Gregory](https://github.com/calebgregory). + +```` + +### Additional Details + * Last updated: Thu, 09 Nov 2023 03:06:57 GMT + * Dependencies: [@types/ms](https://npmjs.com/package/@types/ms) + +# Credits +These definitions were written by [Seon-Wook Park](https://github.com/swook), [Gal Talmor](https://github.com/galtalmor), [John McLaughlin](https://github.com/zamb3zi), [Brasten Sager](https://github.com/brasten), [Nicolas Penin](https://github.com/npenin), [Kristian Brünn](https://github.com/kristianmitk), and [Caleb Gregory](https://github.com/calebgregory). diff --git a/backend/node_modules/@types/ms/README.md b/backend/node_modules/@types/ms/README.md index e2354c3..6512928 100644 --- a/backend/node_modules/@types/ms/README.md +++ b/backend/node_modules/@types/ms/README.md @@ -1,13 +1,13 @@ -# Installation -> `npm install --save @types/ms` - -# Summary -This package contains type definitions for ms (https://github.com/zeit/ms). - -# Details -Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/ms. -## [index.d.ts](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/ms/index.d.ts) -````ts +# Installation +> `npm install --save @types/ms` + +# Summary +This package contains type definitions for ms (https://github.com/zeit/ms). + +# Details +Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/ms. +## [index.d.ts](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/ms/index.d.ts) +````ts /** * Short/Long format for `value`. * @@ -26,12 +26,12 @@ declare function ms(value: number, options?: { long: boolean }): string; declare function ms(value: string): number; export = ms; - -```` - -### Additional Details - * Last updated: Tue, 07 Nov 2023 09:09:39 GMT - * Dependencies: none - -# Credits -These definitions were written by [Zhiyuan Wang](https://github.com/danny8002). + +```` + +### Additional Details + * Last updated: Tue, 07 Nov 2023 09:09:39 GMT + * Dependencies: none + +# Credits +These definitions were written by [Zhiyuan Wang](https://github.com/danny8002). diff --git a/backend/node_modules/@types/node/README.md b/backend/node_modules/@types/node/README.md index 317aecd..7d75f1c 100644 --- a/backend/node_modules/@types/node/README.md +++ b/backend/node_modules/@types/node/README.md @@ -1,15 +1,15 @@ -# Installation -> `npm install --save @types/node` - -# Summary -This package contains type definitions for node (https://nodejs.org/). - -# Details -Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node. - -### Additional Details - * Last updated: Tue, 23 Jul 2024 18:09:25 GMT - * Dependencies: [undici-types](https://npmjs.com/package/undici-types) - -# Credits -These definitions were written by [Microsoft TypeScript](https://github.com/Microsoft), [Alberto Schiabel](https://github.com/jkomyno), [Alvis HT Tang](https://github.com/alvis), [Andrew Makarov](https://github.com/r3nya), [Benjamin Toueg](https://github.com/btoueg), [Chigozirim C.](https://github.com/smac89), [David Junger](https://github.com/touffy), [Deividas Bakanas](https://github.com/DeividasBakanas), [Eugene Y. Q. Shen](https://github.com/eyqs), [Hannes Magnusson](https://github.com/Hannes-Magnusson-CK), [Huw](https://github.com/hoo29), [Kelvin Jin](https://github.com/kjin), [Klaus Meinhardt](https://github.com/ajafff), [Lishude](https://github.com/islishude), [Mariusz Wiktorczyk](https://github.com/mwiktorczyk), [Mohsen Azimi](https://github.com/mohsen1), [Nikita Galkin](https://github.com/galkin), [Parambir Singh](https://github.com/parambirs), [Sebastian Silbermann](https://github.com/eps1lon), [Thomas den Hollander](https://github.com/ThomasdenH), [Wilco Bakker](https://github.com/WilcoBakker), [wwwy3y3](https://github.com/wwwy3y3), [Samuel Ainsworth](https://github.com/samuela), [Kyle Uehlein](https://github.com/kuehlein), [Thanik Bhongbhibhat](https://github.com/bhongy), [Marcin Kopacz](https://github.com/chyzwar), [Trivikram Kamat](https://github.com/trivikr), [Junxiao Shi](https://github.com/yoursunny), [Ilia Baryshnikov](https://github.com/qwelias), [ExE Boss](https://github.com/ExE-Boss), [Piotr Błażejewicz](https://github.com/peterblazejewicz), [Anna Henningsen](https://github.com/addaleax), [Victor Perin](https://github.com/victorperin), [Yongsheng Zhang](https://github.com/ZYSzys), [NodeJS Contributors](https://github.com/NodeJS), [Linus Unnebäck](https://github.com/LinusU), [wafuwafu13](https://github.com/wafuwafu13), [Matteo Collina](https://github.com/mcollina), and [Dmitry Semigradsky](https://github.com/Semigradsky). +# Installation +> `npm install --save @types/node` + +# Summary +This package contains type definitions for node (https://nodejs.org/). + +# Details +Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node. + +### Additional Details + * Last updated: Tue, 23 Jul 2024 18:09:25 GMT + * Dependencies: [undici-types](https://npmjs.com/package/undici-types) + +# Credits +These definitions were written by [Microsoft TypeScript](https://github.com/Microsoft), [Alberto Schiabel](https://github.com/jkomyno), [Alvis HT Tang](https://github.com/alvis), [Andrew Makarov](https://github.com/r3nya), [Benjamin Toueg](https://github.com/btoueg), [Chigozirim C.](https://github.com/smac89), [David Junger](https://github.com/touffy), [Deividas Bakanas](https://github.com/DeividasBakanas), [Eugene Y. Q. Shen](https://github.com/eyqs), [Hannes Magnusson](https://github.com/Hannes-Magnusson-CK), [Huw](https://github.com/hoo29), [Kelvin Jin](https://github.com/kjin), [Klaus Meinhardt](https://github.com/ajafff), [Lishude](https://github.com/islishude), [Mariusz Wiktorczyk](https://github.com/mwiktorczyk), [Mohsen Azimi](https://github.com/mohsen1), [Nikita Galkin](https://github.com/galkin), [Parambir Singh](https://github.com/parambirs), [Sebastian Silbermann](https://github.com/eps1lon), [Thomas den Hollander](https://github.com/ThomasdenH), [Wilco Bakker](https://github.com/WilcoBakker), [wwwy3y3](https://github.com/wwwy3y3), [Samuel Ainsworth](https://github.com/samuela), [Kyle Uehlein](https://github.com/kuehlein), [Thanik Bhongbhibhat](https://github.com/bhongy), [Marcin Kopacz](https://github.com/chyzwar), [Trivikram Kamat](https://github.com/trivikr), [Junxiao Shi](https://github.com/yoursunny), [Ilia Baryshnikov](https://github.com/qwelias), [ExE Boss](https://github.com/ExE-Boss), [Piotr Błażejewicz](https://github.com/peterblazejewicz), [Anna Henningsen](https://github.com/addaleax), [Victor Perin](https://github.com/victorperin), [Yongsheng Zhang](https://github.com/ZYSzys), [NodeJS Contributors](https://github.com/NodeJS), [Linus Unnebäck](https://github.com/LinusU), [wafuwafu13](https://github.com/wafuwafu13), [Matteo Collina](https://github.com/mcollina), and [Dmitry Semigradsky](https://github.com/Semigradsky). diff --git a/backend/node_modules/@types/validator/README.md b/backend/node_modules/@types/validator/README.md index d86ef04..5a9c5be 100644 --- a/backend/node_modules/@types/validator/README.md +++ b/backend/node_modules/@types/validator/README.md @@ -1,15 +1,15 @@ -# Installation -> `npm install --save @types/validator` - -# Summary -This package contains type definitions for validator (https://github.com/validatorjs/validator.js). - -# Details -Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/validator. - -### Additional Details - * Last updated: Sun, 16 Jun 2024 11:35:49 GMT - * Dependencies: none - -# Credits -These definitions were written by [tgfjt](https://github.com/tgfjt), [Ilya Mochalov](https://github.com/chrootsu), [Ayman Nedjmeddine](https://github.com/IOAyman), [Louay Alakkad](https://github.com/louy), [Bonggyun Lee](https://github.com/deptno), [Naoto Yokoyama](https://github.com/builtinnya), [Philipp Katz](https://github.com/qqilihq), [Jace Warren](https://github.com/keatz55), [Munif Tanjim](https://github.com/MunifTanjim), [Vlad Poluch](https://github.com/vlapo), [Piotr Błażejewicz](https://github.com/peterblazejewicz), [Matteo Nista](https://github.com/Mattewn99), [Roman Babiak](https://github.com/Almost-Infinity), and [Daniel Freire](https://github.com/dcfreire). +# Installation +> `npm install --save @types/validator` + +# Summary +This package contains type definitions for validator (https://github.com/validatorjs/validator.js). + +# Details +Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/validator. + +### Additional Details + * Last updated: Sun, 16 Jun 2024 11:35:49 GMT + * Dependencies: none + +# Credits +These definitions were written by [tgfjt](https://github.com/tgfjt), [Ilya Mochalov](https://github.com/chrootsu), [Ayman Nedjmeddine](https://github.com/IOAyman), [Louay Alakkad](https://github.com/louy), [Bonggyun Lee](https://github.com/deptno), [Naoto Yokoyama](https://github.com/builtinnya), [Philipp Katz](https://github.com/qqilihq), [Jace Warren](https://github.com/keatz55), [Munif Tanjim](https://github.com/MunifTanjim), [Vlad Poluch](https://github.com/vlapo), [Piotr Błażejewicz](https://github.com/peterblazejewicz), [Matteo Nista](https://github.com/Mattewn99), [Roman Babiak](https://github.com/Almost-Infinity), and [Daniel Freire](https://github.com/dcfreire). diff --git a/backend/node_modules/aws-ssl-profiles/package.json b/backend/node_modules/aws-ssl-profiles/package.json old mode 100644 new mode 100755 diff --git a/backend/node_modules/bcrypt/appveyor.yml b/backend/node_modules/bcrypt/appveyor.yml index 795d3f6..d9b4ebb 100644 --- a/backend/node_modules/bcrypt/appveyor.yml +++ b/backend/node_modules/bcrypt/appveyor.yml @@ -1,39 +1,39 @@ -environment: - matrix: - - nodejs_version: "14" - platform: x64 - - nodejs_version: "14" - platform: x86 - - nodejs_version: "16" - platform: x64 - - nodejs_version: "16" - platform: x86 - - nodejs_version: "18" - platform: x64 - -install: - - where npm - - where node - - ps: Install-Product node $env:nodejs_version $env:platform - -build: off - -artifacts: - - path: 'build/stage/**/bcrypt*.tar.gz' - -test_script: - - node --version - - npm --version - - npm test - -after_test: - - .\node_modules\.bin\node-pre-gyp package - -on_success: - - ps: > - if ($env:NODE_PRE_GYP_GITHUB_TOKEN -ne $null -and $env:APPVEYOR_REPO_TAG_NAME -match '^v(0|[1-9]+)\.(0|[1-9]+)\.(0|[1-9]+)(-\w)?$') { - echo "Publishing $env:APPVEYOR_REPO_TAG_NAME" - npm install node-pre-gyp-github@1.4.3 - ./node_modules/.bin/node-pre-gyp-github publish --release - } - +environment: + matrix: + - nodejs_version: "14" + platform: x64 + - nodejs_version: "14" + platform: x86 + - nodejs_version: "16" + platform: x64 + - nodejs_version: "16" + platform: x86 + - nodejs_version: "18" + platform: x64 + +install: + - where npm + - where node + - ps: Install-Product node $env:nodejs_version $env:platform + +build: off + +artifacts: + - path: 'build/stage/**/bcrypt*.tar.gz' + +test_script: + - node --version + - npm --version + - npm test + +after_test: + - .\node_modules\.bin\node-pre-gyp package + +on_success: + - ps: > + if ($env:NODE_PRE_GYP_GITHUB_TOKEN -ne $null -and $env:APPVEYOR_REPO_TAG_NAME -match '^v(0|[1-9]+)\.(0|[1-9]+)\.(0|[1-9]+)(-\w)?$') { + echo "Publishing $env:APPVEYOR_REPO_TAG_NAME" + npm install node-pre-gyp-github@1.4.3 + ./node_modules/.bin/node-pre-gyp-github publish --release + } + diff --git a/backend/node_modules/bcrypt/lib/binding/napi-v3/bcrypt_lib.node b/backend/node_modules/bcrypt/lib/binding/napi-v3/bcrypt_lib.node old mode 100644 new mode 100755 index ba87d28..74302ae Binary files a/backend/node_modules/bcrypt/lib/binding/napi-v3/bcrypt_lib.node and b/backend/node_modules/bcrypt/lib/binding/napi-v3/bcrypt_lib.node differ diff --git a/backend/node_modules/bcrypt/test-docker.sh b/backend/node_modules/bcrypt/test-docker.sh old mode 100644 new mode 100755 diff --git a/backend/node_modules/color-support/bin.js b/backend/node_modules/color-support/bin.js old mode 100644 new mode 100755 diff --git a/backend/node_modules/make-dir/node_modules/.bin/semver b/backend/node_modules/make-dir/node_modules/.bin/semver deleted file mode 100644 index 97c5327..0000000 --- a/backend/node_modules/make-dir/node_modules/.bin/semver +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") - -case `uname` in - *CYGWIN*|*MINGW*|*MSYS*) - if command -v cygpath > /dev/null 2>&1; then - basedir=`cygpath -w "$basedir"` - fi - ;; -esac - -if [ -x "$basedir/node" ]; then - exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@" -else - exec node "$basedir/../semver/bin/semver.js" "$@" -fi diff --git a/backend/node_modules/make-dir/node_modules/.bin/semver b/backend/node_modules/make-dir/node_modules/.bin/semver new file mode 120000 index 0000000..5aaadf4 --- /dev/null +++ b/backend/node_modules/make-dir/node_modules/.bin/semver @@ -0,0 +1 @@ +../semver/bin/semver.js \ No newline at end of file diff --git a/backend/node_modules/make-dir/node_modules/.bin/semver.cmd b/backend/node_modules/make-dir/node_modules/.bin/semver.cmd deleted file mode 100644 index 9913fa9..0000000 --- a/backend/node_modules/make-dir/node_modules/.bin/semver.cmd +++ /dev/null @@ -1,17 +0,0 @@ -@ECHO off -GOTO start -:find_dp0 -SET dp0=%~dp0 -EXIT /b -:start -SETLOCAL -CALL :find_dp0 - -IF EXIST "%dp0%\node.exe" ( - SET "_prog=%dp0%\node.exe" -) ELSE ( - SET "_prog=node" - SET PATHEXT=%PATHEXT:;.JS;=;% -) - -endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\semver\bin\semver.js" %* diff --git a/backend/node_modules/make-dir/node_modules/.bin/semver.ps1 b/backend/node_modules/make-dir/node_modules/.bin/semver.ps1 deleted file mode 100644 index 314717a..0000000 --- a/backend/node_modules/make-dir/node_modules/.bin/semver.ps1 +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env pwsh -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent - -$exe="" -if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { - # Fix case when both the Windows and Linux builds of Node - # are installed in the same directory - $exe=".exe" -} -$ret=0 -if (Test-Path "$basedir/node$exe") { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args - } else { - & "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args - } - $ret=$LASTEXITCODE -} else { - # Support pipeline input - if ($MyInvocation.ExpectingInput) { - $input | & "node$exe" "$basedir/../semver/bin/semver.js" $args - } else { - & "node$exe" "$basedir/../semver/bin/semver.js" $args - } - $ret=$LASTEXITCODE -} -exit $ret diff --git a/backend/node_modules/make-dir/node_modules/semver/bin/semver.js b/backend/node_modules/make-dir/node_modules/semver/bin/semver.js old mode 100644 new mode 100755 diff --git a/backend/node_modules/mime/cli.js b/backend/node_modules/mime/cli.js old mode 100644 new mode 100755 diff --git a/backend/node_modules/mime/src/build.js b/backend/node_modules/mime/src/build.js old mode 100644 new mode 100755 diff --git a/backend/node_modules/mkdirp/bin/cmd.js b/backend/node_modules/mkdirp/bin/cmd.js old mode 100644 new mode 100755 diff --git a/backend/node_modules/node-addon-api/tools/conversion.js b/backend/node_modules/node-addon-api/tools/conversion.js old mode 100644 new mode 100755 diff --git a/backend/node_modules/nodemon/bin/nodemon.js b/backend/node_modules/nodemon/bin/nodemon.js old mode 100644 new mode 100755 diff --git a/backend/node_modules/nopt/bin/nopt.js b/backend/node_modules/nopt/bin/nopt.js old mode 100644 new mode 100755 diff --git a/backend/node_modules/rimraf/bin.js b/backend/node_modules/rimraf/bin.js old mode 100644 new mode 100755 diff --git a/backend/node_modules/semver/bin/semver.js b/backend/node_modules/semver/bin/semver.js old mode 100644 new mode 100755 diff --git a/backend/node_modules/sequelize/lib/utils.js b/backend/node_modules/sequelize/lib/utils.js index 4cce60e..bee014e 100644 --- a/backend/node_modules/sequelize/lib/utils.js +++ b/backend/node_modules/sequelize/lib/utils.js @@ -272,17 +272,11 @@ exports.now = now; const TICK_CHAR = "`"; exports.TICK_CHAR = TICK_CHAR; function addTicks(s, tickChar) { - if (typeof s !== 'string') { - return s; - } tickChar = tickChar || TICK_CHAR; return tickChar + removeTicks(s, tickChar) + tickChar; } exports.addTicks = addTicks; function removeTicks(s, tickChar) { - if (typeof s !== 'string') { - return s; - } tickChar = tickChar || TICK_CHAR; return s.replace(new RegExp(tickChar, "g"), ""); } diff --git a/backend/node_modules/simple-update-notifier/build/index.js b/backend/node_modules/simple-update-notifier/build/index.js index 090f9df..d7c3cde 100644 --- a/backend/node_modules/simple-update-notifier/build/index.js +++ b/backend/node_modules/simple-update-notifier/build/index.js @@ -7,59 +7,59 @@ var path = require('path'); var fs = require('fs'); var https = require('https'); -/****************************************************************************** -Copyright (c) Microsoft Corporation. - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -***************************************************************************** */ -/* global Reflect, Promise */ - - -function __awaiter(thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -} - -function __generator(thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (g && (g = 0, op[0] && (_ = 0)), _) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } +/****************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ +/* global Reflect, Promise */ + + +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +function __generator(thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } } var packageJson = process$1.env.npm_package_json; diff --git a/backend/node_modules/touch/bin/nodetouch.js b/backend/node_modules/touch/bin/nodetouch.js old mode 100644 new mode 100755 diff --git a/backend/node_modules/uuid/dist/bin/uuid b/backend/node_modules/uuid/dist/bin/uuid old mode 100644 new mode 100755 diff --git a/backend/node_modules/validator/es/lib/isCurrency.js b/backend/node_modules/validator/es/lib/isCurrency.js old mode 100644 new mode 100755 diff --git a/backend/node_modules/validator/es/lib/isVAT.js b/backend/node_modules/validator/es/lib/isVAT.js index 30a2f2d..df83ec7 100644 --- a/backend/node_modules/validator/es/lib/isVAT.js +++ b/backend/node_modules/validator/es/lib/isVAT.js @@ -46,8 +46,8 @@ var PT = function PT(str) { return checksum === parseInt(tin[8], 10); }; export var vatMatchers = { - /** - * European Union VAT identification numbers + /** + * European Union VAT identification numbers */ AT: function AT(str) { return /^(AT)?U\d{8}$/.test(str); @@ -128,8 +128,8 @@ export var vatMatchers = { SE: function SE(str) { return /^(SE)?\d{12}$/.test(str); }, - /** - * VAT numbers of non-EU countries + /** + * VAT numbers of non-EU countries */ AL: function AL(str) { return /^(AL)?\w{9}[A-Z]$/.test(str); @@ -196,8 +196,8 @@ export var vatMatchers = { UZ: function UZ(str) { return /^(UZ)?\d{9}$/.test(str); }, - /** - * VAT numbers of Latin American countries + /** + * VAT numbers of Latin American countries */ AR: function AR(str) { return /^(AR)?\d{11}$/.test(str); diff --git a/backend/node_modules/validator/lib/isCurrency.js b/backend/node_modules/validator/lib/isCurrency.js old mode 100644 new mode 100755 diff --git a/backend/node_modules/validator/lib/isVAT.js b/backend/node_modules/validator/lib/isVAT.js index f4e008c..8d475cb 100644 --- a/backend/node_modules/validator/lib/isVAT.js +++ b/backend/node_modules/validator/lib/isVAT.js @@ -57,8 +57,8 @@ var PT = function PT(str) { return checksum === parseInt(tin[8], 10); }; var vatMatchers = exports.vatMatchers = { - /** - * European Union VAT identification numbers + /** + * European Union VAT identification numbers */ AT: function AT(str) { return /^(AT)?U\d{8}$/.test(str); @@ -139,8 +139,8 @@ var vatMatchers = exports.vatMatchers = { SE: function SE(str) { return /^(SE)?\d{12}$/.test(str); }, - /** - * VAT numbers of non-EU countries + /** + * VAT numbers of non-EU countries */ AL: function AL(str) { return /^(AL)?\w{9}[A-Z]$/.test(str); @@ -207,8 +207,8 @@ var vatMatchers = exports.vatMatchers = { UZ: function UZ(str) { return /^(UZ)?\d{9}$/.test(str); }, - /** - * VAT numbers of Latin American countries + /** + * VAT numbers of Latin American countries */ AR: function AR(str) { return /^(AR)?\d{11}$/.test(str); diff --git a/backend/node_modules/validator/validator.js b/backend/node_modules/validator/validator.js index b01f91f..8b00bd3 100644 --- a/backend/node_modules/validator/validator.js +++ b/backend/node_modules/validator/validator.js @@ -5228,8 +5228,8 @@ var PT = function PT(str) { return checksum === parseInt(tin[8], 10); }; var vatMatchers = { - /** - * European Union VAT identification numbers + /** + * European Union VAT identification numbers */ AT: function AT(str) { return /^(AT)?U\d{8}$/.test(str); @@ -5310,8 +5310,8 @@ var vatMatchers = { SE: function SE(str) { return /^(SE)?\d{12}$/.test(str); }, - /** - * VAT numbers of non-EU countries + /** + * VAT numbers of non-EU countries */ AL: function AL(str) { return /^(AL)?\w{9}[A-Z]$/.test(str); @@ -5378,8 +5378,8 @@ var vatMatchers = { UZ: function UZ(str) { return /^(UZ)?\d{9}$/.test(str); }, - /** - * VAT numbers of Latin American countries + /** + * VAT numbers of Latin American countries */ AR: function AR(str) { return /^(AR)?\d{11}$/.test(str); diff --git a/backend/node_modules/whatwg-url/lib/url-state-machine.js b/backend/node_modules/whatwg-url/lib/url-state-machine.js index 27d977a..c25dbc2 100644 --- a/backend/node_modules/whatwg-url/lib/url-state-machine.js +++ b/backend/node_modules/whatwg-url/lib/url-state-machine.js @@ -1,1297 +1,1297 @@ -"use strict"; -const punycode = require("punycode"); -const tr46 = require("tr46"); - -const specialSchemes = { - ftp: 21, - file: null, - gopher: 70, - http: 80, - https: 443, - ws: 80, - wss: 443 -}; - -const failure = Symbol("failure"); - -function countSymbols(str) { - return punycode.ucs2.decode(str).length; -} - -function at(input, idx) { - const c = input[idx]; - return isNaN(c) ? undefined : String.fromCodePoint(c); -} - -function isASCIIDigit(c) { - return c >= 0x30 && c <= 0x39; -} - -function isASCIIAlpha(c) { - return (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A); -} - -function isASCIIAlphanumeric(c) { - return isASCIIAlpha(c) || isASCIIDigit(c); -} - -function isASCIIHex(c) { - return isASCIIDigit(c) || (c >= 0x41 && c <= 0x46) || (c >= 0x61 && c <= 0x66); -} - -function isSingleDot(buffer) { - return buffer === "." || buffer.toLowerCase() === "%2e"; -} - -function isDoubleDot(buffer) { - buffer = buffer.toLowerCase(); - return buffer === ".." || buffer === "%2e." || buffer === ".%2e" || buffer === "%2e%2e"; -} - -function isWindowsDriveLetterCodePoints(cp1, cp2) { - return isASCIIAlpha(cp1) && (cp2 === 58 || cp2 === 124); -} - -function isWindowsDriveLetterString(string) { - return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && (string[1] === ":" || string[1] === "|"); -} - -function isNormalizedWindowsDriveLetterString(string) { - return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && string[1] === ":"; -} - -function containsForbiddenHostCodePoint(string) { - return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|%|\/|:|\?|@|\[|\\|\]/) !== -1; -} - -function containsForbiddenHostCodePointExcludingPercent(string) { - return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|\/|:|\?|@|\[|\\|\]/) !== -1; -} - -function isSpecialScheme(scheme) { - return specialSchemes[scheme] !== undefined; -} - -function isSpecial(url) { - return isSpecialScheme(url.scheme); -} - -function defaultPort(scheme) { - return specialSchemes[scheme]; -} - -function percentEncode(c) { - let hex = c.toString(16).toUpperCase(); - if (hex.length === 1) { - hex = "0" + hex; - } - - return "%" + hex; -} - -function utf8PercentEncode(c) { - const buf = new Buffer(c); - - let str = ""; - - for (let i = 0; i < buf.length; ++i) { - str += percentEncode(buf[i]); - } - - return str; -} - -function utf8PercentDecode(str) { - const input = new Buffer(str); - const output = []; - for (let i = 0; i < input.length; ++i) { - if (input[i] !== 37) { - output.push(input[i]); - } else if (input[i] === 37 && isASCIIHex(input[i + 1]) && isASCIIHex(input[i + 2])) { - output.push(parseInt(input.slice(i + 1, i + 3).toString(), 16)); - i += 2; - } else { - output.push(input[i]); - } - } - return new Buffer(output).toString(); -} - -function isC0ControlPercentEncode(c) { - return c <= 0x1F || c > 0x7E; -} - -const extraPathPercentEncodeSet = new Set([32, 34, 35, 60, 62, 63, 96, 123, 125]); -function isPathPercentEncode(c) { - return isC0ControlPercentEncode(c) || extraPathPercentEncodeSet.has(c); -} - -const extraUserinfoPercentEncodeSet = - new Set([47, 58, 59, 61, 64, 91, 92, 93, 94, 124]); -function isUserinfoPercentEncode(c) { - return isPathPercentEncode(c) || extraUserinfoPercentEncodeSet.has(c); -} - -function percentEncodeChar(c, encodeSetPredicate) { - const cStr = String.fromCodePoint(c); - - if (encodeSetPredicate(c)) { - return utf8PercentEncode(cStr); - } - - return cStr; -} - -function parseIPv4Number(input) { - let R = 10; - - if (input.length >= 2 && input.charAt(0) === "0" && input.charAt(1).toLowerCase() === "x") { - input = input.substring(2); - R = 16; - } else if (input.length >= 2 && input.charAt(0) === "0") { - input = input.substring(1); - R = 8; - } - - if (input === "") { - return 0; - } - - const regex = R === 10 ? /[^0-9]/ : (R === 16 ? /[^0-9A-Fa-f]/ : /[^0-7]/); - if (regex.test(input)) { - return failure; - } - - return parseInt(input, R); -} - -function parseIPv4(input) { - const parts = input.split("."); - if (parts[parts.length - 1] === "") { - if (parts.length > 1) { - parts.pop(); - } - } - - if (parts.length > 4) { - return input; - } - - const numbers = []; - for (const part of parts) { - if (part === "") { - return input; - } - const n = parseIPv4Number(part); - if (n === failure) { - return input; - } - - numbers.push(n); - } - - for (let i = 0; i < numbers.length - 1; ++i) { - if (numbers[i] > 255) { - return failure; - } - } - if (numbers[numbers.length - 1] >= Math.pow(256, 5 - numbers.length)) { - return failure; - } - - let ipv4 = numbers.pop(); - let counter = 0; - - for (const n of numbers) { - ipv4 += n * Math.pow(256, 3 - counter); - ++counter; - } - - return ipv4; -} - -function serializeIPv4(address) { - let output = ""; - let n = address; - - for (let i = 1; i <= 4; ++i) { - output = String(n % 256) + output; - if (i !== 4) { - output = "." + output; - } - n = Math.floor(n / 256); - } - - return output; -} - -function parseIPv6(input) { - const address = [0, 0, 0, 0, 0, 0, 0, 0]; - let pieceIndex = 0; - let compress = null; - let pointer = 0; - - input = punycode.ucs2.decode(input); - - if (input[pointer] === 58) { - if (input[pointer + 1] !== 58) { - return failure; - } - - pointer += 2; - ++pieceIndex; - compress = pieceIndex; - } - - while (pointer < input.length) { - if (pieceIndex === 8) { - return failure; - } - - if (input[pointer] === 58) { - if (compress !== null) { - return failure; - } - ++pointer; - ++pieceIndex; - compress = pieceIndex; - continue; - } - - let value = 0; - let length = 0; - - while (length < 4 && isASCIIHex(input[pointer])) { - value = value * 0x10 + parseInt(at(input, pointer), 16); - ++pointer; - ++length; - } - - if (input[pointer] === 46) { - if (length === 0) { - return failure; - } - - pointer -= length; - - if (pieceIndex > 6) { - return failure; - } - - let numbersSeen = 0; - - while (input[pointer] !== undefined) { - let ipv4Piece = null; - - if (numbersSeen > 0) { - if (input[pointer] === 46 && numbersSeen < 4) { - ++pointer; - } else { - return failure; - } - } - - if (!isASCIIDigit(input[pointer])) { - return failure; - } - - while (isASCIIDigit(input[pointer])) { - const number = parseInt(at(input, pointer)); - if (ipv4Piece === null) { - ipv4Piece = number; - } else if (ipv4Piece === 0) { - return failure; - } else { - ipv4Piece = ipv4Piece * 10 + number; - } - if (ipv4Piece > 255) { - return failure; - } - ++pointer; - } - - address[pieceIndex] = address[pieceIndex] * 0x100 + ipv4Piece; - - ++numbersSeen; - - if (numbersSeen === 2 || numbersSeen === 4) { - ++pieceIndex; - } - } - - if (numbersSeen !== 4) { - return failure; - } - - break; - } else if (input[pointer] === 58) { - ++pointer; - if (input[pointer] === undefined) { - return failure; - } - } else if (input[pointer] !== undefined) { - return failure; - } - - address[pieceIndex] = value; - ++pieceIndex; - } - - if (compress !== null) { - let swaps = pieceIndex - compress; - pieceIndex = 7; - while (pieceIndex !== 0 && swaps > 0) { - const temp = address[compress + swaps - 1]; - address[compress + swaps - 1] = address[pieceIndex]; - address[pieceIndex] = temp; - --pieceIndex; - --swaps; - } - } else if (compress === null && pieceIndex !== 8) { - return failure; - } - - return address; -} - -function serializeIPv6(address) { - let output = ""; - const seqResult = findLongestZeroSequence(address); - const compress = seqResult.idx; - let ignore0 = false; - - for (let pieceIndex = 0; pieceIndex <= 7; ++pieceIndex) { - if (ignore0 && address[pieceIndex] === 0) { - continue; - } else if (ignore0) { - ignore0 = false; - } - - if (compress === pieceIndex) { - const separator = pieceIndex === 0 ? "::" : ":"; - output += separator; - ignore0 = true; - continue; - } - - output += address[pieceIndex].toString(16); - - if (pieceIndex !== 7) { - output += ":"; - } - } - - return output; -} - -function parseHost(input, isSpecialArg) { - if (input[0] === "[") { - if (input[input.length - 1] !== "]") { - return failure; - } - - return parseIPv6(input.substring(1, input.length - 1)); - } - - if (!isSpecialArg) { - return parseOpaqueHost(input); - } - - const domain = utf8PercentDecode(input); - const asciiDomain = tr46.toASCII(domain, false, tr46.PROCESSING_OPTIONS.NONTRANSITIONAL, false); - if (asciiDomain === null) { - return failure; - } - - if (containsForbiddenHostCodePoint(asciiDomain)) { - return failure; - } - - const ipv4Host = parseIPv4(asciiDomain); - if (typeof ipv4Host === "number" || ipv4Host === failure) { - return ipv4Host; - } - - return asciiDomain; -} - -function parseOpaqueHost(input) { - if (containsForbiddenHostCodePointExcludingPercent(input)) { - return failure; - } - - let output = ""; - const decoded = punycode.ucs2.decode(input); - for (let i = 0; i < decoded.length; ++i) { - output += percentEncodeChar(decoded[i], isC0ControlPercentEncode); - } - return output; -} - -function findLongestZeroSequence(arr) { - let maxIdx = null; - let maxLen = 1; // only find elements > 1 - let currStart = null; - let currLen = 0; - - for (let i = 0; i < arr.length; ++i) { - if (arr[i] !== 0) { - if (currLen > maxLen) { - maxIdx = currStart; - maxLen = currLen; - } - - currStart = null; - currLen = 0; - } else { - if (currStart === null) { - currStart = i; - } - ++currLen; - } - } - - // if trailing zeros - if (currLen > maxLen) { - maxIdx = currStart; - maxLen = currLen; - } - - return { - idx: maxIdx, - len: maxLen - }; -} - -function serializeHost(host) { - if (typeof host === "number") { - return serializeIPv4(host); - } - - // IPv6 serializer - if (host instanceof Array) { - return "[" + serializeIPv6(host) + "]"; - } - - return host; -} - -function trimControlChars(url) { - return url.replace(/^[\u0000-\u001F\u0020]+|[\u0000-\u001F\u0020]+$/g, ""); -} - -function trimTabAndNewline(url) { - return url.replace(/\u0009|\u000A|\u000D/g, ""); -} - -function shortenPath(url) { - const path = url.path; - if (path.length === 0) { - return; - } - if (url.scheme === "file" && path.length === 1 && isNormalizedWindowsDriveLetter(path[0])) { - return; - } - - path.pop(); -} - -function includesCredentials(url) { - return url.username !== "" || url.password !== ""; -} - -function cannotHaveAUsernamePasswordPort(url) { - return url.host === null || url.host === "" || url.cannotBeABaseURL || url.scheme === "file"; -} - -function isNormalizedWindowsDriveLetter(string) { - return /^[A-Za-z]:$/.test(string); -} - -function URLStateMachine(input, base, encodingOverride, url, stateOverride) { - this.pointer = 0; - this.input = input; - this.base = base || null; - this.encodingOverride = encodingOverride || "utf-8"; - this.stateOverride = stateOverride; - this.url = url; - this.failure = false; - this.parseError = false; - - if (!this.url) { - this.url = { - scheme: "", - username: "", - password: "", - host: null, - port: null, - path: [], - query: null, - fragment: null, - - cannotBeABaseURL: false - }; - - const res = trimControlChars(this.input); - if (res !== this.input) { - this.parseError = true; - } - this.input = res; - } - - const res = trimTabAndNewline(this.input); - if (res !== this.input) { - this.parseError = true; - } - this.input = res; - - this.state = stateOverride || "scheme start"; - - this.buffer = ""; - this.atFlag = false; - this.arrFlag = false; - this.passwordTokenSeenFlag = false; - - this.input = punycode.ucs2.decode(this.input); - - for (; this.pointer <= this.input.length; ++this.pointer) { - const c = this.input[this.pointer]; - const cStr = isNaN(c) ? undefined : String.fromCodePoint(c); - - // exec state machine - const ret = this["parse " + this.state](c, cStr); - if (!ret) { - break; // terminate algorithm - } else if (ret === failure) { - this.failure = true; - break; - } - } -} - -URLStateMachine.prototype["parse scheme start"] = function parseSchemeStart(c, cStr) { - if (isASCIIAlpha(c)) { - this.buffer += cStr.toLowerCase(); - this.state = "scheme"; - } else if (!this.stateOverride) { - this.state = "no scheme"; - --this.pointer; - } else { - this.parseError = true; - return failure; - } - - return true; -}; - -URLStateMachine.prototype["parse scheme"] = function parseScheme(c, cStr) { - if (isASCIIAlphanumeric(c) || c === 43 || c === 45 || c === 46) { - this.buffer += cStr.toLowerCase(); - } else if (c === 58) { - if (this.stateOverride) { - if (isSpecial(this.url) && !isSpecialScheme(this.buffer)) { - return false; - } - - if (!isSpecial(this.url) && isSpecialScheme(this.buffer)) { - return false; - } - - if ((includesCredentials(this.url) || this.url.port !== null) && this.buffer === "file") { - return false; - } - - if (this.url.scheme === "file" && (this.url.host === "" || this.url.host === null)) { - return false; - } - } - this.url.scheme = this.buffer; - this.buffer = ""; - if (this.stateOverride) { - return false; - } - if (this.url.scheme === "file") { - if (this.input[this.pointer + 1] !== 47 || this.input[this.pointer + 2] !== 47) { - this.parseError = true; - } - this.state = "file"; - } else if (isSpecial(this.url) && this.base !== null && this.base.scheme === this.url.scheme) { - this.state = "special relative or authority"; - } else if (isSpecial(this.url)) { - this.state = "special authority slashes"; - } else if (this.input[this.pointer + 1] === 47) { - this.state = "path or authority"; - ++this.pointer; - } else { - this.url.cannotBeABaseURL = true; - this.url.path.push(""); - this.state = "cannot-be-a-base-URL path"; - } - } else if (!this.stateOverride) { - this.buffer = ""; - this.state = "no scheme"; - this.pointer = -1; - } else { - this.parseError = true; - return failure; - } - - return true; -}; - -URLStateMachine.prototype["parse no scheme"] = function parseNoScheme(c) { - if (this.base === null || (this.base.cannotBeABaseURL && c !== 35)) { - return failure; - } else if (this.base.cannotBeABaseURL && c === 35) { - this.url.scheme = this.base.scheme; - this.url.path = this.base.path.slice(); - this.url.query = this.base.query; - this.url.fragment = ""; - this.url.cannotBeABaseURL = true; - this.state = "fragment"; - } else if (this.base.scheme === "file") { - this.state = "file"; - --this.pointer; - } else { - this.state = "relative"; - --this.pointer; - } - - return true; -}; - -URLStateMachine.prototype["parse special relative or authority"] = function parseSpecialRelativeOrAuthority(c) { - if (c === 47 && this.input[this.pointer + 1] === 47) { - this.state = "special authority ignore slashes"; - ++this.pointer; - } else { - this.parseError = true; - this.state = "relative"; - --this.pointer; - } - - return true; -}; - -URLStateMachine.prototype["parse path or authority"] = function parsePathOrAuthority(c) { - if (c === 47) { - this.state = "authority"; - } else { - this.state = "path"; - --this.pointer; - } - - return true; -}; - -URLStateMachine.prototype["parse relative"] = function parseRelative(c) { - this.url.scheme = this.base.scheme; - if (isNaN(c)) { - this.url.username = this.base.username; - this.url.password = this.base.password; - this.url.host = this.base.host; - this.url.port = this.base.port; - this.url.path = this.base.path.slice(); - this.url.query = this.base.query; - } else if (c === 47) { - this.state = "relative slash"; - } else if (c === 63) { - this.url.username = this.base.username; - this.url.password = this.base.password; - this.url.host = this.base.host; - this.url.port = this.base.port; - this.url.path = this.base.path.slice(); - this.url.query = ""; - this.state = "query"; - } else if (c === 35) { - this.url.username = this.base.username; - this.url.password = this.base.password; - this.url.host = this.base.host; - this.url.port = this.base.port; - this.url.path = this.base.path.slice(); - this.url.query = this.base.query; - this.url.fragment = ""; - this.state = "fragment"; - } else if (isSpecial(this.url) && c === 92) { - this.parseError = true; - this.state = "relative slash"; - } else { - this.url.username = this.base.username; - this.url.password = this.base.password; - this.url.host = this.base.host; - this.url.port = this.base.port; - this.url.path = this.base.path.slice(0, this.base.path.length - 1); - - this.state = "path"; - --this.pointer; - } - - return true; -}; - -URLStateMachine.prototype["parse relative slash"] = function parseRelativeSlash(c) { - if (isSpecial(this.url) && (c === 47 || c === 92)) { - if (c === 92) { - this.parseError = true; - } - this.state = "special authority ignore slashes"; - } else if (c === 47) { - this.state = "authority"; - } else { - this.url.username = this.base.username; - this.url.password = this.base.password; - this.url.host = this.base.host; - this.url.port = this.base.port; - this.state = "path"; - --this.pointer; - } - - return true; -}; - -URLStateMachine.prototype["parse special authority slashes"] = function parseSpecialAuthoritySlashes(c) { - if (c === 47 && this.input[this.pointer + 1] === 47) { - this.state = "special authority ignore slashes"; - ++this.pointer; - } else { - this.parseError = true; - this.state = "special authority ignore slashes"; - --this.pointer; - } - - return true; -}; - -URLStateMachine.prototype["parse special authority ignore slashes"] = function parseSpecialAuthorityIgnoreSlashes(c) { - if (c !== 47 && c !== 92) { - this.state = "authority"; - --this.pointer; - } else { - this.parseError = true; - } - - return true; -}; - -URLStateMachine.prototype["parse authority"] = function parseAuthority(c, cStr) { - if (c === 64) { - this.parseError = true; - if (this.atFlag) { - this.buffer = "%40" + this.buffer; - } - this.atFlag = true; - - // careful, this is based on buffer and has its own pointer (this.pointer != pointer) and inner chars - const len = countSymbols(this.buffer); - for (let pointer = 0; pointer < len; ++pointer) { - const codePoint = this.buffer.codePointAt(pointer); - - if (codePoint === 58 && !this.passwordTokenSeenFlag) { - this.passwordTokenSeenFlag = true; - continue; - } - const encodedCodePoints = percentEncodeChar(codePoint, isUserinfoPercentEncode); - if (this.passwordTokenSeenFlag) { - this.url.password += encodedCodePoints; - } else { - this.url.username += encodedCodePoints; - } - } - this.buffer = ""; - } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || - (isSpecial(this.url) && c === 92)) { - if (this.atFlag && this.buffer === "") { - this.parseError = true; - return failure; - } - this.pointer -= countSymbols(this.buffer) + 1; - this.buffer = ""; - this.state = "host"; - } else { - this.buffer += cStr; - } - - return true; -}; - -URLStateMachine.prototype["parse hostname"] = -URLStateMachine.prototype["parse host"] = function parseHostName(c, cStr) { - if (this.stateOverride && this.url.scheme === "file") { - --this.pointer; - this.state = "file host"; - } else if (c === 58 && !this.arrFlag) { - if (this.buffer === "") { - this.parseError = true; - return failure; - } - - const host = parseHost(this.buffer, isSpecial(this.url)); - if (host === failure) { - return failure; - } - - this.url.host = host; - this.buffer = ""; - this.state = "port"; - if (this.stateOverride === "hostname") { - return false; - } - } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || - (isSpecial(this.url) && c === 92)) { - --this.pointer; - if (isSpecial(this.url) && this.buffer === "") { - this.parseError = true; - return failure; - } else if (this.stateOverride && this.buffer === "" && - (includesCredentials(this.url) || this.url.port !== null)) { - this.parseError = true; - return false; - } - - const host = parseHost(this.buffer, isSpecial(this.url)); - if (host === failure) { - return failure; - } - - this.url.host = host; - this.buffer = ""; - this.state = "path start"; - if (this.stateOverride) { - return false; - } - } else { - if (c === 91) { - this.arrFlag = true; - } else if (c === 93) { - this.arrFlag = false; - } - this.buffer += cStr; - } - - return true; -}; - -URLStateMachine.prototype["parse port"] = function parsePort(c, cStr) { - if (isASCIIDigit(c)) { - this.buffer += cStr; - } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || - (isSpecial(this.url) && c === 92) || - this.stateOverride) { - if (this.buffer !== "") { - const port = parseInt(this.buffer); - if (port > Math.pow(2, 16) - 1) { - this.parseError = true; - return failure; - } - this.url.port = port === defaultPort(this.url.scheme) ? null : port; - this.buffer = ""; - } - if (this.stateOverride) { - return false; - } - this.state = "path start"; - --this.pointer; - } else { - this.parseError = true; - return failure; - } - - return true; -}; - -const fileOtherwiseCodePoints = new Set([47, 92, 63, 35]); - -URLStateMachine.prototype["parse file"] = function parseFile(c) { - this.url.scheme = "file"; - - if (c === 47 || c === 92) { - if (c === 92) { - this.parseError = true; - } - this.state = "file slash"; - } else if (this.base !== null && this.base.scheme === "file") { - if (isNaN(c)) { - this.url.host = this.base.host; - this.url.path = this.base.path.slice(); - this.url.query = this.base.query; - } else if (c === 63) { - this.url.host = this.base.host; - this.url.path = this.base.path.slice(); - this.url.query = ""; - this.state = "query"; - } else if (c === 35) { - this.url.host = this.base.host; - this.url.path = this.base.path.slice(); - this.url.query = this.base.query; - this.url.fragment = ""; - this.state = "fragment"; - } else { - if (this.input.length - this.pointer - 1 === 0 || // remaining consists of 0 code points - !isWindowsDriveLetterCodePoints(c, this.input[this.pointer + 1]) || - (this.input.length - this.pointer - 1 >= 2 && // remaining has at least 2 code points - !fileOtherwiseCodePoints.has(this.input[this.pointer + 2]))) { - this.url.host = this.base.host; - this.url.path = this.base.path.slice(); - shortenPath(this.url); - } else { - this.parseError = true; - } - - this.state = "path"; - --this.pointer; - } - } else { - this.state = "path"; - --this.pointer; - } - - return true; -}; - -URLStateMachine.prototype["parse file slash"] = function parseFileSlash(c) { - if (c === 47 || c === 92) { - if (c === 92) { - this.parseError = true; - } - this.state = "file host"; - } else { - if (this.base !== null && this.base.scheme === "file") { - if (isNormalizedWindowsDriveLetterString(this.base.path[0])) { - this.url.path.push(this.base.path[0]); - } else { - this.url.host = this.base.host; - } - } - this.state = "path"; - --this.pointer; - } - - return true; -}; - -URLStateMachine.prototype["parse file host"] = function parseFileHost(c, cStr) { - if (isNaN(c) || c === 47 || c === 92 || c === 63 || c === 35) { - --this.pointer; - if (!this.stateOverride && isWindowsDriveLetterString(this.buffer)) { - this.parseError = true; - this.state = "path"; - } else if (this.buffer === "") { - this.url.host = ""; - if (this.stateOverride) { - return false; - } - this.state = "path start"; - } else { - let host = parseHost(this.buffer, isSpecial(this.url)); - if (host === failure) { - return failure; - } - if (host === "localhost") { - host = ""; - } - this.url.host = host; - - if (this.stateOverride) { - return false; - } - - this.buffer = ""; - this.state = "path start"; - } - } else { - this.buffer += cStr; - } - - return true; -}; - -URLStateMachine.prototype["parse path start"] = function parsePathStart(c) { - if (isSpecial(this.url)) { - if (c === 92) { - this.parseError = true; - } - this.state = "path"; - - if (c !== 47 && c !== 92) { - --this.pointer; - } - } else if (!this.stateOverride && c === 63) { - this.url.query = ""; - this.state = "query"; - } else if (!this.stateOverride && c === 35) { - this.url.fragment = ""; - this.state = "fragment"; - } else if (c !== undefined) { - this.state = "path"; - if (c !== 47) { - --this.pointer; - } - } - - return true; -}; - -URLStateMachine.prototype["parse path"] = function parsePath(c) { - if (isNaN(c) || c === 47 || (isSpecial(this.url) && c === 92) || - (!this.stateOverride && (c === 63 || c === 35))) { - if (isSpecial(this.url) && c === 92) { - this.parseError = true; - } - - if (isDoubleDot(this.buffer)) { - shortenPath(this.url); - if (c !== 47 && !(isSpecial(this.url) && c === 92)) { - this.url.path.push(""); - } - } else if (isSingleDot(this.buffer) && c !== 47 && - !(isSpecial(this.url) && c === 92)) { - this.url.path.push(""); - } else if (!isSingleDot(this.buffer)) { - if (this.url.scheme === "file" && this.url.path.length === 0 && isWindowsDriveLetterString(this.buffer)) { - if (this.url.host !== "" && this.url.host !== null) { - this.parseError = true; - this.url.host = ""; - } - this.buffer = this.buffer[0] + ":"; - } - this.url.path.push(this.buffer); - } - this.buffer = ""; - if (this.url.scheme === "file" && (c === undefined || c === 63 || c === 35)) { - while (this.url.path.length > 1 && this.url.path[0] === "") { - this.parseError = true; - this.url.path.shift(); - } - } - if (c === 63) { - this.url.query = ""; - this.state = "query"; - } - if (c === 35) { - this.url.fragment = ""; - this.state = "fragment"; - } - } else { - // TODO: If c is not a URL code point and not "%", parse error. - - if (c === 37 && - (!isASCIIHex(this.input[this.pointer + 1]) || - !isASCIIHex(this.input[this.pointer + 2]))) { - this.parseError = true; - } - - this.buffer += percentEncodeChar(c, isPathPercentEncode); - } - - return true; -}; - -URLStateMachine.prototype["parse cannot-be-a-base-URL path"] = function parseCannotBeABaseURLPath(c) { - if (c === 63) { - this.url.query = ""; - this.state = "query"; - } else if (c === 35) { - this.url.fragment = ""; - this.state = "fragment"; - } else { - // TODO: Add: not a URL code point - if (!isNaN(c) && c !== 37) { - this.parseError = true; - } - - if (c === 37 && - (!isASCIIHex(this.input[this.pointer + 1]) || - !isASCIIHex(this.input[this.pointer + 2]))) { - this.parseError = true; - } - - if (!isNaN(c)) { - this.url.path[0] = this.url.path[0] + percentEncodeChar(c, isC0ControlPercentEncode); - } - } - - return true; -}; - -URLStateMachine.prototype["parse query"] = function parseQuery(c, cStr) { - if (isNaN(c) || (!this.stateOverride && c === 35)) { - if (!isSpecial(this.url) || this.url.scheme === "ws" || this.url.scheme === "wss") { - this.encodingOverride = "utf-8"; - } - - const buffer = new Buffer(this.buffer); // TODO: Use encoding override instead - for (let i = 0; i < buffer.length; ++i) { - if (buffer[i] < 0x21 || buffer[i] > 0x7E || buffer[i] === 0x22 || buffer[i] === 0x23 || - buffer[i] === 0x3C || buffer[i] === 0x3E) { - this.url.query += percentEncode(buffer[i]); - } else { - this.url.query += String.fromCodePoint(buffer[i]); - } - } - - this.buffer = ""; - if (c === 35) { - this.url.fragment = ""; - this.state = "fragment"; - } - } else { - // TODO: If c is not a URL code point and not "%", parse error. - if (c === 37 && - (!isASCIIHex(this.input[this.pointer + 1]) || - !isASCIIHex(this.input[this.pointer + 2]))) { - this.parseError = true; - } - - this.buffer += cStr; - } - - return true; -}; - -URLStateMachine.prototype["parse fragment"] = function parseFragment(c) { - if (isNaN(c)) { // do nothing - } else if (c === 0x0) { - this.parseError = true; - } else { - // TODO: If c is not a URL code point and not "%", parse error. - if (c === 37 && - (!isASCIIHex(this.input[this.pointer + 1]) || - !isASCIIHex(this.input[this.pointer + 2]))) { - this.parseError = true; - } - - this.url.fragment += percentEncodeChar(c, isC0ControlPercentEncode); - } - - return true; -}; - -function serializeURL(url, excludeFragment) { - let output = url.scheme + ":"; - if (url.host !== null) { - output += "//"; - - if (url.username !== "" || url.password !== "") { - output += url.username; - if (url.password !== "") { - output += ":" + url.password; - } - output += "@"; - } - - output += serializeHost(url.host); - - if (url.port !== null) { - output += ":" + url.port; - } - } else if (url.host === null && url.scheme === "file") { - output += "//"; - } - - if (url.cannotBeABaseURL) { - output += url.path[0]; - } else { - for (const string of url.path) { - output += "/" + string; - } - } - - if (url.query !== null) { - output += "?" + url.query; - } - - if (!excludeFragment && url.fragment !== null) { - output += "#" + url.fragment; - } - - return output; -} - -function serializeOrigin(tuple) { - let result = tuple.scheme + "://"; - result += serializeHost(tuple.host); - - if (tuple.port !== null) { - result += ":" + tuple.port; - } - - return result; -} - -module.exports.serializeURL = serializeURL; - -module.exports.serializeURLOrigin = function (url) { - // https://url.spec.whatwg.org/#concept-url-origin - switch (url.scheme) { - case "blob": - try { - return module.exports.serializeURLOrigin(module.exports.parseURL(url.path[0])); - } catch (e) { - // serializing an opaque origin returns "null" - return "null"; - } - case "ftp": - case "gopher": - case "http": - case "https": - case "ws": - case "wss": - return serializeOrigin({ - scheme: url.scheme, - host: url.host, - port: url.port - }); - case "file": - // spec says "exercise to the reader", chrome says "file://" - return "file://"; - default: - // serializing an opaque origin returns "null" - return "null"; - } -}; - -module.exports.basicURLParse = function (input, options) { - if (options === undefined) { - options = {}; - } - - const usm = new URLStateMachine(input, options.baseURL, options.encodingOverride, options.url, options.stateOverride); - if (usm.failure) { - return "failure"; - } - - return usm.url; -}; - -module.exports.setTheUsername = function (url, username) { - url.username = ""; - const decoded = punycode.ucs2.decode(username); - for (let i = 0; i < decoded.length; ++i) { - url.username += percentEncodeChar(decoded[i], isUserinfoPercentEncode); - } -}; - -module.exports.setThePassword = function (url, password) { - url.password = ""; - const decoded = punycode.ucs2.decode(password); - for (let i = 0; i < decoded.length; ++i) { - url.password += percentEncodeChar(decoded[i], isUserinfoPercentEncode); - } -}; - -module.exports.serializeHost = serializeHost; - -module.exports.cannotHaveAUsernamePasswordPort = cannotHaveAUsernamePasswordPort; - -module.exports.serializeInteger = function (integer) { - return String(integer); -}; - -module.exports.parseURL = function (input, options) { - if (options === undefined) { - options = {}; - } - - // We don't handle blobs, so this just delegates: - return module.exports.basicURLParse(input, { baseURL: options.baseURL, encodingOverride: options.encodingOverride }); -}; +"use strict"; +const punycode = require("punycode"); +const tr46 = require("tr46"); + +const specialSchemes = { + ftp: 21, + file: null, + gopher: 70, + http: 80, + https: 443, + ws: 80, + wss: 443 +}; + +const failure = Symbol("failure"); + +function countSymbols(str) { + return punycode.ucs2.decode(str).length; +} + +function at(input, idx) { + const c = input[idx]; + return isNaN(c) ? undefined : String.fromCodePoint(c); +} + +function isASCIIDigit(c) { + return c >= 0x30 && c <= 0x39; +} + +function isASCIIAlpha(c) { + return (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A); +} + +function isASCIIAlphanumeric(c) { + return isASCIIAlpha(c) || isASCIIDigit(c); +} + +function isASCIIHex(c) { + return isASCIIDigit(c) || (c >= 0x41 && c <= 0x46) || (c >= 0x61 && c <= 0x66); +} + +function isSingleDot(buffer) { + return buffer === "." || buffer.toLowerCase() === "%2e"; +} + +function isDoubleDot(buffer) { + buffer = buffer.toLowerCase(); + return buffer === ".." || buffer === "%2e." || buffer === ".%2e" || buffer === "%2e%2e"; +} + +function isWindowsDriveLetterCodePoints(cp1, cp2) { + return isASCIIAlpha(cp1) && (cp2 === 58 || cp2 === 124); +} + +function isWindowsDriveLetterString(string) { + return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && (string[1] === ":" || string[1] === "|"); +} + +function isNormalizedWindowsDriveLetterString(string) { + return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && string[1] === ":"; +} + +function containsForbiddenHostCodePoint(string) { + return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|%|\/|:|\?|@|\[|\\|\]/) !== -1; +} + +function containsForbiddenHostCodePointExcludingPercent(string) { + return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|\/|:|\?|@|\[|\\|\]/) !== -1; +} + +function isSpecialScheme(scheme) { + return specialSchemes[scheme] !== undefined; +} + +function isSpecial(url) { + return isSpecialScheme(url.scheme); +} + +function defaultPort(scheme) { + return specialSchemes[scheme]; +} + +function percentEncode(c) { + let hex = c.toString(16).toUpperCase(); + if (hex.length === 1) { + hex = "0" + hex; + } + + return "%" + hex; +} + +function utf8PercentEncode(c) { + const buf = new Buffer(c); + + let str = ""; + + for (let i = 0; i < buf.length; ++i) { + str += percentEncode(buf[i]); + } + + return str; +} + +function utf8PercentDecode(str) { + const input = new Buffer(str); + const output = []; + for (let i = 0; i < input.length; ++i) { + if (input[i] !== 37) { + output.push(input[i]); + } else if (input[i] === 37 && isASCIIHex(input[i + 1]) && isASCIIHex(input[i + 2])) { + output.push(parseInt(input.slice(i + 1, i + 3).toString(), 16)); + i += 2; + } else { + output.push(input[i]); + } + } + return new Buffer(output).toString(); +} + +function isC0ControlPercentEncode(c) { + return c <= 0x1F || c > 0x7E; +} + +const extraPathPercentEncodeSet = new Set([32, 34, 35, 60, 62, 63, 96, 123, 125]); +function isPathPercentEncode(c) { + return isC0ControlPercentEncode(c) || extraPathPercentEncodeSet.has(c); +} + +const extraUserinfoPercentEncodeSet = + new Set([47, 58, 59, 61, 64, 91, 92, 93, 94, 124]); +function isUserinfoPercentEncode(c) { + return isPathPercentEncode(c) || extraUserinfoPercentEncodeSet.has(c); +} + +function percentEncodeChar(c, encodeSetPredicate) { + const cStr = String.fromCodePoint(c); + + if (encodeSetPredicate(c)) { + return utf8PercentEncode(cStr); + } + + return cStr; +} + +function parseIPv4Number(input) { + let R = 10; + + if (input.length >= 2 && input.charAt(0) === "0" && input.charAt(1).toLowerCase() === "x") { + input = input.substring(2); + R = 16; + } else if (input.length >= 2 && input.charAt(0) === "0") { + input = input.substring(1); + R = 8; + } + + if (input === "") { + return 0; + } + + const regex = R === 10 ? /[^0-9]/ : (R === 16 ? /[^0-9A-Fa-f]/ : /[^0-7]/); + if (regex.test(input)) { + return failure; + } + + return parseInt(input, R); +} + +function parseIPv4(input) { + const parts = input.split("."); + if (parts[parts.length - 1] === "") { + if (parts.length > 1) { + parts.pop(); + } + } + + if (parts.length > 4) { + return input; + } + + const numbers = []; + for (const part of parts) { + if (part === "") { + return input; + } + const n = parseIPv4Number(part); + if (n === failure) { + return input; + } + + numbers.push(n); + } + + for (let i = 0; i < numbers.length - 1; ++i) { + if (numbers[i] > 255) { + return failure; + } + } + if (numbers[numbers.length - 1] >= Math.pow(256, 5 - numbers.length)) { + return failure; + } + + let ipv4 = numbers.pop(); + let counter = 0; + + for (const n of numbers) { + ipv4 += n * Math.pow(256, 3 - counter); + ++counter; + } + + return ipv4; +} + +function serializeIPv4(address) { + let output = ""; + let n = address; + + for (let i = 1; i <= 4; ++i) { + output = String(n % 256) + output; + if (i !== 4) { + output = "." + output; + } + n = Math.floor(n / 256); + } + + return output; +} + +function parseIPv6(input) { + const address = [0, 0, 0, 0, 0, 0, 0, 0]; + let pieceIndex = 0; + let compress = null; + let pointer = 0; + + input = punycode.ucs2.decode(input); + + if (input[pointer] === 58) { + if (input[pointer + 1] !== 58) { + return failure; + } + + pointer += 2; + ++pieceIndex; + compress = pieceIndex; + } + + while (pointer < input.length) { + if (pieceIndex === 8) { + return failure; + } + + if (input[pointer] === 58) { + if (compress !== null) { + return failure; + } + ++pointer; + ++pieceIndex; + compress = pieceIndex; + continue; + } + + let value = 0; + let length = 0; + + while (length < 4 && isASCIIHex(input[pointer])) { + value = value * 0x10 + parseInt(at(input, pointer), 16); + ++pointer; + ++length; + } + + if (input[pointer] === 46) { + if (length === 0) { + return failure; + } + + pointer -= length; + + if (pieceIndex > 6) { + return failure; + } + + let numbersSeen = 0; + + while (input[pointer] !== undefined) { + let ipv4Piece = null; + + if (numbersSeen > 0) { + if (input[pointer] === 46 && numbersSeen < 4) { + ++pointer; + } else { + return failure; + } + } + + if (!isASCIIDigit(input[pointer])) { + return failure; + } + + while (isASCIIDigit(input[pointer])) { + const number = parseInt(at(input, pointer)); + if (ipv4Piece === null) { + ipv4Piece = number; + } else if (ipv4Piece === 0) { + return failure; + } else { + ipv4Piece = ipv4Piece * 10 + number; + } + if (ipv4Piece > 255) { + return failure; + } + ++pointer; + } + + address[pieceIndex] = address[pieceIndex] * 0x100 + ipv4Piece; + + ++numbersSeen; + + if (numbersSeen === 2 || numbersSeen === 4) { + ++pieceIndex; + } + } + + if (numbersSeen !== 4) { + return failure; + } + + break; + } else if (input[pointer] === 58) { + ++pointer; + if (input[pointer] === undefined) { + return failure; + } + } else if (input[pointer] !== undefined) { + return failure; + } + + address[pieceIndex] = value; + ++pieceIndex; + } + + if (compress !== null) { + let swaps = pieceIndex - compress; + pieceIndex = 7; + while (pieceIndex !== 0 && swaps > 0) { + const temp = address[compress + swaps - 1]; + address[compress + swaps - 1] = address[pieceIndex]; + address[pieceIndex] = temp; + --pieceIndex; + --swaps; + } + } else if (compress === null && pieceIndex !== 8) { + return failure; + } + + return address; +} + +function serializeIPv6(address) { + let output = ""; + const seqResult = findLongestZeroSequence(address); + const compress = seqResult.idx; + let ignore0 = false; + + for (let pieceIndex = 0; pieceIndex <= 7; ++pieceIndex) { + if (ignore0 && address[pieceIndex] === 0) { + continue; + } else if (ignore0) { + ignore0 = false; + } + + if (compress === pieceIndex) { + const separator = pieceIndex === 0 ? "::" : ":"; + output += separator; + ignore0 = true; + continue; + } + + output += address[pieceIndex].toString(16); + + if (pieceIndex !== 7) { + output += ":"; + } + } + + return output; +} + +function parseHost(input, isSpecialArg) { + if (input[0] === "[") { + if (input[input.length - 1] !== "]") { + return failure; + } + + return parseIPv6(input.substring(1, input.length - 1)); + } + + if (!isSpecialArg) { + return parseOpaqueHost(input); + } + + const domain = utf8PercentDecode(input); + const asciiDomain = tr46.toASCII(domain, false, tr46.PROCESSING_OPTIONS.NONTRANSITIONAL, false); + if (asciiDomain === null) { + return failure; + } + + if (containsForbiddenHostCodePoint(asciiDomain)) { + return failure; + } + + const ipv4Host = parseIPv4(asciiDomain); + if (typeof ipv4Host === "number" || ipv4Host === failure) { + return ipv4Host; + } + + return asciiDomain; +} + +function parseOpaqueHost(input) { + if (containsForbiddenHostCodePointExcludingPercent(input)) { + return failure; + } + + let output = ""; + const decoded = punycode.ucs2.decode(input); + for (let i = 0; i < decoded.length; ++i) { + output += percentEncodeChar(decoded[i], isC0ControlPercentEncode); + } + return output; +} + +function findLongestZeroSequence(arr) { + let maxIdx = null; + let maxLen = 1; // only find elements > 1 + let currStart = null; + let currLen = 0; + + for (let i = 0; i < arr.length; ++i) { + if (arr[i] !== 0) { + if (currLen > maxLen) { + maxIdx = currStart; + maxLen = currLen; + } + + currStart = null; + currLen = 0; + } else { + if (currStart === null) { + currStart = i; + } + ++currLen; + } + } + + // if trailing zeros + if (currLen > maxLen) { + maxIdx = currStart; + maxLen = currLen; + } + + return { + idx: maxIdx, + len: maxLen + }; +} + +function serializeHost(host) { + if (typeof host === "number") { + return serializeIPv4(host); + } + + // IPv6 serializer + if (host instanceof Array) { + return "[" + serializeIPv6(host) + "]"; + } + + return host; +} + +function trimControlChars(url) { + return url.replace(/^[\u0000-\u001F\u0020]+|[\u0000-\u001F\u0020]+$/g, ""); +} + +function trimTabAndNewline(url) { + return url.replace(/\u0009|\u000A|\u000D/g, ""); +} + +function shortenPath(url) { + const path = url.path; + if (path.length === 0) { + return; + } + if (url.scheme === "file" && path.length === 1 && isNormalizedWindowsDriveLetter(path[0])) { + return; + } + + path.pop(); +} + +function includesCredentials(url) { + return url.username !== "" || url.password !== ""; +} + +function cannotHaveAUsernamePasswordPort(url) { + return url.host === null || url.host === "" || url.cannotBeABaseURL || url.scheme === "file"; +} + +function isNormalizedWindowsDriveLetter(string) { + return /^[A-Za-z]:$/.test(string); +} + +function URLStateMachine(input, base, encodingOverride, url, stateOverride) { + this.pointer = 0; + this.input = input; + this.base = base || null; + this.encodingOverride = encodingOverride || "utf-8"; + this.stateOverride = stateOverride; + this.url = url; + this.failure = false; + this.parseError = false; + + if (!this.url) { + this.url = { + scheme: "", + username: "", + password: "", + host: null, + port: null, + path: [], + query: null, + fragment: null, + + cannotBeABaseURL: false + }; + + const res = trimControlChars(this.input); + if (res !== this.input) { + this.parseError = true; + } + this.input = res; + } + + const res = trimTabAndNewline(this.input); + if (res !== this.input) { + this.parseError = true; + } + this.input = res; + + this.state = stateOverride || "scheme start"; + + this.buffer = ""; + this.atFlag = false; + this.arrFlag = false; + this.passwordTokenSeenFlag = false; + + this.input = punycode.ucs2.decode(this.input); + + for (; this.pointer <= this.input.length; ++this.pointer) { + const c = this.input[this.pointer]; + const cStr = isNaN(c) ? undefined : String.fromCodePoint(c); + + // exec state machine + const ret = this["parse " + this.state](c, cStr); + if (!ret) { + break; // terminate algorithm + } else if (ret === failure) { + this.failure = true; + break; + } + } +} + +URLStateMachine.prototype["parse scheme start"] = function parseSchemeStart(c, cStr) { + if (isASCIIAlpha(c)) { + this.buffer += cStr.toLowerCase(); + this.state = "scheme"; + } else if (!this.stateOverride) { + this.state = "no scheme"; + --this.pointer; + } else { + this.parseError = true; + return failure; + } + + return true; +}; + +URLStateMachine.prototype["parse scheme"] = function parseScheme(c, cStr) { + if (isASCIIAlphanumeric(c) || c === 43 || c === 45 || c === 46) { + this.buffer += cStr.toLowerCase(); + } else if (c === 58) { + if (this.stateOverride) { + if (isSpecial(this.url) && !isSpecialScheme(this.buffer)) { + return false; + } + + if (!isSpecial(this.url) && isSpecialScheme(this.buffer)) { + return false; + } + + if ((includesCredentials(this.url) || this.url.port !== null) && this.buffer === "file") { + return false; + } + + if (this.url.scheme === "file" && (this.url.host === "" || this.url.host === null)) { + return false; + } + } + this.url.scheme = this.buffer; + this.buffer = ""; + if (this.stateOverride) { + return false; + } + if (this.url.scheme === "file") { + if (this.input[this.pointer + 1] !== 47 || this.input[this.pointer + 2] !== 47) { + this.parseError = true; + } + this.state = "file"; + } else if (isSpecial(this.url) && this.base !== null && this.base.scheme === this.url.scheme) { + this.state = "special relative or authority"; + } else if (isSpecial(this.url)) { + this.state = "special authority slashes"; + } else if (this.input[this.pointer + 1] === 47) { + this.state = "path or authority"; + ++this.pointer; + } else { + this.url.cannotBeABaseURL = true; + this.url.path.push(""); + this.state = "cannot-be-a-base-URL path"; + } + } else if (!this.stateOverride) { + this.buffer = ""; + this.state = "no scheme"; + this.pointer = -1; + } else { + this.parseError = true; + return failure; + } + + return true; +}; + +URLStateMachine.prototype["parse no scheme"] = function parseNoScheme(c) { + if (this.base === null || (this.base.cannotBeABaseURL && c !== 35)) { + return failure; + } else if (this.base.cannotBeABaseURL && c === 35) { + this.url.scheme = this.base.scheme; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + this.url.fragment = ""; + this.url.cannotBeABaseURL = true; + this.state = "fragment"; + } else if (this.base.scheme === "file") { + this.state = "file"; + --this.pointer; + } else { + this.state = "relative"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse special relative or authority"] = function parseSpecialRelativeOrAuthority(c) { + if (c === 47 && this.input[this.pointer + 1] === 47) { + this.state = "special authority ignore slashes"; + ++this.pointer; + } else { + this.parseError = true; + this.state = "relative"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse path or authority"] = function parsePathOrAuthority(c) { + if (c === 47) { + this.state = "authority"; + } else { + this.state = "path"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse relative"] = function parseRelative(c) { + this.url.scheme = this.base.scheme; + if (isNaN(c)) { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + } else if (c === 47) { + this.state = "relative slash"; + } else if (c === 63) { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(); + this.url.query = ""; + this.state = "query"; + } else if (c === 35) { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + this.url.fragment = ""; + this.state = "fragment"; + } else if (isSpecial(this.url) && c === 92) { + this.parseError = true; + this.state = "relative slash"; + } else { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(0, this.base.path.length - 1); + + this.state = "path"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse relative slash"] = function parseRelativeSlash(c) { + if (isSpecial(this.url) && (c === 47 || c === 92)) { + if (c === 92) { + this.parseError = true; + } + this.state = "special authority ignore slashes"; + } else if (c === 47) { + this.state = "authority"; + } else { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.state = "path"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse special authority slashes"] = function parseSpecialAuthoritySlashes(c) { + if (c === 47 && this.input[this.pointer + 1] === 47) { + this.state = "special authority ignore slashes"; + ++this.pointer; + } else { + this.parseError = true; + this.state = "special authority ignore slashes"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse special authority ignore slashes"] = function parseSpecialAuthorityIgnoreSlashes(c) { + if (c !== 47 && c !== 92) { + this.state = "authority"; + --this.pointer; + } else { + this.parseError = true; + } + + return true; +}; + +URLStateMachine.prototype["parse authority"] = function parseAuthority(c, cStr) { + if (c === 64) { + this.parseError = true; + if (this.atFlag) { + this.buffer = "%40" + this.buffer; + } + this.atFlag = true; + + // careful, this is based on buffer and has its own pointer (this.pointer != pointer) and inner chars + const len = countSymbols(this.buffer); + for (let pointer = 0; pointer < len; ++pointer) { + const codePoint = this.buffer.codePointAt(pointer); + + if (codePoint === 58 && !this.passwordTokenSeenFlag) { + this.passwordTokenSeenFlag = true; + continue; + } + const encodedCodePoints = percentEncodeChar(codePoint, isUserinfoPercentEncode); + if (this.passwordTokenSeenFlag) { + this.url.password += encodedCodePoints; + } else { + this.url.username += encodedCodePoints; + } + } + this.buffer = ""; + } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || + (isSpecial(this.url) && c === 92)) { + if (this.atFlag && this.buffer === "") { + this.parseError = true; + return failure; + } + this.pointer -= countSymbols(this.buffer) + 1; + this.buffer = ""; + this.state = "host"; + } else { + this.buffer += cStr; + } + + return true; +}; + +URLStateMachine.prototype["parse hostname"] = +URLStateMachine.prototype["parse host"] = function parseHostName(c, cStr) { + if (this.stateOverride && this.url.scheme === "file") { + --this.pointer; + this.state = "file host"; + } else if (c === 58 && !this.arrFlag) { + if (this.buffer === "") { + this.parseError = true; + return failure; + } + + const host = parseHost(this.buffer, isSpecial(this.url)); + if (host === failure) { + return failure; + } + + this.url.host = host; + this.buffer = ""; + this.state = "port"; + if (this.stateOverride === "hostname") { + return false; + } + } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || + (isSpecial(this.url) && c === 92)) { + --this.pointer; + if (isSpecial(this.url) && this.buffer === "") { + this.parseError = true; + return failure; + } else if (this.stateOverride && this.buffer === "" && + (includesCredentials(this.url) || this.url.port !== null)) { + this.parseError = true; + return false; + } + + const host = parseHost(this.buffer, isSpecial(this.url)); + if (host === failure) { + return failure; + } + + this.url.host = host; + this.buffer = ""; + this.state = "path start"; + if (this.stateOverride) { + return false; + } + } else { + if (c === 91) { + this.arrFlag = true; + } else if (c === 93) { + this.arrFlag = false; + } + this.buffer += cStr; + } + + return true; +}; + +URLStateMachine.prototype["parse port"] = function parsePort(c, cStr) { + if (isASCIIDigit(c)) { + this.buffer += cStr; + } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || + (isSpecial(this.url) && c === 92) || + this.stateOverride) { + if (this.buffer !== "") { + const port = parseInt(this.buffer); + if (port > Math.pow(2, 16) - 1) { + this.parseError = true; + return failure; + } + this.url.port = port === defaultPort(this.url.scheme) ? null : port; + this.buffer = ""; + } + if (this.stateOverride) { + return false; + } + this.state = "path start"; + --this.pointer; + } else { + this.parseError = true; + return failure; + } + + return true; +}; + +const fileOtherwiseCodePoints = new Set([47, 92, 63, 35]); + +URLStateMachine.prototype["parse file"] = function parseFile(c) { + this.url.scheme = "file"; + + if (c === 47 || c === 92) { + if (c === 92) { + this.parseError = true; + } + this.state = "file slash"; + } else if (this.base !== null && this.base.scheme === "file") { + if (isNaN(c)) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + } else if (c === 63) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + this.url.query = ""; + this.state = "query"; + } else if (c === 35) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + this.url.fragment = ""; + this.state = "fragment"; + } else { + if (this.input.length - this.pointer - 1 === 0 || // remaining consists of 0 code points + !isWindowsDriveLetterCodePoints(c, this.input[this.pointer + 1]) || + (this.input.length - this.pointer - 1 >= 2 && // remaining has at least 2 code points + !fileOtherwiseCodePoints.has(this.input[this.pointer + 2]))) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + shortenPath(this.url); + } else { + this.parseError = true; + } + + this.state = "path"; + --this.pointer; + } + } else { + this.state = "path"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse file slash"] = function parseFileSlash(c) { + if (c === 47 || c === 92) { + if (c === 92) { + this.parseError = true; + } + this.state = "file host"; + } else { + if (this.base !== null && this.base.scheme === "file") { + if (isNormalizedWindowsDriveLetterString(this.base.path[0])) { + this.url.path.push(this.base.path[0]); + } else { + this.url.host = this.base.host; + } + } + this.state = "path"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse file host"] = function parseFileHost(c, cStr) { + if (isNaN(c) || c === 47 || c === 92 || c === 63 || c === 35) { + --this.pointer; + if (!this.stateOverride && isWindowsDriveLetterString(this.buffer)) { + this.parseError = true; + this.state = "path"; + } else if (this.buffer === "") { + this.url.host = ""; + if (this.stateOverride) { + return false; + } + this.state = "path start"; + } else { + let host = parseHost(this.buffer, isSpecial(this.url)); + if (host === failure) { + return failure; + } + if (host === "localhost") { + host = ""; + } + this.url.host = host; + + if (this.stateOverride) { + return false; + } + + this.buffer = ""; + this.state = "path start"; + } + } else { + this.buffer += cStr; + } + + return true; +}; + +URLStateMachine.prototype["parse path start"] = function parsePathStart(c) { + if (isSpecial(this.url)) { + if (c === 92) { + this.parseError = true; + } + this.state = "path"; + + if (c !== 47 && c !== 92) { + --this.pointer; + } + } else if (!this.stateOverride && c === 63) { + this.url.query = ""; + this.state = "query"; + } else if (!this.stateOverride && c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } else if (c !== undefined) { + this.state = "path"; + if (c !== 47) { + --this.pointer; + } + } + + return true; +}; + +URLStateMachine.prototype["parse path"] = function parsePath(c) { + if (isNaN(c) || c === 47 || (isSpecial(this.url) && c === 92) || + (!this.stateOverride && (c === 63 || c === 35))) { + if (isSpecial(this.url) && c === 92) { + this.parseError = true; + } + + if (isDoubleDot(this.buffer)) { + shortenPath(this.url); + if (c !== 47 && !(isSpecial(this.url) && c === 92)) { + this.url.path.push(""); + } + } else if (isSingleDot(this.buffer) && c !== 47 && + !(isSpecial(this.url) && c === 92)) { + this.url.path.push(""); + } else if (!isSingleDot(this.buffer)) { + if (this.url.scheme === "file" && this.url.path.length === 0 && isWindowsDriveLetterString(this.buffer)) { + if (this.url.host !== "" && this.url.host !== null) { + this.parseError = true; + this.url.host = ""; + } + this.buffer = this.buffer[0] + ":"; + } + this.url.path.push(this.buffer); + } + this.buffer = ""; + if (this.url.scheme === "file" && (c === undefined || c === 63 || c === 35)) { + while (this.url.path.length > 1 && this.url.path[0] === "") { + this.parseError = true; + this.url.path.shift(); + } + } + if (c === 63) { + this.url.query = ""; + this.state = "query"; + } + if (c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } + } else { + // TODO: If c is not a URL code point and not "%", parse error. + + if (c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + + this.buffer += percentEncodeChar(c, isPathPercentEncode); + } + + return true; +}; + +URLStateMachine.prototype["parse cannot-be-a-base-URL path"] = function parseCannotBeABaseURLPath(c) { + if (c === 63) { + this.url.query = ""; + this.state = "query"; + } else if (c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } else { + // TODO: Add: not a URL code point + if (!isNaN(c) && c !== 37) { + this.parseError = true; + } + + if (c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + + if (!isNaN(c)) { + this.url.path[0] = this.url.path[0] + percentEncodeChar(c, isC0ControlPercentEncode); + } + } + + return true; +}; + +URLStateMachine.prototype["parse query"] = function parseQuery(c, cStr) { + if (isNaN(c) || (!this.stateOverride && c === 35)) { + if (!isSpecial(this.url) || this.url.scheme === "ws" || this.url.scheme === "wss") { + this.encodingOverride = "utf-8"; + } + + const buffer = new Buffer(this.buffer); // TODO: Use encoding override instead + for (let i = 0; i < buffer.length; ++i) { + if (buffer[i] < 0x21 || buffer[i] > 0x7E || buffer[i] === 0x22 || buffer[i] === 0x23 || + buffer[i] === 0x3C || buffer[i] === 0x3E) { + this.url.query += percentEncode(buffer[i]); + } else { + this.url.query += String.fromCodePoint(buffer[i]); + } + } + + this.buffer = ""; + if (c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } + } else { + // TODO: If c is not a URL code point and not "%", parse error. + if (c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + + this.buffer += cStr; + } + + return true; +}; + +URLStateMachine.prototype["parse fragment"] = function parseFragment(c) { + if (isNaN(c)) { // do nothing + } else if (c === 0x0) { + this.parseError = true; + } else { + // TODO: If c is not a URL code point and not "%", parse error. + if (c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + + this.url.fragment += percentEncodeChar(c, isC0ControlPercentEncode); + } + + return true; +}; + +function serializeURL(url, excludeFragment) { + let output = url.scheme + ":"; + if (url.host !== null) { + output += "//"; + + if (url.username !== "" || url.password !== "") { + output += url.username; + if (url.password !== "") { + output += ":" + url.password; + } + output += "@"; + } + + output += serializeHost(url.host); + + if (url.port !== null) { + output += ":" + url.port; + } + } else if (url.host === null && url.scheme === "file") { + output += "//"; + } + + if (url.cannotBeABaseURL) { + output += url.path[0]; + } else { + for (const string of url.path) { + output += "/" + string; + } + } + + if (url.query !== null) { + output += "?" + url.query; + } + + if (!excludeFragment && url.fragment !== null) { + output += "#" + url.fragment; + } + + return output; +} + +function serializeOrigin(tuple) { + let result = tuple.scheme + "://"; + result += serializeHost(tuple.host); + + if (tuple.port !== null) { + result += ":" + tuple.port; + } + + return result; +} + +module.exports.serializeURL = serializeURL; + +module.exports.serializeURLOrigin = function (url) { + // https://url.spec.whatwg.org/#concept-url-origin + switch (url.scheme) { + case "blob": + try { + return module.exports.serializeURLOrigin(module.exports.parseURL(url.path[0])); + } catch (e) { + // serializing an opaque origin returns "null" + return "null"; + } + case "ftp": + case "gopher": + case "http": + case "https": + case "ws": + case "wss": + return serializeOrigin({ + scheme: url.scheme, + host: url.host, + port: url.port + }); + case "file": + // spec says "exercise to the reader", chrome says "file://" + return "file://"; + default: + // serializing an opaque origin returns "null" + return "null"; + } +}; + +module.exports.basicURLParse = function (input, options) { + if (options === undefined) { + options = {}; + } + + const usm = new URLStateMachine(input, options.baseURL, options.encodingOverride, options.url, options.stateOverride); + if (usm.failure) { + return "failure"; + } + + return usm.url; +}; + +module.exports.setTheUsername = function (url, username) { + url.username = ""; + const decoded = punycode.ucs2.decode(username); + for (let i = 0; i < decoded.length; ++i) { + url.username += percentEncodeChar(decoded[i], isUserinfoPercentEncode); + } +}; + +module.exports.setThePassword = function (url, password) { + url.password = ""; + const decoded = punycode.ucs2.decode(password); + for (let i = 0; i < decoded.length; ++i) { + url.password += percentEncodeChar(decoded[i], isUserinfoPercentEncode); + } +}; + +module.exports.serializeHost = serializeHost; + +module.exports.cannotHaveAUsernamePasswordPort = cannotHaveAUsernamePasswordPort; + +module.exports.serializeInteger = function (integer) { + return String(integer); +}; + +module.exports.parseURL = function (input, options) { + if (options === undefined) { + options = {}; + } + + // We don't handle blobs, so this just delegates: + return module.exports.basicURLParse(input, { baseURL: options.baseURL, encodingOverride: options.encodingOverride }); +}; diff --git a/backend/node_modules/wide-align/LICENSE b/backend/node_modules/wide-align/LICENSE old mode 100644 new mode 100755 diff --git a/backend/node_modules/wide-align/README.md b/backend/node_modules/wide-align/README.md old mode 100644 new mode 100755 diff --git a/backend/node_modules/wide-align/align.js b/backend/node_modules/wide-align/align.js old mode 100644 new mode 100755 diff --git a/backend/node_modules/wide-align/package.json b/backend/node_modules/wide-align/package.json old mode 100644 new mode 100755 diff --git a/backend/node_modules/wkx/LICENSE.txt b/backend/node_modules/wkx/LICENSE.txt index 394e47a..2659446 100644 --- a/backend/node_modules/wkx/LICENSE.txt +++ b/backend/node_modules/wkx/LICENSE.txt @@ -1,20 +1,20 @@ -The MIT License (MIT) - -Copyright (c) 2013 Christian Schwarz - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The MIT License (MIT) + +Copyright (c) 2013 Christian Schwarz + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/backend/node_modules/wkx/README.md b/backend/node_modules/wkx/README.md index 378c023..1d3a353 100644 --- a/backend/node_modules/wkx/README.md +++ b/backend/node_modules/wkx/README.md @@ -1,92 +1,92 @@ -wkx [![Build Status](https://travis-ci.org/cschwarz/wkx.svg?branch=master)](https://travis-ci.org/cschwarz/wkx) [![Coverage Status](https://coveralls.io/repos/cschwarz/wkx/badge.svg?branch=master)](https://coveralls.io/r/cschwarz/wkx?branch=master) -======== - -A WKT/WKB/EWKT/EWKB/TWKB/GeoJSON parser and serializer with support for - -- Point -- LineString -- Polygon -- MultiPoint -- MultiLineString -- MultiPolygon -- GeometryCollection - -Examples --------- - -The following examples show you how to work with wkx. - -```javascript -var wkx = require('wkx'); - -//Parsing a WKT string -var geometry = wkx.Geometry.parse('POINT(1 2)'); - -//Parsing an EWKT string -var geometry = wkx.Geometry.parse('SRID=4326;POINT(1 2)'); - -//Parsing a node Buffer containing a WKB object -var geometry = wkx.Geometry.parse(wkbBuffer); - -//Parsing a node Buffer containing an EWKB object -var geometry = wkx.Geometry.parse(ewkbBuffer); - -//Parsing a node Buffer containing a TWKB object -var geometry = wkx.Geometry.parseTwkb(twkbBuffer); - -//Parsing a GeoJSON object -var geometry = wkx.Geometry.parseGeoJSON({ type: 'Point', coordinates: [1, 2] }); - -//Serializing a Point geometry to WKT -var wktString = new wkx.Point(1, 2).toWkt(); - -//Serializing a Point geometry to WKB -var wkbBuffer = new wkx.Point(1, 2).toWkb(); - -//Serializing a Point geometry to EWKT -var ewktString = new wkx.Point(1, 2, undefined, undefined, 4326).toEwkt(); - -//Serializing a Point geometry to EWKB -var ewkbBuffer = new wkx.Point(1, 2, undefined, undefined, 4326).toEwkb(); - -//Serializing a Point geometry to TWKB -var twkbBuffer = new wkx.Point(1, 2).toTwkb(); - -//Serializing a Point geometry to GeoJSON -var geoJSONObject = new wkx.Point(1, 2).toGeoJSON(); -``` - -Browser -------- - -To use `wkx` in a webpage, simply copy a built browser version from `dist/` into your project, and use a `script` tag -to include it: -```html - -``` - -If you use [browserify][] for your project, you can simply `npm install wkx --save`, and just require `wkx` as usual in -your code. - ----- - -Regardless of which of the preceeding options you choose, using `wkx` in the browser will look the same: -```javascript -var wkx = require('wkx'); - -var geometry = wkx.Geometry.parse('POINT(1 2)'); - -console.log(geometry.toGeoJSON()); -``` - -In addition to the `wkx` module, the browser versions also export `buffer`, which is useful for parsing WKB: -```javascript -var Buffer = require('buffer').Buffer; -var wkx = require('wkx'); - -var wkbBuffer = new Buffer('0101000000000000000000f03f0000000000000040', 'hex'); -var geometry = wkx.Geometry.parse(wkbBuffer); - -console.log(geometry.toGeoJSON()); -``` -[browserify]: http://browserify.org/ +wkx [![Build Status](https://travis-ci.org/cschwarz/wkx.svg?branch=master)](https://travis-ci.org/cschwarz/wkx) [![Coverage Status](https://coveralls.io/repos/cschwarz/wkx/badge.svg?branch=master)](https://coveralls.io/r/cschwarz/wkx?branch=master) +======== + +A WKT/WKB/EWKT/EWKB/TWKB/GeoJSON parser and serializer with support for + +- Point +- LineString +- Polygon +- MultiPoint +- MultiLineString +- MultiPolygon +- GeometryCollection + +Examples +-------- + +The following examples show you how to work with wkx. + +```javascript +var wkx = require('wkx'); + +//Parsing a WKT string +var geometry = wkx.Geometry.parse('POINT(1 2)'); + +//Parsing an EWKT string +var geometry = wkx.Geometry.parse('SRID=4326;POINT(1 2)'); + +//Parsing a node Buffer containing a WKB object +var geometry = wkx.Geometry.parse(wkbBuffer); + +//Parsing a node Buffer containing an EWKB object +var geometry = wkx.Geometry.parse(ewkbBuffer); + +//Parsing a node Buffer containing a TWKB object +var geometry = wkx.Geometry.parseTwkb(twkbBuffer); + +//Parsing a GeoJSON object +var geometry = wkx.Geometry.parseGeoJSON({ type: 'Point', coordinates: [1, 2] }); + +//Serializing a Point geometry to WKT +var wktString = new wkx.Point(1, 2).toWkt(); + +//Serializing a Point geometry to WKB +var wkbBuffer = new wkx.Point(1, 2).toWkb(); + +//Serializing a Point geometry to EWKT +var ewktString = new wkx.Point(1, 2, undefined, undefined, 4326).toEwkt(); + +//Serializing a Point geometry to EWKB +var ewkbBuffer = new wkx.Point(1, 2, undefined, undefined, 4326).toEwkb(); + +//Serializing a Point geometry to TWKB +var twkbBuffer = new wkx.Point(1, 2).toTwkb(); + +//Serializing a Point geometry to GeoJSON +var geoJSONObject = new wkx.Point(1, 2).toGeoJSON(); +``` + +Browser +------- + +To use `wkx` in a webpage, simply copy a built browser version from `dist/` into your project, and use a `script` tag +to include it: +```html + +``` + +If you use [browserify][] for your project, you can simply `npm install wkx --save`, and just require `wkx` as usual in +your code. + +---- + +Regardless of which of the preceeding options you choose, using `wkx` in the browser will look the same: +```javascript +var wkx = require('wkx'); + +var geometry = wkx.Geometry.parse('POINT(1 2)'); + +console.log(geometry.toGeoJSON()); +``` + +In addition to the `wkx` module, the browser versions also export `buffer`, which is useful for parsing WKB: +```javascript +var Buffer = require('buffer').Buffer; +var wkx = require('wkx'); + +var wkbBuffer = new Buffer('0101000000000000000000f03f0000000000000040', 'hex'); +var geometry = wkx.Geometry.parse(wkbBuffer); + +console.log(geometry.toGeoJSON()); +``` +[browserify]: http://browserify.org/ diff --git a/backend/node_modules/wkx/dist/wkx.js b/backend/node_modules/wkx/dist/wkx.js index 4346c59..0dcb697 100644 --- a/backend/node_modules/wkx/dist/wkx.js +++ b/backend/node_modules/wkx/dist/wkx.js @@ -1,2130 +1,2130 @@ require=(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i= 0x80); - - this.position += bytesRead; - - return result; -}; +module.exports = BinaryReader; + +function BinaryReader(buffer, isBigEndian) { + this.buffer = buffer; + this.position = 0; + this.isBigEndian = isBigEndian || false; +} + +function _read(readLE, readBE, size) { + return function () { + var value; + + if (this.isBigEndian) + value = readBE.call(this.buffer, this.position); + else + value = readLE.call(this.buffer, this.position); + + this.position += size; + + return value; + }; +} + +BinaryReader.prototype.readUInt8 = _read(Buffer.prototype.readUInt8, Buffer.prototype.readUInt8, 1); +BinaryReader.prototype.readUInt16 = _read(Buffer.prototype.readUInt16LE, Buffer.prototype.readUInt16BE, 2); +BinaryReader.prototype.readUInt32 = _read(Buffer.prototype.readUInt32LE, Buffer.prototype.readUInt32BE, 4); +BinaryReader.prototype.readInt8 = _read(Buffer.prototype.readInt8, Buffer.prototype.readInt8, 1); +BinaryReader.prototype.readInt16 = _read(Buffer.prototype.readInt16LE, Buffer.prototype.readInt16BE, 2); +BinaryReader.prototype.readInt32 = _read(Buffer.prototype.readInt32LE, Buffer.prototype.readInt32BE, 4); +BinaryReader.prototype.readFloat = _read(Buffer.prototype.readFloatLE, Buffer.prototype.readFloatBE, 4); +BinaryReader.prototype.readDouble = _read(Buffer.prototype.readDoubleLE, Buffer.prototype.readDoubleBE, 8); + +BinaryReader.prototype.readVarInt = function () { + var nextByte, + result = 0, + bytesRead = 0; + + do { + nextByte = this.buffer[this.position + bytesRead]; + result += (nextByte & 0x7F) << (7 * bytesRead); + bytesRead++; + } while (nextByte >= 0x80); + + this.position += bytesRead; + + return result; +}; }).call(this,require("buffer").Buffer) },{"buffer":"buffer"}],2:[function(require,module,exports){ (function (Buffer){ -module.exports = BinaryWriter; - -function BinaryWriter(size, allowResize) { - this.buffer = new Buffer(size); - this.position = 0; - this.allowResize = allowResize; -} - -function _write(write, size) { - return function (value, noAssert) { - this.ensureSize(size); - - write.call(this.buffer, value, this.position, noAssert); - this.position += size; - }; -} - -BinaryWriter.prototype.writeUInt8 = _write(Buffer.prototype.writeUInt8, 1); -BinaryWriter.prototype.writeUInt16LE = _write(Buffer.prototype.writeUInt16LE, 2); -BinaryWriter.prototype.writeUInt16BE = _write(Buffer.prototype.writeUInt16BE, 2); -BinaryWriter.prototype.writeUInt32LE = _write(Buffer.prototype.writeUInt32LE, 4); -BinaryWriter.prototype.writeUInt32BE = _write(Buffer.prototype.writeUInt32BE, 4); -BinaryWriter.prototype.writeInt8 = _write(Buffer.prototype.writeInt8, 1); -BinaryWriter.prototype.writeInt16LE = _write(Buffer.prototype.writeInt16LE, 2); -BinaryWriter.prototype.writeInt16BE = _write(Buffer.prototype.writeInt16BE, 2); -BinaryWriter.prototype.writeInt32LE = _write(Buffer.prototype.writeInt32LE, 4); -BinaryWriter.prototype.writeInt32BE = _write(Buffer.prototype.writeInt32BE, 4); -BinaryWriter.prototype.writeFloatLE = _write(Buffer.prototype.writeFloatLE, 4); -BinaryWriter.prototype.writeFloatBE = _write(Buffer.prototype.writeFloatBE, 4); -BinaryWriter.prototype.writeDoubleLE = _write(Buffer.prototype.writeDoubleLE, 8); -BinaryWriter.prototype.writeDoubleBE = _write(Buffer.prototype.writeDoubleBE, 8); - -BinaryWriter.prototype.writeBuffer = function (buffer) { - this.ensureSize(buffer.length); - - buffer.copy(this.buffer, this.position, 0, buffer.length); - this.position += buffer.length; -}; - -BinaryWriter.prototype.writeVarInt = function (value) { - var length = 1; - - while ((value & 0xFFFFFF80) !== 0) { - this.writeUInt8((value & 0x7F) | 0x80); - value >>>= 7; - length++; - } - - this.writeUInt8(value & 0x7F); - - return length; -}; - -BinaryWriter.prototype.ensureSize = function (size) { - if (this.buffer.length < this.position + size) { - if (this.allowResize) { - var tempBuffer = new Buffer(this.position + size); - this.buffer.copy(tempBuffer, 0, 0, this.buffer.length); - this.buffer = tempBuffer; - } - else { - throw new RangeError('index out of range'); - } - } -}; +module.exports = BinaryWriter; + +function BinaryWriter(size, allowResize) { + this.buffer = new Buffer(size); + this.position = 0; + this.allowResize = allowResize; +} + +function _write(write, size) { + return function (value, noAssert) { + this.ensureSize(size); + + write.call(this.buffer, value, this.position, noAssert); + this.position += size; + }; +} + +BinaryWriter.prototype.writeUInt8 = _write(Buffer.prototype.writeUInt8, 1); +BinaryWriter.prototype.writeUInt16LE = _write(Buffer.prototype.writeUInt16LE, 2); +BinaryWriter.prototype.writeUInt16BE = _write(Buffer.prototype.writeUInt16BE, 2); +BinaryWriter.prototype.writeUInt32LE = _write(Buffer.prototype.writeUInt32LE, 4); +BinaryWriter.prototype.writeUInt32BE = _write(Buffer.prototype.writeUInt32BE, 4); +BinaryWriter.prototype.writeInt8 = _write(Buffer.prototype.writeInt8, 1); +BinaryWriter.prototype.writeInt16LE = _write(Buffer.prototype.writeInt16LE, 2); +BinaryWriter.prototype.writeInt16BE = _write(Buffer.prototype.writeInt16BE, 2); +BinaryWriter.prototype.writeInt32LE = _write(Buffer.prototype.writeInt32LE, 4); +BinaryWriter.prototype.writeInt32BE = _write(Buffer.prototype.writeInt32BE, 4); +BinaryWriter.prototype.writeFloatLE = _write(Buffer.prototype.writeFloatLE, 4); +BinaryWriter.prototype.writeFloatBE = _write(Buffer.prototype.writeFloatBE, 4); +BinaryWriter.prototype.writeDoubleLE = _write(Buffer.prototype.writeDoubleLE, 8); +BinaryWriter.prototype.writeDoubleBE = _write(Buffer.prototype.writeDoubleBE, 8); + +BinaryWriter.prototype.writeBuffer = function (buffer) { + this.ensureSize(buffer.length); + + buffer.copy(this.buffer, this.position, 0, buffer.length); + this.position += buffer.length; +}; + +BinaryWriter.prototype.writeVarInt = function (value) { + var length = 1; + + while ((value & 0xFFFFFF80) !== 0) { + this.writeUInt8((value & 0x7F) | 0x80); + value >>>= 7; + length++; + } + + this.writeUInt8(value & 0x7F); + + return length; +}; + +BinaryWriter.prototype.ensureSize = function (size) { + if (this.buffer.length < this.position + size) { + if (this.allowResize) { + var tempBuffer = new Buffer(this.position + size); + this.buffer.copy(tempBuffer, 0, 0, this.buffer.length); + this.buffer = tempBuffer; + } + else { + throw new RangeError('index out of range'); + } + } +}; }).call(this,require("buffer").Buffer) },{"buffer":"buffer"}],3:[function(require,module,exports){ (function (Buffer){ -module.exports = Geometry; - -var Types = require('./types'); -var Point = require('./point'); -var LineString = require('./linestring'); -var Polygon = require('./polygon'); -var MultiPoint = require('./multipoint'); -var MultiLineString = require('./multilinestring'); -var MultiPolygon = require('./multipolygon'); -var GeometryCollection = require('./geometrycollection'); -var BinaryReader = require('./binaryreader'); -var BinaryWriter = require('./binarywriter'); -var WktParser = require('./wktparser'); -var ZigZag = require('./zigzag.js'); - -function Geometry() { - this.srid = undefined; - this.hasZ = false; - this.hasM = false; -} - -Geometry.parse = function (value, options) { - var valueType = typeof value; - - if (valueType === 'string' || value instanceof WktParser) - return Geometry._parseWkt(value); - else if (Buffer.isBuffer(value) || value instanceof BinaryReader) - return Geometry._parseWkb(value, options); - else - throw new Error('first argument must be a string or Buffer'); -}; - -Geometry._parseWkt = function (value) { - var wktParser, - srid; - - if (value instanceof WktParser) - wktParser = value; - else - wktParser = new WktParser(value); - - var match = wktParser.matchRegex([/^SRID=(\d+);/]); - if (match) - srid = parseInt(match[1], 10); - - var geometryType = wktParser.matchType(); - var dimension = wktParser.matchDimension(); - - var options = { - srid: srid, - hasZ: dimension.hasZ, - hasM: dimension.hasM - }; - - switch (geometryType) { - case Types.wkt.Point: - return Point._parseWkt(wktParser, options); - case Types.wkt.LineString: - return LineString._parseWkt(wktParser, options); - case Types.wkt.Polygon: - return Polygon._parseWkt(wktParser, options); - case Types.wkt.MultiPoint: - return MultiPoint._parseWkt(wktParser, options); - case Types.wkt.MultiLineString: - return MultiLineString._parseWkt(wktParser, options); - case Types.wkt.MultiPolygon: - return MultiPolygon._parseWkt(wktParser, options); - case Types.wkt.GeometryCollection: - return GeometryCollection._parseWkt(wktParser, options); - } -}; - -Geometry._parseWkb = function (value, parentOptions) { - var binaryReader, - wkbType, - geometryType, - options = {}; - - if (value instanceof BinaryReader) - binaryReader = value; - else - binaryReader = new BinaryReader(value); - - binaryReader.isBigEndian = !binaryReader.readInt8(); - - wkbType = binaryReader.readUInt32(); - - options.hasSrid = (wkbType & 0x20000000) === 0x20000000; - options.isEwkb = (wkbType & 0x20000000) || (wkbType & 0x40000000) || (wkbType & 0x80000000); - - if (options.hasSrid) - options.srid = binaryReader.readUInt32(); - - options.hasZ = false; - options.hasM = false; - - if (!options.isEwkb && (!parentOptions || !parentOptions.isEwkb)) { - if (wkbType >= 1000 && wkbType < 2000) { - options.hasZ = true; - geometryType = wkbType - 1000; - } - else if (wkbType >= 2000 && wkbType < 3000) { - options.hasM = true; - geometryType = wkbType - 2000; - } - else if (wkbType >= 3000 && wkbType < 4000) { - options.hasZ = true; - options.hasM = true; - geometryType = wkbType - 3000; - } - else { - geometryType = wkbType; - } - } - else { - if (wkbType & 0x80000000) - options.hasZ = true; - if (wkbType & 0x40000000) - options.hasM = true; - - geometryType = wkbType & 0xF; - } - - switch (geometryType) { - case Types.wkb.Point: - return Point._parseWkb(binaryReader, options); - case Types.wkb.LineString: - return LineString._parseWkb(binaryReader, options); - case Types.wkb.Polygon: - return Polygon._parseWkb(binaryReader, options); - case Types.wkb.MultiPoint: - return MultiPoint._parseWkb(binaryReader, options); - case Types.wkb.MultiLineString: - return MultiLineString._parseWkb(binaryReader, options); - case Types.wkb.MultiPolygon: - return MultiPolygon._parseWkb(binaryReader, options); - case Types.wkb.GeometryCollection: - return GeometryCollection._parseWkb(binaryReader, options); - default: - throw new Error('GeometryType ' + geometryType + ' not supported'); - } -}; - -Geometry.parseTwkb = function (value) { - var binaryReader, - options = {}; - - if (value instanceof BinaryReader) - binaryReader = value; - else - binaryReader = new BinaryReader(value); - - var type = binaryReader.readUInt8(); - var metadataHeader = binaryReader.readUInt8(); - - var geometryType = type & 0x0F; - options.precision = ZigZag.decode(type >> 4); - options.precisionFactor = Math.pow(10, options.precision); - - options.hasBoundingBox = metadataHeader >> 0 & 1; - options.hasSizeAttribute = metadataHeader >> 1 & 1; - options.hasIdList = metadataHeader >> 2 & 1; - options.hasExtendedPrecision = metadataHeader >> 3 & 1; - options.isEmpty = metadataHeader >> 4 & 1; - - if (options.hasExtendedPrecision) { - var extendedPrecision = binaryReader.readUInt8(); - options.hasZ = (extendedPrecision & 0x01) === 0x01; - options.hasM = (extendedPrecision & 0x02) === 0x02; - - options.zPrecision = ZigZag.decode((extendedPrecision & 0x1C) >> 2); - options.zPrecisionFactor = Math.pow(10, options.zPrecision); - - options.mPrecision = ZigZag.decode((extendedPrecision & 0xE0) >> 5); - options.mPrecisionFactor = Math.pow(10, options.mPrecision); - } - else { - options.hasZ = false; - options.hasM = false; - } - - if (options.hasSizeAttribute) - binaryReader.readVarInt(); - if (options.hasBoundingBox) { - var dimensions = 2; - - if (options.hasZ) - dimensions++; - if (options.hasM) - dimensions++; - - for (var i = 0; i < dimensions; i++) { - binaryReader.readVarInt(); - binaryReader.readVarInt(); - } - } - - switch (geometryType) { - case Types.wkb.Point: - return Point._parseTwkb(binaryReader, options); - case Types.wkb.LineString: - return LineString._parseTwkb(binaryReader, options); - case Types.wkb.Polygon: - return Polygon._parseTwkb(binaryReader, options); - case Types.wkb.MultiPoint: - return MultiPoint._parseTwkb(binaryReader, options); - case Types.wkb.MultiLineString: - return MultiLineString._parseTwkb(binaryReader, options); - case Types.wkb.MultiPolygon: - return MultiPolygon._parseTwkb(binaryReader, options); - case Types.wkb.GeometryCollection: - return GeometryCollection._parseTwkb(binaryReader, options); - default: - throw new Error('GeometryType ' + geometryType + ' not supported'); - } -}; - -Geometry.parseGeoJSON = function (value) { - return Geometry._parseGeoJSON(value); -}; - -Geometry._parseGeoJSON = function (value, isSubGeometry) { - var geometry; - - switch (value.type) { - case Types.geoJSON.Point: - geometry = Point._parseGeoJSON(value); break; - case Types.geoJSON.LineString: - geometry = LineString._parseGeoJSON(value); break; - case Types.geoJSON.Polygon: - geometry = Polygon._parseGeoJSON(value); break; - case Types.geoJSON.MultiPoint: - geometry = MultiPoint._parseGeoJSON(value); break; - case Types.geoJSON.MultiLineString: - geometry = MultiLineString._parseGeoJSON(value); break; - case Types.geoJSON.MultiPolygon: - geometry = MultiPolygon._parseGeoJSON(value); break; - case Types.geoJSON.GeometryCollection: - geometry = GeometryCollection._parseGeoJSON(value); break; - default: - throw new Error('GeometryType ' + value.type + ' not supported'); - } - - if (value.crs && value.crs.type && value.crs.type === 'name' && value.crs.properties && value.crs.properties.name) { - var crs = value.crs.properties.name; - - if (crs.indexOf('EPSG:') === 0) - geometry.srid = parseInt(crs.substring(5)); - else if (crs.indexOf('urn:ogc:def:crs:EPSG::') === 0) - geometry.srid = parseInt(crs.substring(22)); - else - throw new Error('Unsupported crs: ' + crs); - } - else if (!isSubGeometry) { - geometry.srid = 4326; - } - - return geometry; -}; - -Geometry.prototype.toEwkt = function () { - return 'SRID=' + this.srid + ';' + this.toWkt(); -}; - -Geometry.prototype.toEwkb = function () { - var ewkb = new BinaryWriter(this._getWkbSize() + 4); - var wkb = this.toWkb(); - - ewkb.writeInt8(1); - ewkb.writeUInt32LE((wkb.slice(1, 5).readUInt32LE(0) | 0x20000000) >>> 0, true); - ewkb.writeUInt32LE(this.srid); - - ewkb.writeBuffer(wkb.slice(5)); - - return ewkb.buffer; -}; - -Geometry.prototype._getWktType = function (wktType, isEmpty) { - var wkt = wktType; - - if (this.hasZ && this.hasM) - wkt += ' ZM '; - else if (this.hasZ) - wkt += ' Z '; - else if (this.hasM) - wkt += ' M '; - - if (isEmpty && !this.hasZ && !this.hasM) - wkt += ' '; - - if (isEmpty) - wkt += 'EMPTY'; - - return wkt; -}; - -Geometry.prototype._getWktCoordinate = function (point) { - var coordinates = point.x + ' ' + point.y; - - if (this.hasZ) - coordinates += ' ' + point.z; - if (this.hasM) - coordinates += ' ' + point.m; - - return coordinates; -}; - -Geometry.prototype._writeWkbType = function (wkb, geometryType, parentOptions) { - var dimensionType = 0; - - if (typeof this.srid === 'undefined' && (!parentOptions || typeof parentOptions.srid === 'undefined')) { - if (this.hasZ && this.hasM) - dimensionType += 3000; - else if (this.hasZ) - dimensionType += 1000; - else if (this.hasM) - dimensionType += 2000; - } - else { - if (this.hasZ) - dimensionType |= 0x80000000; - if (this.hasM) - dimensionType |= 0x40000000; - } - - wkb.writeUInt32LE((dimensionType + geometryType) >>> 0, true); -}; - -Geometry.getTwkbPrecision = function (xyPrecision, zPrecision, mPrecision) { - return { - xy: xyPrecision, - z: zPrecision, - m: mPrecision, - xyFactor: Math.pow(10, xyPrecision), - zFactor: Math.pow(10, zPrecision), - mFactor: Math.pow(10, mPrecision) - }; -}; - -Geometry.prototype._writeTwkbHeader = function (twkb, geometryType, precision, isEmpty) { - var type = (ZigZag.encode(precision.xy) << 4) + geometryType; - var metadataHeader = (this.hasZ || this.hasM) << 3; - metadataHeader += isEmpty << 4; - - twkb.writeUInt8(type); - twkb.writeUInt8(metadataHeader); - - if (this.hasZ || this.hasM) { - var extendedPrecision = 0; - if (this.hasZ) - extendedPrecision |= 0x1; - if (this.hasM) - extendedPrecision |= 0x2; - - twkb.writeUInt8(extendedPrecision); - } -}; - -Geometry.prototype.toGeoJSON = function (options) { - var geoJSON = {}; - - if (this.srid) { - if (options) { - if (options.shortCrs) { - geoJSON.crs = { - type: 'name', - properties: { - name: 'EPSG:' + this.srid - } - }; - } - else if (options.longCrs) { - geoJSON.crs = { - type: 'name', - properties: { - name: 'urn:ogc:def:crs:EPSG::' + this.srid - } - }; - } - } - } - - return geoJSON; -}; +module.exports = Geometry; + +var Types = require('./types'); +var Point = require('./point'); +var LineString = require('./linestring'); +var Polygon = require('./polygon'); +var MultiPoint = require('./multipoint'); +var MultiLineString = require('./multilinestring'); +var MultiPolygon = require('./multipolygon'); +var GeometryCollection = require('./geometrycollection'); +var BinaryReader = require('./binaryreader'); +var BinaryWriter = require('./binarywriter'); +var WktParser = require('./wktparser'); +var ZigZag = require('./zigzag.js'); + +function Geometry() { + this.srid = undefined; + this.hasZ = false; + this.hasM = false; +} + +Geometry.parse = function (value, options) { + var valueType = typeof value; + + if (valueType === 'string' || value instanceof WktParser) + return Geometry._parseWkt(value); + else if (Buffer.isBuffer(value) || value instanceof BinaryReader) + return Geometry._parseWkb(value, options); + else + throw new Error('first argument must be a string or Buffer'); +}; + +Geometry._parseWkt = function (value) { + var wktParser, + srid; + + if (value instanceof WktParser) + wktParser = value; + else + wktParser = new WktParser(value); + + var match = wktParser.matchRegex([/^SRID=(\d+);/]); + if (match) + srid = parseInt(match[1], 10); + + var geometryType = wktParser.matchType(); + var dimension = wktParser.matchDimension(); + + var options = { + srid: srid, + hasZ: dimension.hasZ, + hasM: dimension.hasM + }; + + switch (geometryType) { + case Types.wkt.Point: + return Point._parseWkt(wktParser, options); + case Types.wkt.LineString: + return LineString._parseWkt(wktParser, options); + case Types.wkt.Polygon: + return Polygon._parseWkt(wktParser, options); + case Types.wkt.MultiPoint: + return MultiPoint._parseWkt(wktParser, options); + case Types.wkt.MultiLineString: + return MultiLineString._parseWkt(wktParser, options); + case Types.wkt.MultiPolygon: + return MultiPolygon._parseWkt(wktParser, options); + case Types.wkt.GeometryCollection: + return GeometryCollection._parseWkt(wktParser, options); + } +}; + +Geometry._parseWkb = function (value, parentOptions) { + var binaryReader, + wkbType, + geometryType, + options = {}; + + if (value instanceof BinaryReader) + binaryReader = value; + else + binaryReader = new BinaryReader(value); + + binaryReader.isBigEndian = !binaryReader.readInt8(); + + wkbType = binaryReader.readUInt32(); + + options.hasSrid = (wkbType & 0x20000000) === 0x20000000; + options.isEwkb = (wkbType & 0x20000000) || (wkbType & 0x40000000) || (wkbType & 0x80000000); + + if (options.hasSrid) + options.srid = binaryReader.readUInt32(); + + options.hasZ = false; + options.hasM = false; + + if (!options.isEwkb && (!parentOptions || !parentOptions.isEwkb)) { + if (wkbType >= 1000 && wkbType < 2000) { + options.hasZ = true; + geometryType = wkbType - 1000; + } + else if (wkbType >= 2000 && wkbType < 3000) { + options.hasM = true; + geometryType = wkbType - 2000; + } + else if (wkbType >= 3000 && wkbType < 4000) { + options.hasZ = true; + options.hasM = true; + geometryType = wkbType - 3000; + } + else { + geometryType = wkbType; + } + } + else { + if (wkbType & 0x80000000) + options.hasZ = true; + if (wkbType & 0x40000000) + options.hasM = true; + + geometryType = wkbType & 0xF; + } + + switch (geometryType) { + case Types.wkb.Point: + return Point._parseWkb(binaryReader, options); + case Types.wkb.LineString: + return LineString._parseWkb(binaryReader, options); + case Types.wkb.Polygon: + return Polygon._parseWkb(binaryReader, options); + case Types.wkb.MultiPoint: + return MultiPoint._parseWkb(binaryReader, options); + case Types.wkb.MultiLineString: + return MultiLineString._parseWkb(binaryReader, options); + case Types.wkb.MultiPolygon: + return MultiPolygon._parseWkb(binaryReader, options); + case Types.wkb.GeometryCollection: + return GeometryCollection._parseWkb(binaryReader, options); + default: + throw new Error('GeometryType ' + geometryType + ' not supported'); + } +}; + +Geometry.parseTwkb = function (value) { + var binaryReader, + options = {}; + + if (value instanceof BinaryReader) + binaryReader = value; + else + binaryReader = new BinaryReader(value); + + var type = binaryReader.readUInt8(); + var metadataHeader = binaryReader.readUInt8(); + + var geometryType = type & 0x0F; + options.precision = ZigZag.decode(type >> 4); + options.precisionFactor = Math.pow(10, options.precision); + + options.hasBoundingBox = metadataHeader >> 0 & 1; + options.hasSizeAttribute = metadataHeader >> 1 & 1; + options.hasIdList = metadataHeader >> 2 & 1; + options.hasExtendedPrecision = metadataHeader >> 3 & 1; + options.isEmpty = metadataHeader >> 4 & 1; + + if (options.hasExtendedPrecision) { + var extendedPrecision = binaryReader.readUInt8(); + options.hasZ = (extendedPrecision & 0x01) === 0x01; + options.hasM = (extendedPrecision & 0x02) === 0x02; + + options.zPrecision = ZigZag.decode((extendedPrecision & 0x1C) >> 2); + options.zPrecisionFactor = Math.pow(10, options.zPrecision); + + options.mPrecision = ZigZag.decode((extendedPrecision & 0xE0) >> 5); + options.mPrecisionFactor = Math.pow(10, options.mPrecision); + } + else { + options.hasZ = false; + options.hasM = false; + } + + if (options.hasSizeAttribute) + binaryReader.readVarInt(); + if (options.hasBoundingBox) { + var dimensions = 2; + + if (options.hasZ) + dimensions++; + if (options.hasM) + dimensions++; + + for (var i = 0; i < dimensions; i++) { + binaryReader.readVarInt(); + binaryReader.readVarInt(); + } + } + + switch (geometryType) { + case Types.wkb.Point: + return Point._parseTwkb(binaryReader, options); + case Types.wkb.LineString: + return LineString._parseTwkb(binaryReader, options); + case Types.wkb.Polygon: + return Polygon._parseTwkb(binaryReader, options); + case Types.wkb.MultiPoint: + return MultiPoint._parseTwkb(binaryReader, options); + case Types.wkb.MultiLineString: + return MultiLineString._parseTwkb(binaryReader, options); + case Types.wkb.MultiPolygon: + return MultiPolygon._parseTwkb(binaryReader, options); + case Types.wkb.GeometryCollection: + return GeometryCollection._parseTwkb(binaryReader, options); + default: + throw new Error('GeometryType ' + geometryType + ' not supported'); + } +}; + +Geometry.parseGeoJSON = function (value) { + return Geometry._parseGeoJSON(value); +}; + +Geometry._parseGeoJSON = function (value, isSubGeometry) { + var geometry; + + switch (value.type) { + case Types.geoJSON.Point: + geometry = Point._parseGeoJSON(value); break; + case Types.geoJSON.LineString: + geometry = LineString._parseGeoJSON(value); break; + case Types.geoJSON.Polygon: + geometry = Polygon._parseGeoJSON(value); break; + case Types.geoJSON.MultiPoint: + geometry = MultiPoint._parseGeoJSON(value); break; + case Types.geoJSON.MultiLineString: + geometry = MultiLineString._parseGeoJSON(value); break; + case Types.geoJSON.MultiPolygon: + geometry = MultiPolygon._parseGeoJSON(value); break; + case Types.geoJSON.GeometryCollection: + geometry = GeometryCollection._parseGeoJSON(value); break; + default: + throw new Error('GeometryType ' + value.type + ' not supported'); + } + + if (value.crs && value.crs.type && value.crs.type === 'name' && value.crs.properties && value.crs.properties.name) { + var crs = value.crs.properties.name; + + if (crs.indexOf('EPSG:') === 0) + geometry.srid = parseInt(crs.substring(5)); + else if (crs.indexOf('urn:ogc:def:crs:EPSG::') === 0) + geometry.srid = parseInt(crs.substring(22)); + else + throw new Error('Unsupported crs: ' + crs); + } + else if (!isSubGeometry) { + geometry.srid = 4326; + } + + return geometry; +}; + +Geometry.prototype.toEwkt = function () { + return 'SRID=' + this.srid + ';' + this.toWkt(); +}; + +Geometry.prototype.toEwkb = function () { + var ewkb = new BinaryWriter(this._getWkbSize() + 4); + var wkb = this.toWkb(); + + ewkb.writeInt8(1); + ewkb.writeUInt32LE((wkb.slice(1, 5).readUInt32LE(0) | 0x20000000) >>> 0, true); + ewkb.writeUInt32LE(this.srid); + + ewkb.writeBuffer(wkb.slice(5)); + + return ewkb.buffer; +}; + +Geometry.prototype._getWktType = function (wktType, isEmpty) { + var wkt = wktType; + + if (this.hasZ && this.hasM) + wkt += ' ZM '; + else if (this.hasZ) + wkt += ' Z '; + else if (this.hasM) + wkt += ' M '; + + if (isEmpty && !this.hasZ && !this.hasM) + wkt += ' '; + + if (isEmpty) + wkt += 'EMPTY'; + + return wkt; +}; + +Geometry.prototype._getWktCoordinate = function (point) { + var coordinates = point.x + ' ' + point.y; + + if (this.hasZ) + coordinates += ' ' + point.z; + if (this.hasM) + coordinates += ' ' + point.m; + + return coordinates; +}; + +Geometry.prototype._writeWkbType = function (wkb, geometryType, parentOptions) { + var dimensionType = 0; + + if (typeof this.srid === 'undefined' && (!parentOptions || typeof parentOptions.srid === 'undefined')) { + if (this.hasZ && this.hasM) + dimensionType += 3000; + else if (this.hasZ) + dimensionType += 1000; + else if (this.hasM) + dimensionType += 2000; + } + else { + if (this.hasZ) + dimensionType |= 0x80000000; + if (this.hasM) + dimensionType |= 0x40000000; + } + + wkb.writeUInt32LE((dimensionType + geometryType) >>> 0, true); +}; + +Geometry.getTwkbPrecision = function (xyPrecision, zPrecision, mPrecision) { + return { + xy: xyPrecision, + z: zPrecision, + m: mPrecision, + xyFactor: Math.pow(10, xyPrecision), + zFactor: Math.pow(10, zPrecision), + mFactor: Math.pow(10, mPrecision) + }; +}; + +Geometry.prototype._writeTwkbHeader = function (twkb, geometryType, precision, isEmpty) { + var type = (ZigZag.encode(precision.xy) << 4) + geometryType; + var metadataHeader = (this.hasZ || this.hasM) << 3; + metadataHeader += isEmpty << 4; + + twkb.writeUInt8(type); + twkb.writeUInt8(metadataHeader); + + if (this.hasZ || this.hasM) { + var extendedPrecision = 0; + if (this.hasZ) + extendedPrecision |= 0x1; + if (this.hasM) + extendedPrecision |= 0x2; + + twkb.writeUInt8(extendedPrecision); + } +}; + +Geometry.prototype.toGeoJSON = function (options) { + var geoJSON = {}; + + if (this.srid) { + if (options) { + if (options.shortCrs) { + geoJSON.crs = { + type: 'name', + properties: { + name: 'EPSG:' + this.srid + } + }; + } + else if (options.longCrs) { + geoJSON.crs = { + type: 'name', + properties: { + name: 'urn:ogc:def:crs:EPSG::' + this.srid + } + }; + } + } + } + + return geoJSON; +}; }).call(this,{"isBuffer":require("../node_modules/is-buffer/index.js")}) },{"../node_modules/is-buffer/index.js":17,"./binaryreader":1,"./binarywriter":2,"./geometrycollection":4,"./linestring":5,"./multilinestring":6,"./multipoint":7,"./multipolygon":8,"./point":9,"./polygon":10,"./types":11,"./wktparser":12,"./zigzag.js":13}],4:[function(require,module,exports){ -module.exports = GeometryCollection; - -var util = require('util'); - -var Types = require('./types'); -var Geometry = require('./geometry'); -var BinaryWriter = require('./binarywriter'); - -function GeometryCollection(geometries, srid) { - Geometry.call(this); - - this.geometries = geometries || []; - this.srid = srid; - - if (this.geometries.length > 0) { - this.hasZ = this.geometries[0].hasZ; - this.hasM = this.geometries[0].hasM; - } -} - -util.inherits(GeometryCollection, Geometry); - -GeometryCollection.Z = function (geometries, srid) { - var geometryCollection = new GeometryCollection(geometries, srid); - geometryCollection.hasZ = true; - return geometryCollection; -}; - -GeometryCollection.M = function (geometries, srid) { - var geometryCollection = new GeometryCollection(geometries, srid); - geometryCollection.hasM = true; - return geometryCollection; -}; - -GeometryCollection.ZM = function (geometries, srid) { - var geometryCollection = new GeometryCollection(geometries, srid); - geometryCollection.hasZ = true; - geometryCollection.hasM = true; - return geometryCollection; -}; - -GeometryCollection._parseWkt = function (value, options) { - var geometryCollection = new GeometryCollection(); - geometryCollection.srid = options.srid; - geometryCollection.hasZ = options.hasZ; - geometryCollection.hasM = options.hasM; - - if (value.isMatch(['EMPTY'])) - return geometryCollection; - - value.expectGroupStart(); - - do { - geometryCollection.geometries.push(Geometry.parse(value)); - } while (value.isMatch([','])); - - value.expectGroupEnd(); - - return geometryCollection; -}; - -GeometryCollection._parseWkb = function (value, options) { - var geometryCollection = new GeometryCollection(); - geometryCollection.srid = options.srid; - geometryCollection.hasZ = options.hasZ; - geometryCollection.hasM = options.hasM; - - var geometryCount = value.readUInt32(); - - for (var i = 0; i < geometryCount; i++) - geometryCollection.geometries.push(Geometry.parse(value, options)); - - return geometryCollection; -}; - -GeometryCollection._parseTwkb = function (value, options) { - var geometryCollection = new GeometryCollection(); - geometryCollection.hasZ = options.hasZ; - geometryCollection.hasM = options.hasM; - - if (options.isEmpty) - return geometryCollection; - - var geometryCount = value.readVarInt(); - - for (var i = 0; i < geometryCount; i++) - geometryCollection.geometries.push(Geometry.parseTwkb(value)); - - return geometryCollection; -}; - -GeometryCollection._parseGeoJSON = function (value) { - var geometryCollection = new GeometryCollection(); - - for (var i = 0; i < value.geometries.length; i++) - geometryCollection.geometries.push(Geometry._parseGeoJSON(value.geometries[i], true)); - - if (geometryCollection.geometries.length > 0) - geometryCollection.hasZ = geometryCollection.geometries[0].hasZ; - - return geometryCollection; -}; - -GeometryCollection.prototype.toWkt = function () { - if (this.geometries.length === 0) - return this._getWktType(Types.wkt.GeometryCollection, true); - - var wkt = this._getWktType(Types.wkt.GeometryCollection, false) + '('; - - for (var i = 0; i < this.geometries.length; i++) - wkt += this.geometries[i].toWkt() + ','; - - wkt = wkt.slice(0, -1); - wkt += ')'; - - return wkt; -}; - -GeometryCollection.prototype.toWkb = function () { - var wkb = new BinaryWriter(this._getWkbSize()); - - wkb.writeInt8(1); - - this._writeWkbType(wkb, Types.wkb.GeometryCollection); - wkb.writeUInt32LE(this.geometries.length); - - for (var i = 0; i < this.geometries.length; i++) - wkb.writeBuffer(this.geometries[i].toWkb({ srid: this.srid })); - - return wkb.buffer; -}; - -GeometryCollection.prototype.toTwkb = function () { - var twkb = new BinaryWriter(0, true); - - var precision = Geometry.getTwkbPrecision(5, 0, 0); - var isEmpty = this.geometries.length === 0; - - this._writeTwkbHeader(twkb, Types.wkb.GeometryCollection, precision, isEmpty); - - if (this.geometries.length > 0) { - twkb.writeVarInt(this.geometries.length); - - for (var i = 0; i < this.geometries.length; i++) - twkb.writeBuffer(this.geometries[i].toTwkb()); - } - - return twkb.buffer; -}; - -GeometryCollection.prototype._getWkbSize = function () { - var size = 1 + 4 + 4; - - for (var i = 0; i < this.geometries.length; i++) - size += this.geometries[i]._getWkbSize(); - - return size; -}; - -GeometryCollection.prototype.toGeoJSON = function (options) { - var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); - geoJSON.type = Types.geoJSON.GeometryCollection; - geoJSON.geometries = []; - - for (var i = 0; i < this.geometries.length; i++) - geoJSON.geometries.push(this.geometries[i].toGeoJSON()); - - return geoJSON; -}; +module.exports = GeometryCollection; + +var util = require('util'); + +var Types = require('./types'); +var Geometry = require('./geometry'); +var BinaryWriter = require('./binarywriter'); + +function GeometryCollection(geometries, srid) { + Geometry.call(this); + + this.geometries = geometries || []; + this.srid = srid; + + if (this.geometries.length > 0) { + this.hasZ = this.geometries[0].hasZ; + this.hasM = this.geometries[0].hasM; + } +} + +util.inherits(GeometryCollection, Geometry); + +GeometryCollection.Z = function (geometries, srid) { + var geometryCollection = new GeometryCollection(geometries, srid); + geometryCollection.hasZ = true; + return geometryCollection; +}; + +GeometryCollection.M = function (geometries, srid) { + var geometryCollection = new GeometryCollection(geometries, srid); + geometryCollection.hasM = true; + return geometryCollection; +}; + +GeometryCollection.ZM = function (geometries, srid) { + var geometryCollection = new GeometryCollection(geometries, srid); + geometryCollection.hasZ = true; + geometryCollection.hasM = true; + return geometryCollection; +}; + +GeometryCollection._parseWkt = function (value, options) { + var geometryCollection = new GeometryCollection(); + geometryCollection.srid = options.srid; + geometryCollection.hasZ = options.hasZ; + geometryCollection.hasM = options.hasM; + + if (value.isMatch(['EMPTY'])) + return geometryCollection; + + value.expectGroupStart(); + + do { + geometryCollection.geometries.push(Geometry.parse(value)); + } while (value.isMatch([','])); + + value.expectGroupEnd(); + + return geometryCollection; +}; + +GeometryCollection._parseWkb = function (value, options) { + var geometryCollection = new GeometryCollection(); + geometryCollection.srid = options.srid; + geometryCollection.hasZ = options.hasZ; + geometryCollection.hasM = options.hasM; + + var geometryCount = value.readUInt32(); + + for (var i = 0; i < geometryCount; i++) + geometryCollection.geometries.push(Geometry.parse(value, options)); + + return geometryCollection; +}; + +GeometryCollection._parseTwkb = function (value, options) { + var geometryCollection = new GeometryCollection(); + geometryCollection.hasZ = options.hasZ; + geometryCollection.hasM = options.hasM; + + if (options.isEmpty) + return geometryCollection; + + var geometryCount = value.readVarInt(); + + for (var i = 0; i < geometryCount; i++) + geometryCollection.geometries.push(Geometry.parseTwkb(value)); + + return geometryCollection; +}; + +GeometryCollection._parseGeoJSON = function (value) { + var geometryCollection = new GeometryCollection(); + + for (var i = 0; i < value.geometries.length; i++) + geometryCollection.geometries.push(Geometry._parseGeoJSON(value.geometries[i], true)); + + if (geometryCollection.geometries.length > 0) + geometryCollection.hasZ = geometryCollection.geometries[0].hasZ; + + return geometryCollection; +}; + +GeometryCollection.prototype.toWkt = function () { + if (this.geometries.length === 0) + return this._getWktType(Types.wkt.GeometryCollection, true); + + var wkt = this._getWktType(Types.wkt.GeometryCollection, false) + '('; + + for (var i = 0; i < this.geometries.length; i++) + wkt += this.geometries[i].toWkt() + ','; + + wkt = wkt.slice(0, -1); + wkt += ')'; + + return wkt; +}; + +GeometryCollection.prototype.toWkb = function () { + var wkb = new BinaryWriter(this._getWkbSize()); + + wkb.writeInt8(1); + + this._writeWkbType(wkb, Types.wkb.GeometryCollection); + wkb.writeUInt32LE(this.geometries.length); + + for (var i = 0; i < this.geometries.length; i++) + wkb.writeBuffer(this.geometries[i].toWkb({ srid: this.srid })); + + return wkb.buffer; +}; + +GeometryCollection.prototype.toTwkb = function () { + var twkb = new BinaryWriter(0, true); + + var precision = Geometry.getTwkbPrecision(5, 0, 0); + var isEmpty = this.geometries.length === 0; + + this._writeTwkbHeader(twkb, Types.wkb.GeometryCollection, precision, isEmpty); + + if (this.geometries.length > 0) { + twkb.writeVarInt(this.geometries.length); + + for (var i = 0; i < this.geometries.length; i++) + twkb.writeBuffer(this.geometries[i].toTwkb()); + } + + return twkb.buffer; +}; + +GeometryCollection.prototype._getWkbSize = function () { + var size = 1 + 4 + 4; + + for (var i = 0; i < this.geometries.length; i++) + size += this.geometries[i]._getWkbSize(); + + return size; +}; + +GeometryCollection.prototype.toGeoJSON = function (options) { + var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); + geoJSON.type = Types.geoJSON.GeometryCollection; + geoJSON.geometries = []; + + for (var i = 0; i < this.geometries.length; i++) + geoJSON.geometries.push(this.geometries[i].toGeoJSON()); + + return geoJSON; +}; },{"./binarywriter":2,"./geometry":3,"./types":11,"util":20}],5:[function(require,module,exports){ -module.exports = LineString; - -var util = require('util'); - -var Geometry = require('./geometry'); -var Types = require('./types'); -var Point = require('./point'); -var BinaryWriter = require('./binarywriter'); - -function LineString(points, srid) { - Geometry.call(this); - - this.points = points || []; - this.srid = srid; - - if (this.points.length > 0) { - this.hasZ = this.points[0].hasZ; - this.hasM = this.points[0].hasM; - } -} - -util.inherits(LineString, Geometry); - -LineString.Z = function (points, srid) { - var lineString = new LineString(points, srid); - lineString.hasZ = true; - return lineString; -}; - -LineString.M = function (points, srid) { - var lineString = new LineString(points, srid); - lineString.hasM = true; - return lineString; -}; - -LineString.ZM = function (points, srid) { - var lineString = new LineString(points, srid); - lineString.hasZ = true; - lineString.hasM = true; - return lineString; -}; - -LineString._parseWkt = function (value, options) { - var lineString = new LineString(); - lineString.srid = options.srid; - lineString.hasZ = options.hasZ; - lineString.hasM = options.hasM; - - if (value.isMatch(['EMPTY'])) - return lineString; - - value.expectGroupStart(); - lineString.points.push.apply(lineString.points, value.matchCoordinates(options)); - value.expectGroupEnd(); - - return lineString; -}; - -LineString._parseWkb = function (value, options) { - var lineString = new LineString(); - lineString.srid = options.srid; - lineString.hasZ = options.hasZ; - lineString.hasM = options.hasM; - - var pointCount = value.readUInt32(); - - for (var i = 0; i < pointCount; i++) - lineString.points.push(Point._readWkbPoint(value, options)); - - return lineString; -}; - -LineString._parseTwkb = function (value, options) { - var lineString = new LineString(); - lineString.hasZ = options.hasZ; - lineString.hasM = options.hasM; - - if (options.isEmpty) - return lineString; - - var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); - var pointCount = value.readVarInt(); - - for (var i = 0; i < pointCount; i++) - lineString.points.push(Point._readTwkbPoint(value, options, previousPoint)); - - return lineString; -}; - -LineString._parseGeoJSON = function (value) { - var lineString = new LineString(); - - if (value.coordinates.length > 0) - lineString.hasZ = value.coordinates[0].length > 2; - - for (var i = 0; i < value.coordinates.length; i++) - lineString.points.push(Point._readGeoJSONPoint(value.coordinates[i])); - - return lineString; -}; - -LineString.prototype.toWkt = function () { - if (this.points.length === 0) - return this._getWktType(Types.wkt.LineString, true); - - return this._getWktType(Types.wkt.LineString, false) + this._toInnerWkt(); -}; - -LineString.prototype._toInnerWkt = function () { - var innerWkt = '('; - - for (var i = 0; i < this.points.length; i++) - innerWkt += this._getWktCoordinate(this.points[i]) + ','; - - innerWkt = innerWkt.slice(0, -1); - innerWkt += ')'; - - return innerWkt; -}; - -LineString.prototype.toWkb = function (parentOptions) { - var wkb = new BinaryWriter(this._getWkbSize()); - - wkb.writeInt8(1); - - this._writeWkbType(wkb, Types.wkb.LineString, parentOptions); - wkb.writeUInt32LE(this.points.length); - - for (var i = 0; i < this.points.length; i++) - this.points[i]._writeWkbPoint(wkb); - - return wkb.buffer; -}; - -LineString.prototype.toTwkb = function () { - var twkb = new BinaryWriter(0, true); - - var precision = Geometry.getTwkbPrecision(5, 0, 0); - var isEmpty = this.points.length === 0; - - this._writeTwkbHeader(twkb, Types.wkb.LineString, precision, isEmpty); - - if (this.points.length > 0) { - twkb.writeVarInt(this.points.length); - - var previousPoint = new Point(0, 0, 0, 0); - for (var i = 0; i < this.points.length; i++) - this.points[i]._writeTwkbPoint(twkb, precision, previousPoint); - } - - return twkb.buffer; -}; - -LineString.prototype._getWkbSize = function () { - var coordinateSize = 16; - - if (this.hasZ) - coordinateSize += 8; - if (this.hasM) - coordinateSize += 8; - - return 1 + 4 + 4 + (this.points.length * coordinateSize); -}; - -LineString.prototype.toGeoJSON = function (options) { - var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); - geoJSON.type = Types.geoJSON.LineString; - geoJSON.coordinates = []; - - for (var i = 0; i < this.points.length; i++) { - if (this.hasZ) - geoJSON.coordinates.push([this.points[i].x, this.points[i].y, this.points[i].z]); - else - geoJSON.coordinates.push([this.points[i].x, this.points[i].y]); - } - - return geoJSON; -}; +module.exports = LineString; + +var util = require('util'); + +var Geometry = require('./geometry'); +var Types = require('./types'); +var Point = require('./point'); +var BinaryWriter = require('./binarywriter'); + +function LineString(points, srid) { + Geometry.call(this); + + this.points = points || []; + this.srid = srid; + + if (this.points.length > 0) { + this.hasZ = this.points[0].hasZ; + this.hasM = this.points[0].hasM; + } +} + +util.inherits(LineString, Geometry); + +LineString.Z = function (points, srid) { + var lineString = new LineString(points, srid); + lineString.hasZ = true; + return lineString; +}; + +LineString.M = function (points, srid) { + var lineString = new LineString(points, srid); + lineString.hasM = true; + return lineString; +}; + +LineString.ZM = function (points, srid) { + var lineString = new LineString(points, srid); + lineString.hasZ = true; + lineString.hasM = true; + return lineString; +}; + +LineString._parseWkt = function (value, options) { + var lineString = new LineString(); + lineString.srid = options.srid; + lineString.hasZ = options.hasZ; + lineString.hasM = options.hasM; + + if (value.isMatch(['EMPTY'])) + return lineString; + + value.expectGroupStart(); + lineString.points.push.apply(lineString.points, value.matchCoordinates(options)); + value.expectGroupEnd(); + + return lineString; +}; + +LineString._parseWkb = function (value, options) { + var lineString = new LineString(); + lineString.srid = options.srid; + lineString.hasZ = options.hasZ; + lineString.hasM = options.hasM; + + var pointCount = value.readUInt32(); + + for (var i = 0; i < pointCount; i++) + lineString.points.push(Point._readWkbPoint(value, options)); + + return lineString; +}; + +LineString._parseTwkb = function (value, options) { + var lineString = new LineString(); + lineString.hasZ = options.hasZ; + lineString.hasM = options.hasM; + + if (options.isEmpty) + return lineString; + + var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); + var pointCount = value.readVarInt(); + + for (var i = 0; i < pointCount; i++) + lineString.points.push(Point._readTwkbPoint(value, options, previousPoint)); + + return lineString; +}; + +LineString._parseGeoJSON = function (value) { + var lineString = new LineString(); + + if (value.coordinates.length > 0) + lineString.hasZ = value.coordinates[0].length > 2; + + for (var i = 0; i < value.coordinates.length; i++) + lineString.points.push(Point._readGeoJSONPoint(value.coordinates[i])); + + return lineString; +}; + +LineString.prototype.toWkt = function () { + if (this.points.length === 0) + return this._getWktType(Types.wkt.LineString, true); + + return this._getWktType(Types.wkt.LineString, false) + this._toInnerWkt(); +}; + +LineString.prototype._toInnerWkt = function () { + var innerWkt = '('; + + for (var i = 0; i < this.points.length; i++) + innerWkt += this._getWktCoordinate(this.points[i]) + ','; + + innerWkt = innerWkt.slice(0, -1); + innerWkt += ')'; + + return innerWkt; +}; + +LineString.prototype.toWkb = function (parentOptions) { + var wkb = new BinaryWriter(this._getWkbSize()); + + wkb.writeInt8(1); + + this._writeWkbType(wkb, Types.wkb.LineString, parentOptions); + wkb.writeUInt32LE(this.points.length); + + for (var i = 0; i < this.points.length; i++) + this.points[i]._writeWkbPoint(wkb); + + return wkb.buffer; +}; + +LineString.prototype.toTwkb = function () { + var twkb = new BinaryWriter(0, true); + + var precision = Geometry.getTwkbPrecision(5, 0, 0); + var isEmpty = this.points.length === 0; + + this._writeTwkbHeader(twkb, Types.wkb.LineString, precision, isEmpty); + + if (this.points.length > 0) { + twkb.writeVarInt(this.points.length); + + var previousPoint = new Point(0, 0, 0, 0); + for (var i = 0; i < this.points.length; i++) + this.points[i]._writeTwkbPoint(twkb, precision, previousPoint); + } + + return twkb.buffer; +}; + +LineString.prototype._getWkbSize = function () { + var coordinateSize = 16; + + if (this.hasZ) + coordinateSize += 8; + if (this.hasM) + coordinateSize += 8; + + return 1 + 4 + 4 + (this.points.length * coordinateSize); +}; + +LineString.prototype.toGeoJSON = function (options) { + var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); + geoJSON.type = Types.geoJSON.LineString; + geoJSON.coordinates = []; + + for (var i = 0; i < this.points.length; i++) { + if (this.hasZ) + geoJSON.coordinates.push([this.points[i].x, this.points[i].y, this.points[i].z]); + else + geoJSON.coordinates.push([this.points[i].x, this.points[i].y]); + } + + return geoJSON; +}; },{"./binarywriter":2,"./geometry":3,"./point":9,"./types":11,"util":20}],6:[function(require,module,exports){ -module.exports = MultiLineString; - -var util = require('util'); - -var Types = require('./types'); -var Geometry = require('./geometry'); -var Point = require('./point'); -var LineString = require('./linestring'); -var BinaryWriter = require('./binarywriter'); - -function MultiLineString(lineStrings, srid) { - Geometry.call(this); - - this.lineStrings = lineStrings || []; - this.srid = srid; - - if (this.lineStrings.length > 0) { - this.hasZ = this.lineStrings[0].hasZ; - this.hasM = this.lineStrings[0].hasM; - } -} - -util.inherits(MultiLineString, Geometry); - -MultiLineString.Z = function (lineStrings, srid) { - var multiLineString = new MultiLineString(lineStrings, srid); - multiLineString.hasZ = true; - return multiLineString; -}; - -MultiLineString.M = function (lineStrings, srid) { - var multiLineString = new MultiLineString(lineStrings, srid); - multiLineString.hasM = true; - return multiLineString; -}; - -MultiLineString.ZM = function (lineStrings, srid) { - var multiLineString = new MultiLineString(lineStrings, srid); - multiLineString.hasZ = true; - multiLineString.hasM = true; - return multiLineString; -}; - -MultiLineString._parseWkt = function (value, options) { - var multiLineString = new MultiLineString(); - multiLineString.srid = options.srid; - multiLineString.hasZ = options.hasZ; - multiLineString.hasM = options.hasM; - - if (value.isMatch(['EMPTY'])) - return multiLineString; - - value.expectGroupStart(); - - do { - value.expectGroupStart(); - multiLineString.lineStrings.push(new LineString(value.matchCoordinates(options))); - value.expectGroupEnd(); - } while (value.isMatch([','])); - - value.expectGroupEnd(); - - return multiLineString; -}; - -MultiLineString._parseWkb = function (value, options) { - var multiLineString = new MultiLineString(); - multiLineString.srid = options.srid; - multiLineString.hasZ = options.hasZ; - multiLineString.hasM = options.hasM; - - var lineStringCount = value.readUInt32(); - - for (var i = 0; i < lineStringCount; i++) - multiLineString.lineStrings.push(Geometry.parse(value, options)); - - return multiLineString; -}; - -MultiLineString._parseTwkb = function (value, options) { - var multiLineString = new MultiLineString(); - multiLineString.hasZ = options.hasZ; - multiLineString.hasM = options.hasM; - - if (options.isEmpty) - return multiLineString; - - var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); - var lineStringCount = value.readVarInt(); - - for (var i = 0; i < lineStringCount; i++) { - var lineString = new LineString(); - lineString.hasZ = options.hasZ; - lineString.hasM = options.hasM; - - var pointCount = value.readVarInt(); - - for (var j = 0; j < pointCount; j++) - lineString.points.push(Point._readTwkbPoint(value, options, previousPoint)); - - multiLineString.lineStrings.push(lineString); - } - - return multiLineString; -}; - -MultiLineString._parseGeoJSON = function (value) { - var multiLineString = new MultiLineString(); - - if (value.coordinates.length > 0 && value.coordinates[0].length > 0) - multiLineString.hasZ = value.coordinates[0][0].length > 2; - - for (var i = 0; i < value.coordinates.length; i++) - multiLineString.lineStrings.push(LineString._parseGeoJSON({ coordinates: value.coordinates[i] })); - - return multiLineString; -}; - -MultiLineString.prototype.toWkt = function () { - if (this.lineStrings.length === 0) - return this._getWktType(Types.wkt.MultiLineString, true); - - var wkt = this._getWktType(Types.wkt.MultiLineString, false) + '('; - - for (var i = 0; i < this.lineStrings.length; i++) - wkt += this.lineStrings[i]._toInnerWkt() + ','; - - wkt = wkt.slice(0, -1); - wkt += ')'; - - return wkt; -}; - -MultiLineString.prototype.toWkb = function () { - var wkb = new BinaryWriter(this._getWkbSize()); - - wkb.writeInt8(1); - - this._writeWkbType(wkb, Types.wkb.MultiLineString); - wkb.writeUInt32LE(this.lineStrings.length); - - for (var i = 0; i < this.lineStrings.length; i++) - wkb.writeBuffer(this.lineStrings[i].toWkb({ srid: this.srid })); - - return wkb.buffer; -}; - -MultiLineString.prototype.toTwkb = function () { - var twkb = new BinaryWriter(0, true); - - var precision = Geometry.getTwkbPrecision(5, 0, 0); - var isEmpty = this.lineStrings.length === 0; - - this._writeTwkbHeader(twkb, Types.wkb.MultiLineString, precision, isEmpty); - - if (this.lineStrings.length > 0) { - twkb.writeVarInt(this.lineStrings.length); - - var previousPoint = new Point(0, 0, 0, 0); - for (var i = 0; i < this.lineStrings.length; i++) { - twkb.writeVarInt(this.lineStrings[i].points.length); - - for (var j = 0; j < this.lineStrings[i].points.length; j++) - this.lineStrings[i].points[j]._writeTwkbPoint(twkb, precision, previousPoint); - } - } - - return twkb.buffer; -}; - -MultiLineString.prototype._getWkbSize = function () { - var size = 1 + 4 + 4; - - for (var i = 0; i < this.lineStrings.length; i++) - size += this.lineStrings[i]._getWkbSize(); - - return size; -}; - -MultiLineString.prototype.toGeoJSON = function (options) { - var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); - geoJSON.type = Types.geoJSON.MultiLineString; - geoJSON.coordinates = []; - - for (var i = 0; i < this.lineStrings.length; i++) - geoJSON.coordinates.push(this.lineStrings[i].toGeoJSON().coordinates); - - return geoJSON; -}; +module.exports = MultiLineString; + +var util = require('util'); + +var Types = require('./types'); +var Geometry = require('./geometry'); +var Point = require('./point'); +var LineString = require('./linestring'); +var BinaryWriter = require('./binarywriter'); + +function MultiLineString(lineStrings, srid) { + Geometry.call(this); + + this.lineStrings = lineStrings || []; + this.srid = srid; + + if (this.lineStrings.length > 0) { + this.hasZ = this.lineStrings[0].hasZ; + this.hasM = this.lineStrings[0].hasM; + } +} + +util.inherits(MultiLineString, Geometry); + +MultiLineString.Z = function (lineStrings, srid) { + var multiLineString = new MultiLineString(lineStrings, srid); + multiLineString.hasZ = true; + return multiLineString; +}; + +MultiLineString.M = function (lineStrings, srid) { + var multiLineString = new MultiLineString(lineStrings, srid); + multiLineString.hasM = true; + return multiLineString; +}; + +MultiLineString.ZM = function (lineStrings, srid) { + var multiLineString = new MultiLineString(lineStrings, srid); + multiLineString.hasZ = true; + multiLineString.hasM = true; + return multiLineString; +}; + +MultiLineString._parseWkt = function (value, options) { + var multiLineString = new MultiLineString(); + multiLineString.srid = options.srid; + multiLineString.hasZ = options.hasZ; + multiLineString.hasM = options.hasM; + + if (value.isMatch(['EMPTY'])) + return multiLineString; + + value.expectGroupStart(); + + do { + value.expectGroupStart(); + multiLineString.lineStrings.push(new LineString(value.matchCoordinates(options))); + value.expectGroupEnd(); + } while (value.isMatch([','])); + + value.expectGroupEnd(); + + return multiLineString; +}; + +MultiLineString._parseWkb = function (value, options) { + var multiLineString = new MultiLineString(); + multiLineString.srid = options.srid; + multiLineString.hasZ = options.hasZ; + multiLineString.hasM = options.hasM; + + var lineStringCount = value.readUInt32(); + + for (var i = 0; i < lineStringCount; i++) + multiLineString.lineStrings.push(Geometry.parse(value, options)); + + return multiLineString; +}; + +MultiLineString._parseTwkb = function (value, options) { + var multiLineString = new MultiLineString(); + multiLineString.hasZ = options.hasZ; + multiLineString.hasM = options.hasM; + + if (options.isEmpty) + return multiLineString; + + var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); + var lineStringCount = value.readVarInt(); + + for (var i = 0; i < lineStringCount; i++) { + var lineString = new LineString(); + lineString.hasZ = options.hasZ; + lineString.hasM = options.hasM; + + var pointCount = value.readVarInt(); + + for (var j = 0; j < pointCount; j++) + lineString.points.push(Point._readTwkbPoint(value, options, previousPoint)); + + multiLineString.lineStrings.push(lineString); + } + + return multiLineString; +}; + +MultiLineString._parseGeoJSON = function (value) { + var multiLineString = new MultiLineString(); + + if (value.coordinates.length > 0 && value.coordinates[0].length > 0) + multiLineString.hasZ = value.coordinates[0][0].length > 2; + + for (var i = 0; i < value.coordinates.length; i++) + multiLineString.lineStrings.push(LineString._parseGeoJSON({ coordinates: value.coordinates[i] })); + + return multiLineString; +}; + +MultiLineString.prototype.toWkt = function () { + if (this.lineStrings.length === 0) + return this._getWktType(Types.wkt.MultiLineString, true); + + var wkt = this._getWktType(Types.wkt.MultiLineString, false) + '('; + + for (var i = 0; i < this.lineStrings.length; i++) + wkt += this.lineStrings[i]._toInnerWkt() + ','; + + wkt = wkt.slice(0, -1); + wkt += ')'; + + return wkt; +}; + +MultiLineString.prototype.toWkb = function () { + var wkb = new BinaryWriter(this._getWkbSize()); + + wkb.writeInt8(1); + + this._writeWkbType(wkb, Types.wkb.MultiLineString); + wkb.writeUInt32LE(this.lineStrings.length); + + for (var i = 0; i < this.lineStrings.length; i++) + wkb.writeBuffer(this.lineStrings[i].toWkb({ srid: this.srid })); + + return wkb.buffer; +}; + +MultiLineString.prototype.toTwkb = function () { + var twkb = new BinaryWriter(0, true); + + var precision = Geometry.getTwkbPrecision(5, 0, 0); + var isEmpty = this.lineStrings.length === 0; + + this._writeTwkbHeader(twkb, Types.wkb.MultiLineString, precision, isEmpty); + + if (this.lineStrings.length > 0) { + twkb.writeVarInt(this.lineStrings.length); + + var previousPoint = new Point(0, 0, 0, 0); + for (var i = 0; i < this.lineStrings.length; i++) { + twkb.writeVarInt(this.lineStrings[i].points.length); + + for (var j = 0; j < this.lineStrings[i].points.length; j++) + this.lineStrings[i].points[j]._writeTwkbPoint(twkb, precision, previousPoint); + } + } + + return twkb.buffer; +}; + +MultiLineString.prototype._getWkbSize = function () { + var size = 1 + 4 + 4; + + for (var i = 0; i < this.lineStrings.length; i++) + size += this.lineStrings[i]._getWkbSize(); + + return size; +}; + +MultiLineString.prototype.toGeoJSON = function (options) { + var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); + geoJSON.type = Types.geoJSON.MultiLineString; + geoJSON.coordinates = []; + + for (var i = 0; i < this.lineStrings.length; i++) + geoJSON.coordinates.push(this.lineStrings[i].toGeoJSON().coordinates); + + return geoJSON; +}; },{"./binarywriter":2,"./geometry":3,"./linestring":5,"./point":9,"./types":11,"util":20}],7:[function(require,module,exports){ -module.exports = MultiPoint; - -var util = require('util'); - -var Types = require('./types'); -var Geometry = require('./geometry'); -var Point = require('./point'); -var BinaryWriter = require('./binarywriter'); - -function MultiPoint(points, srid) { - Geometry.call(this); - - this.points = points || []; - this.srid = srid; - - if (this.points.length > 0) { - this.hasZ = this.points[0].hasZ; - this.hasM = this.points[0].hasM; - } -} - -util.inherits(MultiPoint, Geometry); - -MultiPoint.Z = function (points, srid) { - var multiPoint = new MultiPoint(points, srid); - multiPoint.hasZ = true; - return multiPoint; -}; - -MultiPoint.M = function (points, srid) { - var multiPoint = new MultiPoint(points, srid); - multiPoint.hasM = true; - return multiPoint; -}; - -MultiPoint.ZM = function (points, srid) { - var multiPoint = new MultiPoint(points, srid); - multiPoint.hasZ = true; - multiPoint.hasM = true; - return multiPoint; -}; - -MultiPoint._parseWkt = function (value, options) { - var multiPoint = new MultiPoint(); - multiPoint.srid = options.srid; - multiPoint.hasZ = options.hasZ; - multiPoint.hasM = options.hasM; - - if (value.isMatch(['EMPTY'])) - return multiPoint; - - value.expectGroupStart(); - multiPoint.points.push.apply(multiPoint.points, value.matchCoordinates(options)); - value.expectGroupEnd(); - - return multiPoint; -}; - -MultiPoint._parseWkb = function (value, options) { - var multiPoint = new MultiPoint(); - multiPoint.srid = options.srid; - multiPoint.hasZ = options.hasZ; - multiPoint.hasM = options.hasM; - - var pointCount = value.readUInt32(); - - for (var i = 0; i < pointCount; i++) - multiPoint.points.push(Geometry.parse(value, options)); - - return multiPoint; -}; - -MultiPoint._parseTwkb = function (value, options) { - var multiPoint = new MultiPoint(); - multiPoint.hasZ = options.hasZ; - multiPoint.hasM = options.hasM; - - if (options.isEmpty) - return multiPoint; - - var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); - var pointCount = value.readVarInt(); - - for (var i = 0; i < pointCount; i++) - multiPoint.points.push(Point._readTwkbPoint(value, options, previousPoint)); - - return multiPoint; -}; - -MultiPoint._parseGeoJSON = function (value) { - var multiPoint = new MultiPoint(); - - if (value.coordinates.length > 0) - multiPoint.hasZ = value.coordinates[0].length > 2; - - for (var i = 0; i < value.coordinates.length; i++) - multiPoint.points.push(Point._parseGeoJSON({ coordinates: value.coordinates[i] })); - - return multiPoint; -}; - -MultiPoint.prototype.toWkt = function () { - if (this.points.length === 0) - return this._getWktType(Types.wkt.MultiPoint, true); - - var wkt = this._getWktType(Types.wkt.MultiPoint, false) + '('; - - for (var i = 0; i < this.points.length; i++) - wkt += this._getWktCoordinate(this.points[i]) + ','; - - wkt = wkt.slice(0, -1); - wkt += ')'; - - return wkt; -}; - -MultiPoint.prototype.toWkb = function () { - var wkb = new BinaryWriter(this._getWkbSize()); - - wkb.writeInt8(1); - - this._writeWkbType(wkb, Types.wkb.MultiPoint); - wkb.writeUInt32LE(this.points.length); - - for (var i = 0; i < this.points.length; i++) - wkb.writeBuffer(this.points[i].toWkb({ srid: this.srid })); - - return wkb.buffer; -}; - -MultiPoint.prototype.toTwkb = function () { - var twkb = new BinaryWriter(0, true); - - var precision = Geometry.getTwkbPrecision(5, 0, 0); - var isEmpty = this.points.length === 0; - - this._writeTwkbHeader(twkb, Types.wkb.MultiPoint, precision, isEmpty); - - if (this.points.length > 0) { - twkb.writeVarInt(this.points.length); - - var previousPoint = new Point(0, 0, 0, 0); - for (var i = 0; i < this.points.length; i++) - this.points[i]._writeTwkbPoint(twkb, precision, previousPoint); - } - - return twkb.buffer; -}; - -MultiPoint.prototype._getWkbSize = function () { - var coordinateSize = 16; - - if (this.hasZ) - coordinateSize += 8; - if (this.hasM) - coordinateSize += 8; - - coordinateSize += 5; - - return 1 + 4 + 4 + (this.points.length * coordinateSize); -}; - -MultiPoint.prototype.toGeoJSON = function (options) { - var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); - geoJSON.type = Types.geoJSON.MultiPoint; - geoJSON.coordinates = []; - - for (var i = 0; i < this.points.length; i++) - geoJSON.coordinates.push(this.points[i].toGeoJSON().coordinates); - - return geoJSON; -}; +module.exports = MultiPoint; + +var util = require('util'); + +var Types = require('./types'); +var Geometry = require('./geometry'); +var Point = require('./point'); +var BinaryWriter = require('./binarywriter'); + +function MultiPoint(points, srid) { + Geometry.call(this); + + this.points = points || []; + this.srid = srid; + + if (this.points.length > 0) { + this.hasZ = this.points[0].hasZ; + this.hasM = this.points[0].hasM; + } +} + +util.inherits(MultiPoint, Geometry); + +MultiPoint.Z = function (points, srid) { + var multiPoint = new MultiPoint(points, srid); + multiPoint.hasZ = true; + return multiPoint; +}; + +MultiPoint.M = function (points, srid) { + var multiPoint = new MultiPoint(points, srid); + multiPoint.hasM = true; + return multiPoint; +}; + +MultiPoint.ZM = function (points, srid) { + var multiPoint = new MultiPoint(points, srid); + multiPoint.hasZ = true; + multiPoint.hasM = true; + return multiPoint; +}; + +MultiPoint._parseWkt = function (value, options) { + var multiPoint = new MultiPoint(); + multiPoint.srid = options.srid; + multiPoint.hasZ = options.hasZ; + multiPoint.hasM = options.hasM; + + if (value.isMatch(['EMPTY'])) + return multiPoint; + + value.expectGroupStart(); + multiPoint.points.push.apply(multiPoint.points, value.matchCoordinates(options)); + value.expectGroupEnd(); + + return multiPoint; +}; + +MultiPoint._parseWkb = function (value, options) { + var multiPoint = new MultiPoint(); + multiPoint.srid = options.srid; + multiPoint.hasZ = options.hasZ; + multiPoint.hasM = options.hasM; + + var pointCount = value.readUInt32(); + + for (var i = 0; i < pointCount; i++) + multiPoint.points.push(Geometry.parse(value, options)); + + return multiPoint; +}; + +MultiPoint._parseTwkb = function (value, options) { + var multiPoint = new MultiPoint(); + multiPoint.hasZ = options.hasZ; + multiPoint.hasM = options.hasM; + + if (options.isEmpty) + return multiPoint; + + var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); + var pointCount = value.readVarInt(); + + for (var i = 0; i < pointCount; i++) + multiPoint.points.push(Point._readTwkbPoint(value, options, previousPoint)); + + return multiPoint; +}; + +MultiPoint._parseGeoJSON = function (value) { + var multiPoint = new MultiPoint(); + + if (value.coordinates.length > 0) + multiPoint.hasZ = value.coordinates[0].length > 2; + + for (var i = 0; i < value.coordinates.length; i++) + multiPoint.points.push(Point._parseGeoJSON({ coordinates: value.coordinates[i] })); + + return multiPoint; +}; + +MultiPoint.prototype.toWkt = function () { + if (this.points.length === 0) + return this._getWktType(Types.wkt.MultiPoint, true); + + var wkt = this._getWktType(Types.wkt.MultiPoint, false) + '('; + + for (var i = 0; i < this.points.length; i++) + wkt += this._getWktCoordinate(this.points[i]) + ','; + + wkt = wkt.slice(0, -1); + wkt += ')'; + + return wkt; +}; + +MultiPoint.prototype.toWkb = function () { + var wkb = new BinaryWriter(this._getWkbSize()); + + wkb.writeInt8(1); + + this._writeWkbType(wkb, Types.wkb.MultiPoint); + wkb.writeUInt32LE(this.points.length); + + for (var i = 0; i < this.points.length; i++) + wkb.writeBuffer(this.points[i].toWkb({ srid: this.srid })); + + return wkb.buffer; +}; + +MultiPoint.prototype.toTwkb = function () { + var twkb = new BinaryWriter(0, true); + + var precision = Geometry.getTwkbPrecision(5, 0, 0); + var isEmpty = this.points.length === 0; + + this._writeTwkbHeader(twkb, Types.wkb.MultiPoint, precision, isEmpty); + + if (this.points.length > 0) { + twkb.writeVarInt(this.points.length); + + var previousPoint = new Point(0, 0, 0, 0); + for (var i = 0; i < this.points.length; i++) + this.points[i]._writeTwkbPoint(twkb, precision, previousPoint); + } + + return twkb.buffer; +}; + +MultiPoint.prototype._getWkbSize = function () { + var coordinateSize = 16; + + if (this.hasZ) + coordinateSize += 8; + if (this.hasM) + coordinateSize += 8; + + coordinateSize += 5; + + return 1 + 4 + 4 + (this.points.length * coordinateSize); +}; + +MultiPoint.prototype.toGeoJSON = function (options) { + var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); + geoJSON.type = Types.geoJSON.MultiPoint; + geoJSON.coordinates = []; + + for (var i = 0; i < this.points.length; i++) + geoJSON.coordinates.push(this.points[i].toGeoJSON().coordinates); + + return geoJSON; +}; },{"./binarywriter":2,"./geometry":3,"./point":9,"./types":11,"util":20}],8:[function(require,module,exports){ -module.exports = MultiPolygon; - -var util = require('util'); - -var Types = require('./types'); -var Geometry = require('./geometry'); -var Point = require('./point'); -var Polygon = require('./polygon'); -var BinaryWriter = require('./binarywriter'); - -function MultiPolygon(polygons, srid) { - Geometry.call(this); - - this.polygons = polygons || []; - this.srid = srid; - - if (this.polygons.length > 0) { - this.hasZ = this.polygons[0].hasZ; - this.hasM = this.polygons[0].hasM; - } -} - -util.inherits(MultiPolygon, Geometry); - -MultiPolygon.Z = function (polygons, srid) { - var multiPolygon = new MultiPolygon(polygons, srid); - multiPolygon.hasZ = true; - return multiPolygon; -}; - -MultiPolygon.M = function (polygons, srid) { - var multiPolygon = new MultiPolygon(polygons, srid); - multiPolygon.hasM = true; - return multiPolygon; -}; - -MultiPolygon.ZM = function (polygons, srid) { - var multiPolygon = new MultiPolygon(polygons, srid); - multiPolygon.hasZ = true; - multiPolygon.hasM = true; - return multiPolygon; -}; - -MultiPolygon._parseWkt = function (value, options) { - var multiPolygon = new MultiPolygon(); - multiPolygon.srid = options.srid; - multiPolygon.hasZ = options.hasZ; - multiPolygon.hasM = options.hasM; - - if (value.isMatch(['EMPTY'])) - return multiPolygon; - - value.expectGroupStart(); - - do { - value.expectGroupStart(); - - var exteriorRing = []; - var interiorRings = []; - - value.expectGroupStart(); - exteriorRing.push.apply(exteriorRing, value.matchCoordinates(options)); - value.expectGroupEnd(); - - while (value.isMatch([','])) { - value.expectGroupStart(); - interiorRings.push(value.matchCoordinates(options)); - value.expectGroupEnd(); - } - - multiPolygon.polygons.push(new Polygon(exteriorRing, interiorRings)); - - value.expectGroupEnd(); - - } while (value.isMatch([','])); - - value.expectGroupEnd(); - - return multiPolygon; -}; - -MultiPolygon._parseWkb = function (value, options) { - var multiPolygon = new MultiPolygon(); - multiPolygon.srid = options.srid; - multiPolygon.hasZ = options.hasZ; - multiPolygon.hasM = options.hasM; - - var polygonCount = value.readUInt32(); - - for (var i = 0; i < polygonCount; i++) - multiPolygon.polygons.push(Geometry.parse(value, options)); - - return multiPolygon; -}; - -MultiPolygon._parseTwkb = function (value, options) { - var multiPolygon = new MultiPolygon(); - multiPolygon.hasZ = options.hasZ; - multiPolygon.hasM = options.hasM; - - if (options.isEmpty) - return multiPolygon; - - var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); - var polygonCount = value.readVarInt(); - - for (var i = 0; i < polygonCount; i++) { - var polygon = new Polygon(); - polygon.hasZ = options.hasZ; - polygon.hasM = options.hasM; - - var ringCount = value.readVarInt(); - var exteriorRingCount = value.readVarInt(); - - for (var j = 0; j < exteriorRingCount; j++) - polygon.exteriorRing.push(Point._readTwkbPoint(value, options, previousPoint)); - - for (j = 1; j < ringCount; j++) { - var interiorRing = []; - - var interiorRingCount = value.readVarInt(); - - for (var k = 0; k < interiorRingCount; k++) - interiorRing.push(Point._readTwkbPoint(value, options, previousPoint)); - - polygon.interiorRings.push(interiorRing); - } - - multiPolygon.polygons.push(polygon); - } - - return multiPolygon; -}; - -MultiPolygon._parseGeoJSON = function (value) { - var multiPolygon = new MultiPolygon(); - - if (value.coordinates.length > 0 && value.coordinates[0].length > 0 && value.coordinates[0][0].length > 0) - multiPolygon.hasZ = value.coordinates[0][0][0].length > 2; - - for (var i = 0; i < value.coordinates.length; i++) - multiPolygon.polygons.push(Polygon._parseGeoJSON({ coordinates: value.coordinates[i] })); - - return multiPolygon; -}; - -MultiPolygon.prototype.toWkt = function () { - if (this.polygons.length === 0) - return this._getWktType(Types.wkt.MultiPolygon, true); - - var wkt = this._getWktType(Types.wkt.MultiPolygon, false) + '('; - - for (var i = 0; i < this.polygons.length; i++) - wkt += this.polygons[i]._toInnerWkt() + ','; - - wkt = wkt.slice(0, -1); - wkt += ')'; - - return wkt; -}; - -MultiPolygon.prototype.toWkb = function () { - var wkb = new BinaryWriter(this._getWkbSize()); - - wkb.writeInt8(1); - - this._writeWkbType(wkb, Types.wkb.MultiPolygon); - wkb.writeUInt32LE(this.polygons.length); - - for (var i = 0; i < this.polygons.length; i++) - wkb.writeBuffer(this.polygons[i].toWkb({ srid: this.srid })); - - return wkb.buffer; -}; - -MultiPolygon.prototype.toTwkb = function () { - var twkb = new BinaryWriter(0, true); - - var precision = Geometry.getTwkbPrecision(5, 0, 0); - var isEmpty = this.polygons.length === 0; - - this._writeTwkbHeader(twkb, Types.wkb.MultiPolygon, precision, isEmpty); - - if (this.polygons.length > 0) { - twkb.writeVarInt(this.polygons.length); - - var previousPoint = new Point(0, 0, 0, 0); - for (var i = 0; i < this.polygons.length; i++) { - twkb.writeVarInt(1 + this.polygons[i].interiorRings.length); - - twkb.writeVarInt(this.polygons[i].exteriorRing.length); - - for (var j = 0; j < this.polygons[i].exteriorRing.length; j++) - this.polygons[i].exteriorRing[j]._writeTwkbPoint(twkb, precision, previousPoint); - - for (j = 0; j < this.polygons[i].interiorRings.length; j++) { - twkb.writeVarInt(this.polygons[i].interiorRings[j].length); - - for (var k = 0; k < this.polygons[i].interiorRings[j].length; k++) - this.polygons[i].interiorRings[j][k]._writeTwkbPoint(twkb, precision, previousPoint); - } - } - } - - return twkb.buffer; -}; - -MultiPolygon.prototype._getWkbSize = function () { - var size = 1 + 4 + 4; - - for (var i = 0; i < this.polygons.length; i++) - size += this.polygons[i]._getWkbSize(); - - return size; -}; - -MultiPolygon.prototype.toGeoJSON = function (options) { - var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); - geoJSON.type = Types.geoJSON.MultiPolygon; - geoJSON.coordinates = []; - - for (var i = 0; i < this.polygons.length; i++) - geoJSON.coordinates.push(this.polygons[i].toGeoJSON().coordinates); - - return geoJSON; -}; +module.exports = MultiPolygon; + +var util = require('util'); + +var Types = require('./types'); +var Geometry = require('./geometry'); +var Point = require('./point'); +var Polygon = require('./polygon'); +var BinaryWriter = require('./binarywriter'); + +function MultiPolygon(polygons, srid) { + Geometry.call(this); + + this.polygons = polygons || []; + this.srid = srid; + + if (this.polygons.length > 0) { + this.hasZ = this.polygons[0].hasZ; + this.hasM = this.polygons[0].hasM; + } +} + +util.inherits(MultiPolygon, Geometry); + +MultiPolygon.Z = function (polygons, srid) { + var multiPolygon = new MultiPolygon(polygons, srid); + multiPolygon.hasZ = true; + return multiPolygon; +}; + +MultiPolygon.M = function (polygons, srid) { + var multiPolygon = new MultiPolygon(polygons, srid); + multiPolygon.hasM = true; + return multiPolygon; +}; + +MultiPolygon.ZM = function (polygons, srid) { + var multiPolygon = new MultiPolygon(polygons, srid); + multiPolygon.hasZ = true; + multiPolygon.hasM = true; + return multiPolygon; +}; + +MultiPolygon._parseWkt = function (value, options) { + var multiPolygon = new MultiPolygon(); + multiPolygon.srid = options.srid; + multiPolygon.hasZ = options.hasZ; + multiPolygon.hasM = options.hasM; + + if (value.isMatch(['EMPTY'])) + return multiPolygon; + + value.expectGroupStart(); + + do { + value.expectGroupStart(); + + var exteriorRing = []; + var interiorRings = []; + + value.expectGroupStart(); + exteriorRing.push.apply(exteriorRing, value.matchCoordinates(options)); + value.expectGroupEnd(); + + while (value.isMatch([','])) { + value.expectGroupStart(); + interiorRings.push(value.matchCoordinates(options)); + value.expectGroupEnd(); + } + + multiPolygon.polygons.push(new Polygon(exteriorRing, interiorRings)); + + value.expectGroupEnd(); + + } while (value.isMatch([','])); + + value.expectGroupEnd(); + + return multiPolygon; +}; + +MultiPolygon._parseWkb = function (value, options) { + var multiPolygon = new MultiPolygon(); + multiPolygon.srid = options.srid; + multiPolygon.hasZ = options.hasZ; + multiPolygon.hasM = options.hasM; + + var polygonCount = value.readUInt32(); + + for (var i = 0; i < polygonCount; i++) + multiPolygon.polygons.push(Geometry.parse(value, options)); + + return multiPolygon; +}; + +MultiPolygon._parseTwkb = function (value, options) { + var multiPolygon = new MultiPolygon(); + multiPolygon.hasZ = options.hasZ; + multiPolygon.hasM = options.hasM; + + if (options.isEmpty) + return multiPolygon; + + var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); + var polygonCount = value.readVarInt(); + + for (var i = 0; i < polygonCount; i++) { + var polygon = new Polygon(); + polygon.hasZ = options.hasZ; + polygon.hasM = options.hasM; + + var ringCount = value.readVarInt(); + var exteriorRingCount = value.readVarInt(); + + for (var j = 0; j < exteriorRingCount; j++) + polygon.exteriorRing.push(Point._readTwkbPoint(value, options, previousPoint)); + + for (j = 1; j < ringCount; j++) { + var interiorRing = []; + + var interiorRingCount = value.readVarInt(); + + for (var k = 0; k < interiorRingCount; k++) + interiorRing.push(Point._readTwkbPoint(value, options, previousPoint)); + + polygon.interiorRings.push(interiorRing); + } + + multiPolygon.polygons.push(polygon); + } + + return multiPolygon; +}; + +MultiPolygon._parseGeoJSON = function (value) { + var multiPolygon = new MultiPolygon(); + + if (value.coordinates.length > 0 && value.coordinates[0].length > 0 && value.coordinates[0][0].length > 0) + multiPolygon.hasZ = value.coordinates[0][0][0].length > 2; + + for (var i = 0; i < value.coordinates.length; i++) + multiPolygon.polygons.push(Polygon._parseGeoJSON({ coordinates: value.coordinates[i] })); + + return multiPolygon; +}; + +MultiPolygon.prototype.toWkt = function () { + if (this.polygons.length === 0) + return this._getWktType(Types.wkt.MultiPolygon, true); + + var wkt = this._getWktType(Types.wkt.MultiPolygon, false) + '('; + + for (var i = 0; i < this.polygons.length; i++) + wkt += this.polygons[i]._toInnerWkt() + ','; + + wkt = wkt.slice(0, -1); + wkt += ')'; + + return wkt; +}; + +MultiPolygon.prototype.toWkb = function () { + var wkb = new BinaryWriter(this._getWkbSize()); + + wkb.writeInt8(1); + + this._writeWkbType(wkb, Types.wkb.MultiPolygon); + wkb.writeUInt32LE(this.polygons.length); + + for (var i = 0; i < this.polygons.length; i++) + wkb.writeBuffer(this.polygons[i].toWkb({ srid: this.srid })); + + return wkb.buffer; +}; + +MultiPolygon.prototype.toTwkb = function () { + var twkb = new BinaryWriter(0, true); + + var precision = Geometry.getTwkbPrecision(5, 0, 0); + var isEmpty = this.polygons.length === 0; + + this._writeTwkbHeader(twkb, Types.wkb.MultiPolygon, precision, isEmpty); + + if (this.polygons.length > 0) { + twkb.writeVarInt(this.polygons.length); + + var previousPoint = new Point(0, 0, 0, 0); + for (var i = 0; i < this.polygons.length; i++) { + twkb.writeVarInt(1 + this.polygons[i].interiorRings.length); + + twkb.writeVarInt(this.polygons[i].exteriorRing.length); + + for (var j = 0; j < this.polygons[i].exteriorRing.length; j++) + this.polygons[i].exteriorRing[j]._writeTwkbPoint(twkb, precision, previousPoint); + + for (j = 0; j < this.polygons[i].interiorRings.length; j++) { + twkb.writeVarInt(this.polygons[i].interiorRings[j].length); + + for (var k = 0; k < this.polygons[i].interiorRings[j].length; k++) + this.polygons[i].interiorRings[j][k]._writeTwkbPoint(twkb, precision, previousPoint); + } + } + } + + return twkb.buffer; +}; + +MultiPolygon.prototype._getWkbSize = function () { + var size = 1 + 4 + 4; + + for (var i = 0; i < this.polygons.length; i++) + size += this.polygons[i]._getWkbSize(); + + return size; +}; + +MultiPolygon.prototype.toGeoJSON = function (options) { + var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); + geoJSON.type = Types.geoJSON.MultiPolygon; + geoJSON.coordinates = []; + + for (var i = 0; i < this.polygons.length; i++) + geoJSON.coordinates.push(this.polygons[i].toGeoJSON().coordinates); + + return geoJSON; +}; },{"./binarywriter":2,"./geometry":3,"./point":9,"./polygon":10,"./types":11,"util":20}],9:[function(require,module,exports){ -module.exports = Point; - -var util = require('util'); - -var Geometry = require('./geometry'); -var Types = require('./types'); -var BinaryWriter = require('./binarywriter'); -var ZigZag = require('./zigzag.js'); - -function Point(x, y, z, m, srid) { - Geometry.call(this); - - this.x = x; - this.y = y; - this.z = z; - this.m = m; - this.srid = srid; - - this.hasZ = typeof this.z !== 'undefined'; - this.hasM = typeof this.m !== 'undefined'; -} - -util.inherits(Point, Geometry); - -Point.Z = function (x, y, z, srid) { - var point = new Point(x, y, z, undefined, srid); - point.hasZ = true; - return point; -}; - -Point.M = function (x, y, m, srid) { - var point = new Point(x, y, undefined, m, srid); - point.hasM = true; - return point; -}; - -Point.ZM = function (x, y, z, m, srid) { - var point = new Point(x, y, z, m, srid); - point.hasZ = true; - point.hasM = true; - return point; -}; - -Point._parseWkt = function (value, options) { - var point = new Point(); - point.srid = options.srid; - point.hasZ = options.hasZ; - point.hasM = options.hasM; - - if (value.isMatch(['EMPTY'])) - return point; - - value.expectGroupStart(); - - var coordinate = value.matchCoordinate(options); - - point.x = coordinate.x; - point.y = coordinate.y; - point.z = coordinate.z; - point.m = coordinate.m; - - value.expectGroupEnd(); - - return point; -}; - -Point._parseWkb = function (value, options) { - var point = Point._readWkbPoint(value, options); - point.srid = options.srid; - return point; -}; - -Point._readWkbPoint = function (value, options) { - return new Point(value.readDouble(), value.readDouble(), - options.hasZ ? value.readDouble() : undefined, - options.hasM ? value.readDouble() : undefined); -}; - -Point._parseTwkb = function (value, options) { - var point = new Point(); - point.hasZ = options.hasZ; - point.hasM = options.hasM; - - if (options.isEmpty) - return point; - - point.x = ZigZag.decode(value.readVarInt()) / options.precisionFactor; - point.y = ZigZag.decode(value.readVarInt()) / options.precisionFactor; - point.z = options.hasZ ? ZigZag.decode(value.readVarInt()) / options.zPrecisionFactor : undefined; - point.m = options.hasM ? ZigZag.decode(value.readVarInt()) / options.mPrecisionFactor : undefined; - - return point; -}; - -Point._readTwkbPoint = function (value, options, previousPoint) { - previousPoint.x += ZigZag.decode(value.readVarInt()) / options.precisionFactor; - previousPoint.y += ZigZag.decode(value.readVarInt()) / options.precisionFactor; - - if (options.hasZ) - previousPoint.z += ZigZag.decode(value.readVarInt()) / options.zPrecisionFactor; - if (options.hasM) - previousPoint.m += ZigZag.decode(value.readVarInt()) / options.mPrecisionFactor; - - return new Point(previousPoint.x, previousPoint.y, previousPoint.z, previousPoint.m); -}; - -Point._parseGeoJSON = function (value) { - return Point._readGeoJSONPoint(value.coordinates); -}; - -Point._readGeoJSONPoint = function (coordinates) { - if (coordinates.length === 0) - return new Point(); - - if (coordinates.length > 2) - return new Point(coordinates[0], coordinates[1], coordinates[2]); - - return new Point(coordinates[0], coordinates[1]); -}; - -Point.prototype.toWkt = function () { - if (typeof this.x === 'undefined' && typeof this.y === 'undefined' && - typeof this.z === 'undefined' && typeof this.m === 'undefined') - return this._getWktType(Types.wkt.Point, true); - - return this._getWktType(Types.wkt.Point, false) + '(' + this._getWktCoordinate(this) + ')'; -}; - -Point.prototype.toWkb = function (parentOptions) { - var wkb = new BinaryWriter(this._getWkbSize()); - - wkb.writeInt8(1); - this._writeWkbType(wkb, Types.wkb.Point, parentOptions); - - if (typeof this.x === 'undefined' && typeof this.y === 'undefined') { - wkb.writeDoubleLE(NaN); - wkb.writeDoubleLE(NaN); - - if (this.hasZ) - wkb.writeDoubleLE(NaN); - if (this.hasM) - wkb.writeDoubleLE(NaN); - } - else { - this._writeWkbPoint(wkb); - } - - return wkb.buffer; -}; - -Point.prototype._writeWkbPoint = function (wkb) { - wkb.writeDoubleLE(this.x); - wkb.writeDoubleLE(this.y); - - if (this.hasZ) - wkb.writeDoubleLE(this.z); - if (this.hasM) - wkb.writeDoubleLE(this.m); -}; - -Point.prototype.toTwkb = function () { - var twkb = new BinaryWriter(0, true); - - var precision = Geometry.getTwkbPrecision(5, 0, 0); - var isEmpty = typeof this.x === 'undefined' && typeof this.y === 'undefined'; - - this._writeTwkbHeader(twkb, Types.wkb.Point, precision, isEmpty); - - if (!isEmpty) - this._writeTwkbPoint(twkb, precision, new Point(0, 0, 0, 0)); - - return twkb.buffer; -}; - -Point.prototype._writeTwkbPoint = function (twkb, precision, previousPoint) { - var x = this.x * precision.xyFactor; - var y = this.y * precision.xyFactor; - var z = this.z * precision.zFactor; - var m = this.m * precision.mFactor; - - twkb.writeVarInt(ZigZag.encode(x - previousPoint.x)); - twkb.writeVarInt(ZigZag.encode(y - previousPoint.y)); - if (this.hasZ) - twkb.writeVarInt(ZigZag.encode(z - previousPoint.z)); - if (this.hasM) - twkb.writeVarInt(ZigZag.encode(m - previousPoint.m)); - - previousPoint.x = x; - previousPoint.y = y; - previousPoint.z = z; - previousPoint.m = m; -}; - -Point.prototype._getWkbSize = function () { - var size = 1 + 4 + 8 + 8; - - if (this.hasZ) - size += 8; - if (this.hasM) - size += 8; - - return size; -}; - -Point.prototype.toGeoJSON = function (options) { - var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); - geoJSON.type = Types.geoJSON.Point; - - if (typeof this.x === 'undefined' && typeof this.y === 'undefined') - geoJSON.coordinates = []; - else if (typeof this.z !== 'undefined') - geoJSON.coordinates = [this.x, this.y, this.z]; - else - geoJSON.coordinates = [this.x, this.y]; - - return geoJSON; -}; +module.exports = Point; + +var util = require('util'); + +var Geometry = require('./geometry'); +var Types = require('./types'); +var BinaryWriter = require('./binarywriter'); +var ZigZag = require('./zigzag.js'); + +function Point(x, y, z, m, srid) { + Geometry.call(this); + + this.x = x; + this.y = y; + this.z = z; + this.m = m; + this.srid = srid; + + this.hasZ = typeof this.z !== 'undefined'; + this.hasM = typeof this.m !== 'undefined'; +} + +util.inherits(Point, Geometry); + +Point.Z = function (x, y, z, srid) { + var point = new Point(x, y, z, undefined, srid); + point.hasZ = true; + return point; +}; + +Point.M = function (x, y, m, srid) { + var point = new Point(x, y, undefined, m, srid); + point.hasM = true; + return point; +}; + +Point.ZM = function (x, y, z, m, srid) { + var point = new Point(x, y, z, m, srid); + point.hasZ = true; + point.hasM = true; + return point; +}; + +Point._parseWkt = function (value, options) { + var point = new Point(); + point.srid = options.srid; + point.hasZ = options.hasZ; + point.hasM = options.hasM; + + if (value.isMatch(['EMPTY'])) + return point; + + value.expectGroupStart(); + + var coordinate = value.matchCoordinate(options); + + point.x = coordinate.x; + point.y = coordinate.y; + point.z = coordinate.z; + point.m = coordinate.m; + + value.expectGroupEnd(); + + return point; +}; + +Point._parseWkb = function (value, options) { + var point = Point._readWkbPoint(value, options); + point.srid = options.srid; + return point; +}; + +Point._readWkbPoint = function (value, options) { + return new Point(value.readDouble(), value.readDouble(), + options.hasZ ? value.readDouble() : undefined, + options.hasM ? value.readDouble() : undefined); +}; + +Point._parseTwkb = function (value, options) { + var point = new Point(); + point.hasZ = options.hasZ; + point.hasM = options.hasM; + + if (options.isEmpty) + return point; + + point.x = ZigZag.decode(value.readVarInt()) / options.precisionFactor; + point.y = ZigZag.decode(value.readVarInt()) / options.precisionFactor; + point.z = options.hasZ ? ZigZag.decode(value.readVarInt()) / options.zPrecisionFactor : undefined; + point.m = options.hasM ? ZigZag.decode(value.readVarInt()) / options.mPrecisionFactor : undefined; + + return point; +}; + +Point._readTwkbPoint = function (value, options, previousPoint) { + previousPoint.x += ZigZag.decode(value.readVarInt()) / options.precisionFactor; + previousPoint.y += ZigZag.decode(value.readVarInt()) / options.precisionFactor; + + if (options.hasZ) + previousPoint.z += ZigZag.decode(value.readVarInt()) / options.zPrecisionFactor; + if (options.hasM) + previousPoint.m += ZigZag.decode(value.readVarInt()) / options.mPrecisionFactor; + + return new Point(previousPoint.x, previousPoint.y, previousPoint.z, previousPoint.m); +}; + +Point._parseGeoJSON = function (value) { + return Point._readGeoJSONPoint(value.coordinates); +}; + +Point._readGeoJSONPoint = function (coordinates) { + if (coordinates.length === 0) + return new Point(); + + if (coordinates.length > 2) + return new Point(coordinates[0], coordinates[1], coordinates[2]); + + return new Point(coordinates[0], coordinates[1]); +}; + +Point.prototype.toWkt = function () { + if (typeof this.x === 'undefined' && typeof this.y === 'undefined' && + typeof this.z === 'undefined' && typeof this.m === 'undefined') + return this._getWktType(Types.wkt.Point, true); + + return this._getWktType(Types.wkt.Point, false) + '(' + this._getWktCoordinate(this) + ')'; +}; + +Point.prototype.toWkb = function (parentOptions) { + var wkb = new BinaryWriter(this._getWkbSize()); + + wkb.writeInt8(1); + this._writeWkbType(wkb, Types.wkb.Point, parentOptions); + + if (typeof this.x === 'undefined' && typeof this.y === 'undefined') { + wkb.writeDoubleLE(NaN); + wkb.writeDoubleLE(NaN); + + if (this.hasZ) + wkb.writeDoubleLE(NaN); + if (this.hasM) + wkb.writeDoubleLE(NaN); + } + else { + this._writeWkbPoint(wkb); + } + + return wkb.buffer; +}; + +Point.prototype._writeWkbPoint = function (wkb) { + wkb.writeDoubleLE(this.x); + wkb.writeDoubleLE(this.y); + + if (this.hasZ) + wkb.writeDoubleLE(this.z); + if (this.hasM) + wkb.writeDoubleLE(this.m); +}; + +Point.prototype.toTwkb = function () { + var twkb = new BinaryWriter(0, true); + + var precision = Geometry.getTwkbPrecision(5, 0, 0); + var isEmpty = typeof this.x === 'undefined' && typeof this.y === 'undefined'; + + this._writeTwkbHeader(twkb, Types.wkb.Point, precision, isEmpty); + + if (!isEmpty) + this._writeTwkbPoint(twkb, precision, new Point(0, 0, 0, 0)); + + return twkb.buffer; +}; + +Point.prototype._writeTwkbPoint = function (twkb, precision, previousPoint) { + var x = this.x * precision.xyFactor; + var y = this.y * precision.xyFactor; + var z = this.z * precision.zFactor; + var m = this.m * precision.mFactor; + + twkb.writeVarInt(ZigZag.encode(x - previousPoint.x)); + twkb.writeVarInt(ZigZag.encode(y - previousPoint.y)); + if (this.hasZ) + twkb.writeVarInt(ZigZag.encode(z - previousPoint.z)); + if (this.hasM) + twkb.writeVarInt(ZigZag.encode(m - previousPoint.m)); + + previousPoint.x = x; + previousPoint.y = y; + previousPoint.z = z; + previousPoint.m = m; +}; + +Point.prototype._getWkbSize = function () { + var size = 1 + 4 + 8 + 8; + + if (this.hasZ) + size += 8; + if (this.hasM) + size += 8; + + return size; +}; + +Point.prototype.toGeoJSON = function (options) { + var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); + geoJSON.type = Types.geoJSON.Point; + + if (typeof this.x === 'undefined' && typeof this.y === 'undefined') + geoJSON.coordinates = []; + else if (typeof this.z !== 'undefined') + geoJSON.coordinates = [this.x, this.y, this.z]; + else + geoJSON.coordinates = [this.x, this.y]; + + return geoJSON; +}; },{"./binarywriter":2,"./geometry":3,"./types":11,"./zigzag.js":13,"util":20}],10:[function(require,module,exports){ -module.exports = Polygon; - -var util = require('util'); - -var Geometry = require('./geometry'); -var Types = require('./types'); -var Point = require('./point'); -var BinaryWriter = require('./binarywriter'); - -function Polygon(exteriorRing, interiorRings, srid) { - Geometry.call(this); - - this.exteriorRing = exteriorRing || []; - this.interiorRings = interiorRings || []; - this.srid = srid; - - if (this.exteriorRing.length > 0) { - this.hasZ = this.exteriorRing[0].hasZ; - this.hasM = this.exteriorRing[0].hasM; - } -} - -util.inherits(Polygon, Geometry); - -Polygon.Z = function (exteriorRing, interiorRings, srid) { - var polygon = new Polygon(exteriorRing, interiorRings, srid); - polygon.hasZ = true; - return polygon; -}; - -Polygon.M = function (exteriorRing, interiorRings, srid) { - var polygon = new Polygon(exteriorRing, interiorRings, srid); - polygon.hasM = true; - return polygon; -}; - -Polygon.ZM = function (exteriorRing, interiorRings, srid) { - var polygon = new Polygon(exteriorRing, interiorRings, srid); - polygon.hasZ = true; - polygon.hasM = true; - return polygon; -}; - -Polygon._parseWkt = function (value, options) { - var polygon = new Polygon(); - polygon.srid = options.srid; - polygon.hasZ = options.hasZ; - polygon.hasM = options.hasM; - - if (value.isMatch(['EMPTY'])) - return polygon; - - value.expectGroupStart(); - - value.expectGroupStart(); - polygon.exteriorRing.push.apply(polygon.exteriorRing, value.matchCoordinates(options)); - value.expectGroupEnd(); - - while (value.isMatch([','])) { - value.expectGroupStart(); - polygon.interiorRings.push(value.matchCoordinates(options)); - value.expectGroupEnd(); - } - - value.expectGroupEnd(); - - return polygon; -}; - -Polygon._parseWkb = function (value, options) { - var polygon = new Polygon(); - polygon.srid = options.srid; - polygon.hasZ = options.hasZ; - polygon.hasM = options.hasM; - - var ringCount = value.readUInt32(); - - if (ringCount > 0) { - var exteriorRingCount = value.readUInt32(); - - for (var i = 0; i < exteriorRingCount; i++) - polygon.exteriorRing.push(Point._readWkbPoint(value, options)); - - for (i = 1; i < ringCount; i++) { - var interiorRing = []; - - var interiorRingCount = value.readUInt32(); - - for (var j = 0; j < interiorRingCount; j++) - interiorRing.push(Point._readWkbPoint(value, options)); - - polygon.interiorRings.push(interiorRing); - } - } - - return polygon; -}; - -Polygon._parseTwkb = function (value, options) { - var polygon = new Polygon(); - polygon.hasZ = options.hasZ; - polygon.hasM = options.hasM; - - if (options.isEmpty) - return polygon; - - var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); - var ringCount = value.readVarInt(); - var exteriorRingCount = value.readVarInt(); - - for (var i = 0; i < exteriorRingCount; i++) - polygon.exteriorRing.push(Point._readTwkbPoint(value, options, previousPoint)); - - for (i = 1; i < ringCount; i++) { - var interiorRing = []; - - var interiorRingCount = value.readVarInt(); - - for (var j = 0; j < interiorRingCount; j++) - interiorRing.push(Point._readTwkbPoint(value, options, previousPoint)); - - polygon.interiorRings.push(interiorRing); - } - - return polygon; -}; - -Polygon._parseGeoJSON = function (value) { - var polygon = new Polygon(); - - if (value.coordinates.length > 0 && value.coordinates[0].length > 0) - polygon.hasZ = value.coordinates[0][0].length > 2; - - for (var i = 0; i < value.coordinates.length; i++) { - if (i > 0) - polygon.interiorRings.push([]); - - for (var j = 0; j < value.coordinates[i].length; j++) { - if (i === 0) - polygon.exteriorRing.push(Point._readGeoJSONPoint(value.coordinates[i][j])); - else - polygon.interiorRings[i - 1].push(Point._readGeoJSONPoint(value.coordinates[i][j])); - } - } - - return polygon; -}; - -Polygon.prototype.toWkt = function () { - if (this.exteriorRing.length === 0) - return this._getWktType(Types.wkt.Polygon, true); - - return this._getWktType(Types.wkt.Polygon, false) + this._toInnerWkt(); -}; - -Polygon.prototype._toInnerWkt = function () { - var innerWkt = '(('; - - for (var i = 0; i < this.exteriorRing.length; i++) - innerWkt += this._getWktCoordinate(this.exteriorRing[i]) + ','; - - innerWkt = innerWkt.slice(0, -1); - innerWkt += ')'; - - for (i = 0; i < this.interiorRings.length; i++) { - innerWkt += ',('; - - for (var j = 0; j < this.interiorRings[i].length; j++) { - innerWkt += this._getWktCoordinate(this.interiorRings[i][j]) + ','; - } - - innerWkt = innerWkt.slice(0, -1); - innerWkt += ')'; - } - - innerWkt += ')'; - - return innerWkt; -}; - -Polygon.prototype.toWkb = function (parentOptions) { - var wkb = new BinaryWriter(this._getWkbSize()); - - wkb.writeInt8(1); - - this._writeWkbType(wkb, Types.wkb.Polygon, parentOptions); - - if (this.exteriorRing.length > 0) { - wkb.writeUInt32LE(1 + this.interiorRings.length); - wkb.writeUInt32LE(this.exteriorRing.length); - } - else { - wkb.writeUInt32LE(0); - } - - for (var i = 0; i < this.exteriorRing.length; i++) - this.exteriorRing[i]._writeWkbPoint(wkb); - - for (i = 0; i < this.interiorRings.length; i++) { - wkb.writeUInt32LE(this.interiorRings[i].length); - - for (var j = 0; j < this.interiorRings[i].length; j++) - this.interiorRings[i][j]._writeWkbPoint(wkb); - } - - return wkb.buffer; -}; - -Polygon.prototype.toTwkb = function () { - var twkb = new BinaryWriter(0, true); - - var precision = Geometry.getTwkbPrecision(5, 0, 0); - var isEmpty = this.exteriorRing.length === 0; - - this._writeTwkbHeader(twkb, Types.wkb.Polygon, precision, isEmpty); - - if (this.exteriorRing.length > 0) { - twkb.writeVarInt(1 + this.interiorRings.length); - - twkb.writeVarInt(this.exteriorRing.length); - - var previousPoint = new Point(0, 0, 0, 0); - for (var i = 0; i < this.exteriorRing.length; i++) - this.exteriorRing[i]._writeTwkbPoint(twkb, precision, previousPoint); - - for (i = 0; i < this.interiorRings.length; i++) { - twkb.writeVarInt(this.interiorRings[i].length); - - for (var j = 0; j < this.interiorRings[i].length; j++) - this.interiorRings[i][j]._writeTwkbPoint(twkb, precision, previousPoint); - } - } - - return twkb.buffer; -}; - -Polygon.prototype._getWkbSize = function () { - var coordinateSize = 16; - - if (this.hasZ) - coordinateSize += 8; - if (this.hasM) - coordinateSize += 8; - - var size = 1 + 4 + 4; - - if (this.exteriorRing.length > 0) - size += 4 + (this.exteriorRing.length * coordinateSize); - - for (var i = 0; i < this.interiorRings.length; i++) - size += 4 + (this.interiorRings[i].length * coordinateSize); - - return size; -}; - -Polygon.prototype.toGeoJSON = function (options) { - var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); - geoJSON.type = Types.geoJSON.Polygon; - geoJSON.coordinates = []; - - if (this.exteriorRing.length > 0) { - var exteriorRing = []; - - for (var i = 0; i < this.exteriorRing.length; i++) { - if (this.hasZ) - exteriorRing.push([this.exteriorRing[i].x, this.exteriorRing[i].y, this.exteriorRing[i].z]); - else - exteriorRing.push([this.exteriorRing[i].x, this.exteriorRing[i].y]); - } - - geoJSON.coordinates.push(exteriorRing); - } - - for (var j = 0; j < this.interiorRings.length; j++) { - var interiorRing = []; - - for (var k = 0; k < this.interiorRings[j].length; k++) { - if (this.hasZ) - interiorRing.push([this.interiorRings[j][k].x, this.interiorRings[j][k].y, this.interiorRings[j][k].z]); - else - interiorRing.push([this.interiorRings[j][k].x, this.interiorRings[j][k].y]); - } - - geoJSON.coordinates.push(interiorRing); - } - - return geoJSON; -}; +module.exports = Polygon; + +var util = require('util'); + +var Geometry = require('./geometry'); +var Types = require('./types'); +var Point = require('./point'); +var BinaryWriter = require('./binarywriter'); + +function Polygon(exteriorRing, interiorRings, srid) { + Geometry.call(this); + + this.exteriorRing = exteriorRing || []; + this.interiorRings = interiorRings || []; + this.srid = srid; + + if (this.exteriorRing.length > 0) { + this.hasZ = this.exteriorRing[0].hasZ; + this.hasM = this.exteriorRing[0].hasM; + } +} + +util.inherits(Polygon, Geometry); + +Polygon.Z = function (exteriorRing, interiorRings, srid) { + var polygon = new Polygon(exteriorRing, interiorRings, srid); + polygon.hasZ = true; + return polygon; +}; + +Polygon.M = function (exteriorRing, interiorRings, srid) { + var polygon = new Polygon(exteriorRing, interiorRings, srid); + polygon.hasM = true; + return polygon; +}; + +Polygon.ZM = function (exteriorRing, interiorRings, srid) { + var polygon = new Polygon(exteriorRing, interiorRings, srid); + polygon.hasZ = true; + polygon.hasM = true; + return polygon; +}; + +Polygon._parseWkt = function (value, options) { + var polygon = new Polygon(); + polygon.srid = options.srid; + polygon.hasZ = options.hasZ; + polygon.hasM = options.hasM; + + if (value.isMatch(['EMPTY'])) + return polygon; + + value.expectGroupStart(); + + value.expectGroupStart(); + polygon.exteriorRing.push.apply(polygon.exteriorRing, value.matchCoordinates(options)); + value.expectGroupEnd(); + + while (value.isMatch([','])) { + value.expectGroupStart(); + polygon.interiorRings.push(value.matchCoordinates(options)); + value.expectGroupEnd(); + } + + value.expectGroupEnd(); + + return polygon; +}; + +Polygon._parseWkb = function (value, options) { + var polygon = new Polygon(); + polygon.srid = options.srid; + polygon.hasZ = options.hasZ; + polygon.hasM = options.hasM; + + var ringCount = value.readUInt32(); + + if (ringCount > 0) { + var exteriorRingCount = value.readUInt32(); + + for (var i = 0; i < exteriorRingCount; i++) + polygon.exteriorRing.push(Point._readWkbPoint(value, options)); + + for (i = 1; i < ringCount; i++) { + var interiorRing = []; + + var interiorRingCount = value.readUInt32(); + + for (var j = 0; j < interiorRingCount; j++) + interiorRing.push(Point._readWkbPoint(value, options)); + + polygon.interiorRings.push(interiorRing); + } + } + + return polygon; +}; + +Polygon._parseTwkb = function (value, options) { + var polygon = new Polygon(); + polygon.hasZ = options.hasZ; + polygon.hasM = options.hasM; + + if (options.isEmpty) + return polygon; + + var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); + var ringCount = value.readVarInt(); + var exteriorRingCount = value.readVarInt(); + + for (var i = 0; i < exteriorRingCount; i++) + polygon.exteriorRing.push(Point._readTwkbPoint(value, options, previousPoint)); + + for (i = 1; i < ringCount; i++) { + var interiorRing = []; + + var interiorRingCount = value.readVarInt(); + + for (var j = 0; j < interiorRingCount; j++) + interiorRing.push(Point._readTwkbPoint(value, options, previousPoint)); + + polygon.interiorRings.push(interiorRing); + } + + return polygon; +}; + +Polygon._parseGeoJSON = function (value) { + var polygon = new Polygon(); + + if (value.coordinates.length > 0 && value.coordinates[0].length > 0) + polygon.hasZ = value.coordinates[0][0].length > 2; + + for (var i = 0; i < value.coordinates.length; i++) { + if (i > 0) + polygon.interiorRings.push([]); + + for (var j = 0; j < value.coordinates[i].length; j++) { + if (i === 0) + polygon.exteriorRing.push(Point._readGeoJSONPoint(value.coordinates[i][j])); + else + polygon.interiorRings[i - 1].push(Point._readGeoJSONPoint(value.coordinates[i][j])); + } + } + + return polygon; +}; + +Polygon.prototype.toWkt = function () { + if (this.exteriorRing.length === 0) + return this._getWktType(Types.wkt.Polygon, true); + + return this._getWktType(Types.wkt.Polygon, false) + this._toInnerWkt(); +}; + +Polygon.prototype._toInnerWkt = function () { + var innerWkt = '(('; + + for (var i = 0; i < this.exteriorRing.length; i++) + innerWkt += this._getWktCoordinate(this.exteriorRing[i]) + ','; + + innerWkt = innerWkt.slice(0, -1); + innerWkt += ')'; + + for (i = 0; i < this.interiorRings.length; i++) { + innerWkt += ',('; + + for (var j = 0; j < this.interiorRings[i].length; j++) { + innerWkt += this._getWktCoordinate(this.interiorRings[i][j]) + ','; + } + + innerWkt = innerWkt.slice(0, -1); + innerWkt += ')'; + } + + innerWkt += ')'; + + return innerWkt; +}; + +Polygon.prototype.toWkb = function (parentOptions) { + var wkb = new BinaryWriter(this._getWkbSize()); + + wkb.writeInt8(1); + + this._writeWkbType(wkb, Types.wkb.Polygon, parentOptions); + + if (this.exteriorRing.length > 0) { + wkb.writeUInt32LE(1 + this.interiorRings.length); + wkb.writeUInt32LE(this.exteriorRing.length); + } + else { + wkb.writeUInt32LE(0); + } + + for (var i = 0; i < this.exteriorRing.length; i++) + this.exteriorRing[i]._writeWkbPoint(wkb); + + for (i = 0; i < this.interiorRings.length; i++) { + wkb.writeUInt32LE(this.interiorRings[i].length); + + for (var j = 0; j < this.interiorRings[i].length; j++) + this.interiorRings[i][j]._writeWkbPoint(wkb); + } + + return wkb.buffer; +}; + +Polygon.prototype.toTwkb = function () { + var twkb = new BinaryWriter(0, true); + + var precision = Geometry.getTwkbPrecision(5, 0, 0); + var isEmpty = this.exteriorRing.length === 0; + + this._writeTwkbHeader(twkb, Types.wkb.Polygon, precision, isEmpty); + + if (this.exteriorRing.length > 0) { + twkb.writeVarInt(1 + this.interiorRings.length); + + twkb.writeVarInt(this.exteriorRing.length); + + var previousPoint = new Point(0, 0, 0, 0); + for (var i = 0; i < this.exteriorRing.length; i++) + this.exteriorRing[i]._writeTwkbPoint(twkb, precision, previousPoint); + + for (i = 0; i < this.interiorRings.length; i++) { + twkb.writeVarInt(this.interiorRings[i].length); + + for (var j = 0; j < this.interiorRings[i].length; j++) + this.interiorRings[i][j]._writeTwkbPoint(twkb, precision, previousPoint); + } + } + + return twkb.buffer; +}; + +Polygon.prototype._getWkbSize = function () { + var coordinateSize = 16; + + if (this.hasZ) + coordinateSize += 8; + if (this.hasM) + coordinateSize += 8; + + var size = 1 + 4 + 4; + + if (this.exteriorRing.length > 0) + size += 4 + (this.exteriorRing.length * coordinateSize); + + for (var i = 0; i < this.interiorRings.length; i++) + size += 4 + (this.interiorRings[i].length * coordinateSize); + + return size; +}; + +Polygon.prototype.toGeoJSON = function (options) { + var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); + geoJSON.type = Types.geoJSON.Polygon; + geoJSON.coordinates = []; + + if (this.exteriorRing.length > 0) { + var exteriorRing = []; + + for (var i = 0; i < this.exteriorRing.length; i++) { + if (this.hasZ) + exteriorRing.push([this.exteriorRing[i].x, this.exteriorRing[i].y, this.exteriorRing[i].z]); + else + exteriorRing.push([this.exteriorRing[i].x, this.exteriorRing[i].y]); + } + + geoJSON.coordinates.push(exteriorRing); + } + + for (var j = 0; j < this.interiorRings.length; j++) { + var interiorRing = []; + + for (var k = 0; k < this.interiorRings[j].length; k++) { + if (this.hasZ) + interiorRing.push([this.interiorRings[j][k].x, this.interiorRings[j][k].y, this.interiorRings[j][k].z]); + else + interiorRing.push([this.interiorRings[j][k].x, this.interiorRings[j][k].y]); + } + + geoJSON.coordinates.push(interiorRing); + } + + return geoJSON; +}; },{"./binarywriter":2,"./geometry":3,"./point":9,"./types":11,"util":20}],11:[function(require,module,exports){ -module.exports = { - wkt: { - Point: 'POINT', - LineString: 'LINESTRING', - Polygon: 'POLYGON', - MultiPoint: 'MULTIPOINT', - MultiLineString: 'MULTILINESTRING', - MultiPolygon: 'MULTIPOLYGON', - GeometryCollection: 'GEOMETRYCOLLECTION' - }, - wkb: { - Point: 1, - LineString: 2, - Polygon: 3, - MultiPoint: 4, - MultiLineString: 5, - MultiPolygon: 6, - GeometryCollection: 7 - }, - geoJSON: { - Point: 'Point', - LineString: 'LineString', - Polygon: 'Polygon', - MultiPoint: 'MultiPoint', - MultiLineString: 'MultiLineString', - MultiPolygon: 'MultiPolygon', - GeometryCollection: 'GeometryCollection' - } -}; +module.exports = { + wkt: { + Point: 'POINT', + LineString: 'LINESTRING', + Polygon: 'POLYGON', + MultiPoint: 'MULTIPOINT', + MultiLineString: 'MULTILINESTRING', + MultiPolygon: 'MULTIPOLYGON', + GeometryCollection: 'GEOMETRYCOLLECTION' + }, + wkb: { + Point: 1, + LineString: 2, + Polygon: 3, + MultiPoint: 4, + MultiLineString: 5, + MultiPolygon: 6, + GeometryCollection: 7 + }, + geoJSON: { + Point: 'Point', + LineString: 'LineString', + Polygon: 'Polygon', + MultiPoint: 'MultiPoint', + MultiLineString: 'MultiLineString', + MultiPolygon: 'MultiPolygon', + GeometryCollection: 'GeometryCollection' + } +}; },{}],12:[function(require,module,exports){ -module.exports = WktParser; - -var Types = require('./types'); -var Point = require('./point'); - -function WktParser(value) { - this.value = value; - this.position = 0; -} - -WktParser.prototype.match = function (tokens) { - this.skipWhitespaces(); - - for (var i = 0; i < tokens.length; i++) { - if (this.value.substring(this.position).indexOf(tokens[i]) === 0) { - this.position += tokens[i].length; - return tokens[i]; - } - } - - return null; -}; - -WktParser.prototype.matchRegex = function (tokens) { - this.skipWhitespaces(); - - for (var i = 0; i < tokens.length; i++) { - var match = this.value.substring(this.position).match(tokens[i]); - - if (match) { - this.position += match[0].length; - return match; - } - } - - return null; -}; - -WktParser.prototype.isMatch = function (tokens) { - this.skipWhitespaces(); - - for (var i = 0; i < tokens.length; i++) { - if (this.value.substring(this.position).indexOf(tokens[i]) === 0) { - this.position += tokens[i].length; - return true; - } - } - - return false; -}; - -WktParser.prototype.matchType = function () { - var geometryType = this.match([Types.wkt.Point, Types.wkt.LineString, Types.wkt.Polygon, Types.wkt.MultiPoint, - Types.wkt.MultiLineString, Types.wkt.MultiPolygon, Types.wkt.GeometryCollection]); - - if (!geometryType) - throw new Error('Expected geometry type'); - - return geometryType; -}; - -WktParser.prototype.matchDimension = function () { - var dimension = this.match(['ZM', 'Z', 'M']); - - switch (dimension) { - case 'ZM': return { hasZ: true, hasM: true }; - case 'Z': return { hasZ: true, hasM: false }; - case 'M': return { hasZ: false, hasM: true }; - default: return { hasZ: false, hasM: false }; - } -}; - -WktParser.prototype.expectGroupStart = function () { - if (!this.isMatch(['('])) - throw new Error('Expected group start'); -}; - -WktParser.prototype.expectGroupEnd = function () { - if (!this.isMatch([')'])) - throw new Error('Expected group end'); -}; - -WktParser.prototype.matchCoordinate = function (options) { - var match; - - if (options.hasZ && options.hasM) - match = this.matchRegex([/^(\S*)\s+(\S*)\s+(\S*)\s+([^\s,)]*)/]); - else if (options.hasZ || options.hasM) - match = this.matchRegex([/^(\S*)\s+(\S*)\s+([^\s,)]*)/]); - else - match = this.matchRegex([/^(\S*)\s+([^\s,)]*)/]); - - if (!match) - throw new Error('Expected coordinates'); - - if (options.hasZ && options.hasM) - return new Point(parseFloat(match[1]), parseFloat(match[2]), parseFloat(match[3]), parseFloat(match[4])); - else if (options.hasZ) - return new Point(parseFloat(match[1]), parseFloat(match[2]), parseFloat(match[3])); - else if (options.hasM) - return new Point(parseFloat(match[1]), parseFloat(match[2]), undefined, parseFloat(match[3])); - else - return new Point(parseFloat(match[1]), parseFloat(match[2])); -}; - -WktParser.prototype.matchCoordinates = function (options) { - var coordinates = []; - - do { - var startsWithBracket = this.isMatch(['(']); - - coordinates.push(this.matchCoordinate(options)); - - if (startsWithBracket) - this.expectGroupEnd(); - } while (this.isMatch([','])); - - return coordinates; -}; - -WktParser.prototype.skipWhitespaces = function () { - while (this.position < this.value.length && this.value[this.position] === ' ') - this.position++; -}; +module.exports = WktParser; + +var Types = require('./types'); +var Point = require('./point'); + +function WktParser(value) { + this.value = value; + this.position = 0; +} + +WktParser.prototype.match = function (tokens) { + this.skipWhitespaces(); + + for (var i = 0; i < tokens.length; i++) { + if (this.value.substring(this.position).indexOf(tokens[i]) === 0) { + this.position += tokens[i].length; + return tokens[i]; + } + } + + return null; +}; + +WktParser.prototype.matchRegex = function (tokens) { + this.skipWhitespaces(); + + for (var i = 0; i < tokens.length; i++) { + var match = this.value.substring(this.position).match(tokens[i]); + + if (match) { + this.position += match[0].length; + return match; + } + } + + return null; +}; + +WktParser.prototype.isMatch = function (tokens) { + this.skipWhitespaces(); + + for (var i = 0; i < tokens.length; i++) { + if (this.value.substring(this.position).indexOf(tokens[i]) === 0) { + this.position += tokens[i].length; + return true; + } + } + + return false; +}; + +WktParser.prototype.matchType = function () { + var geometryType = this.match([Types.wkt.Point, Types.wkt.LineString, Types.wkt.Polygon, Types.wkt.MultiPoint, + Types.wkt.MultiLineString, Types.wkt.MultiPolygon, Types.wkt.GeometryCollection]); + + if (!geometryType) + throw new Error('Expected geometry type'); + + return geometryType; +}; + +WktParser.prototype.matchDimension = function () { + var dimension = this.match(['ZM', 'Z', 'M']); + + switch (dimension) { + case 'ZM': return { hasZ: true, hasM: true }; + case 'Z': return { hasZ: true, hasM: false }; + case 'M': return { hasZ: false, hasM: true }; + default: return { hasZ: false, hasM: false }; + } +}; + +WktParser.prototype.expectGroupStart = function () { + if (!this.isMatch(['('])) + throw new Error('Expected group start'); +}; + +WktParser.prototype.expectGroupEnd = function () { + if (!this.isMatch([')'])) + throw new Error('Expected group end'); +}; + +WktParser.prototype.matchCoordinate = function (options) { + var match; + + if (options.hasZ && options.hasM) + match = this.matchRegex([/^(\S*)\s+(\S*)\s+(\S*)\s+([^\s,)]*)/]); + else if (options.hasZ || options.hasM) + match = this.matchRegex([/^(\S*)\s+(\S*)\s+([^\s,)]*)/]); + else + match = this.matchRegex([/^(\S*)\s+([^\s,)]*)/]); + + if (!match) + throw new Error('Expected coordinates'); + + if (options.hasZ && options.hasM) + return new Point(parseFloat(match[1]), parseFloat(match[2]), parseFloat(match[3]), parseFloat(match[4])); + else if (options.hasZ) + return new Point(parseFloat(match[1]), parseFloat(match[2]), parseFloat(match[3])); + else if (options.hasM) + return new Point(parseFloat(match[1]), parseFloat(match[2]), undefined, parseFloat(match[3])); + else + return new Point(parseFloat(match[1]), parseFloat(match[2])); +}; + +WktParser.prototype.matchCoordinates = function (options) { + var coordinates = []; + + do { + var startsWithBracket = this.isMatch(['(']); + + coordinates.push(this.matchCoordinate(options)); + + if (startsWithBracket) + this.expectGroupEnd(); + } while (this.isMatch([','])); + + return coordinates; +}; + +WktParser.prototype.skipWhitespaces = function () { + while (this.position < this.value.length && this.value[this.position] === ' ') + this.position++; +}; },{"./point":9,"./types":11}],13:[function(require,module,exports){ -module.exports = { - encode: function (value) { - return (value << 1) ^ (value >> 31); - }, - decode: function (value) { - return (value >> 1) ^ (-(value & 1)); - } -}; +module.exports = { + encode: function (value) { + return (value << 1) ^ (value >> 31); + }, + decode: function (value) { + return (value >> 1) ^ (-(value & 1)); + } +}; },{}],14:[function(require,module,exports){ 'use strict' @@ -5007,13 +5007,13 @@ var hexSliceLookupTable = (function () { }).call(this,require("buffer").Buffer) },{"base64-js":14,"buffer":"buffer","ieee754":15}],"wkx":[function(require,module,exports){ -exports.Types = require('./types'); -exports.Geometry = require('./geometry'); -exports.Point = require('./point'); -exports.LineString = require('./linestring'); -exports.Polygon = require('./polygon'); -exports.MultiPoint = require('./multipoint'); -exports.MultiLineString = require('./multilinestring'); -exports.MultiPolygon = require('./multipolygon'); +exports.Types = require('./types'); +exports.Geometry = require('./geometry'); +exports.Point = require('./point'); +exports.LineString = require('./linestring'); +exports.Polygon = require('./polygon'); +exports.MultiPoint = require('./multipoint'); +exports.MultiLineString = require('./multilinestring'); +exports.MultiPolygon = require('./multipolygon'); exports.GeometryCollection = require('./geometrycollection'); },{"./geometry":3,"./geometrycollection":4,"./linestring":5,"./multilinestring":6,"./multipoint":7,"./multipolygon":8,"./point":9,"./polygon":10,"./types":11}]},{},["wkx"]); diff --git a/backend/node_modules/wkx/lib/binaryreader.js b/backend/node_modules/wkx/lib/binaryreader.js index 4bb9115..1675337 100644 --- a/backend/node_modules/wkx/lib/binaryreader.js +++ b/backend/node_modules/wkx/lib/binaryreader.js @@ -1,47 +1,47 @@ -module.exports = BinaryReader; - -function BinaryReader(buffer, isBigEndian) { - this.buffer = buffer; - this.position = 0; - this.isBigEndian = isBigEndian || false; -} - -function _read(readLE, readBE, size) { - return function () { - var value; - - if (this.isBigEndian) - value = readBE.call(this.buffer, this.position); - else - value = readLE.call(this.buffer, this.position); - - this.position += size; - - return value; - }; -} - -BinaryReader.prototype.readUInt8 = _read(Buffer.prototype.readUInt8, Buffer.prototype.readUInt8, 1); -BinaryReader.prototype.readUInt16 = _read(Buffer.prototype.readUInt16LE, Buffer.prototype.readUInt16BE, 2); -BinaryReader.prototype.readUInt32 = _read(Buffer.prototype.readUInt32LE, Buffer.prototype.readUInt32BE, 4); -BinaryReader.prototype.readInt8 = _read(Buffer.prototype.readInt8, Buffer.prototype.readInt8, 1); -BinaryReader.prototype.readInt16 = _read(Buffer.prototype.readInt16LE, Buffer.prototype.readInt16BE, 2); -BinaryReader.prototype.readInt32 = _read(Buffer.prototype.readInt32LE, Buffer.prototype.readInt32BE, 4); -BinaryReader.prototype.readFloat = _read(Buffer.prototype.readFloatLE, Buffer.prototype.readFloatBE, 4); -BinaryReader.prototype.readDouble = _read(Buffer.prototype.readDoubleLE, Buffer.prototype.readDoubleBE, 8); - -BinaryReader.prototype.readVarInt = function () { - var nextByte, - result = 0, - bytesRead = 0; - - do { - nextByte = this.buffer[this.position + bytesRead]; - result += (nextByte & 0x7F) << (7 * bytesRead); - bytesRead++; - } while (nextByte >= 0x80); - - this.position += bytesRead; - - return result; -}; +module.exports = BinaryReader; + +function BinaryReader(buffer, isBigEndian) { + this.buffer = buffer; + this.position = 0; + this.isBigEndian = isBigEndian || false; +} + +function _read(readLE, readBE, size) { + return function () { + var value; + + if (this.isBigEndian) + value = readBE.call(this.buffer, this.position); + else + value = readLE.call(this.buffer, this.position); + + this.position += size; + + return value; + }; +} + +BinaryReader.prototype.readUInt8 = _read(Buffer.prototype.readUInt8, Buffer.prototype.readUInt8, 1); +BinaryReader.prototype.readUInt16 = _read(Buffer.prototype.readUInt16LE, Buffer.prototype.readUInt16BE, 2); +BinaryReader.prototype.readUInt32 = _read(Buffer.prototype.readUInt32LE, Buffer.prototype.readUInt32BE, 4); +BinaryReader.prototype.readInt8 = _read(Buffer.prototype.readInt8, Buffer.prototype.readInt8, 1); +BinaryReader.prototype.readInt16 = _read(Buffer.prototype.readInt16LE, Buffer.prototype.readInt16BE, 2); +BinaryReader.prototype.readInt32 = _read(Buffer.prototype.readInt32LE, Buffer.prototype.readInt32BE, 4); +BinaryReader.prototype.readFloat = _read(Buffer.prototype.readFloatLE, Buffer.prototype.readFloatBE, 4); +BinaryReader.prototype.readDouble = _read(Buffer.prototype.readDoubleLE, Buffer.prototype.readDoubleBE, 8); + +BinaryReader.prototype.readVarInt = function () { + var nextByte, + result = 0, + bytesRead = 0; + + do { + nextByte = this.buffer[this.position + bytesRead]; + result += (nextByte & 0x7F) << (7 * bytesRead); + bytesRead++; + } while (nextByte >= 0x80); + + this.position += bytesRead; + + return result; +}; diff --git a/backend/node_modules/wkx/lib/binarywriter.js b/backend/node_modules/wkx/lib/binarywriter.js index 0ce052b..99dc454 100644 --- a/backend/node_modules/wkx/lib/binarywriter.js +++ b/backend/node_modules/wkx/lib/binarywriter.js @@ -1,65 +1,65 @@ -module.exports = BinaryWriter; - -function BinaryWriter(size, allowResize) { - this.buffer = new Buffer(size); - this.position = 0; - this.allowResize = allowResize; -} - -function _write(write, size) { - return function (value, noAssert) { - this.ensureSize(size); - - write.call(this.buffer, value, this.position, noAssert); - this.position += size; - }; -} - -BinaryWriter.prototype.writeUInt8 = _write(Buffer.prototype.writeUInt8, 1); -BinaryWriter.prototype.writeUInt16LE = _write(Buffer.prototype.writeUInt16LE, 2); -BinaryWriter.prototype.writeUInt16BE = _write(Buffer.prototype.writeUInt16BE, 2); -BinaryWriter.prototype.writeUInt32LE = _write(Buffer.prototype.writeUInt32LE, 4); -BinaryWriter.prototype.writeUInt32BE = _write(Buffer.prototype.writeUInt32BE, 4); -BinaryWriter.prototype.writeInt8 = _write(Buffer.prototype.writeInt8, 1); -BinaryWriter.prototype.writeInt16LE = _write(Buffer.prototype.writeInt16LE, 2); -BinaryWriter.prototype.writeInt16BE = _write(Buffer.prototype.writeInt16BE, 2); -BinaryWriter.prototype.writeInt32LE = _write(Buffer.prototype.writeInt32LE, 4); -BinaryWriter.prototype.writeInt32BE = _write(Buffer.prototype.writeInt32BE, 4); -BinaryWriter.prototype.writeFloatLE = _write(Buffer.prototype.writeFloatLE, 4); -BinaryWriter.prototype.writeFloatBE = _write(Buffer.prototype.writeFloatBE, 4); -BinaryWriter.prototype.writeDoubleLE = _write(Buffer.prototype.writeDoubleLE, 8); -BinaryWriter.prototype.writeDoubleBE = _write(Buffer.prototype.writeDoubleBE, 8); - -BinaryWriter.prototype.writeBuffer = function (buffer) { - this.ensureSize(buffer.length); - - buffer.copy(this.buffer, this.position, 0, buffer.length); - this.position += buffer.length; -}; - -BinaryWriter.prototype.writeVarInt = function (value) { - var length = 1; - - while ((value & 0xFFFFFF80) !== 0) { - this.writeUInt8((value & 0x7F) | 0x80); - value >>>= 7; - length++; - } - - this.writeUInt8(value & 0x7F); - - return length; -}; - -BinaryWriter.prototype.ensureSize = function (size) { - if (this.buffer.length < this.position + size) { - if (this.allowResize) { - var tempBuffer = new Buffer(this.position + size); - this.buffer.copy(tempBuffer, 0, 0, this.buffer.length); - this.buffer = tempBuffer; - } - else { - throw new RangeError('index out of range'); - } - } -}; +module.exports = BinaryWriter; + +function BinaryWriter(size, allowResize) { + this.buffer = new Buffer(size); + this.position = 0; + this.allowResize = allowResize; +} + +function _write(write, size) { + return function (value, noAssert) { + this.ensureSize(size); + + write.call(this.buffer, value, this.position, noAssert); + this.position += size; + }; +} + +BinaryWriter.prototype.writeUInt8 = _write(Buffer.prototype.writeUInt8, 1); +BinaryWriter.prototype.writeUInt16LE = _write(Buffer.prototype.writeUInt16LE, 2); +BinaryWriter.prototype.writeUInt16BE = _write(Buffer.prototype.writeUInt16BE, 2); +BinaryWriter.prototype.writeUInt32LE = _write(Buffer.prototype.writeUInt32LE, 4); +BinaryWriter.prototype.writeUInt32BE = _write(Buffer.prototype.writeUInt32BE, 4); +BinaryWriter.prototype.writeInt8 = _write(Buffer.prototype.writeInt8, 1); +BinaryWriter.prototype.writeInt16LE = _write(Buffer.prototype.writeInt16LE, 2); +BinaryWriter.prototype.writeInt16BE = _write(Buffer.prototype.writeInt16BE, 2); +BinaryWriter.prototype.writeInt32LE = _write(Buffer.prototype.writeInt32LE, 4); +BinaryWriter.prototype.writeInt32BE = _write(Buffer.prototype.writeInt32BE, 4); +BinaryWriter.prototype.writeFloatLE = _write(Buffer.prototype.writeFloatLE, 4); +BinaryWriter.prototype.writeFloatBE = _write(Buffer.prototype.writeFloatBE, 4); +BinaryWriter.prototype.writeDoubleLE = _write(Buffer.prototype.writeDoubleLE, 8); +BinaryWriter.prototype.writeDoubleBE = _write(Buffer.prototype.writeDoubleBE, 8); + +BinaryWriter.prototype.writeBuffer = function (buffer) { + this.ensureSize(buffer.length); + + buffer.copy(this.buffer, this.position, 0, buffer.length); + this.position += buffer.length; +}; + +BinaryWriter.prototype.writeVarInt = function (value) { + var length = 1; + + while ((value & 0xFFFFFF80) !== 0) { + this.writeUInt8((value & 0x7F) | 0x80); + value >>>= 7; + length++; + } + + this.writeUInt8(value & 0x7F); + + return length; +}; + +BinaryWriter.prototype.ensureSize = function (size) { + if (this.buffer.length < this.position + size) { + if (this.allowResize) { + var tempBuffer = new Buffer(this.position + size); + this.buffer.copy(tempBuffer, 0, 0, this.buffer.length); + this.buffer = tempBuffer; + } + else { + throw new RangeError('index out of range'); + } + } +}; diff --git a/backend/node_modules/wkx/lib/geometry.js b/backend/node_modules/wkx/lib/geometry.js index a20a0d6..37d1bef 100644 --- a/backend/node_modules/wkx/lib/geometry.js +++ b/backend/node_modules/wkx/lib/geometry.js @@ -1,384 +1,384 @@ -module.exports = Geometry; - -var Types = require('./types'); -var Point = require('./point'); -var LineString = require('./linestring'); -var Polygon = require('./polygon'); -var MultiPoint = require('./multipoint'); -var MultiLineString = require('./multilinestring'); -var MultiPolygon = require('./multipolygon'); -var GeometryCollection = require('./geometrycollection'); -var BinaryReader = require('./binaryreader'); -var BinaryWriter = require('./binarywriter'); -var WktParser = require('./wktparser'); -var ZigZag = require('./zigzag.js'); - -function Geometry() { - this.srid = undefined; - this.hasZ = false; - this.hasM = false; -} - -Geometry.parse = function (value, options) { - var valueType = typeof value; - - if (valueType === 'string' || value instanceof WktParser) - return Geometry._parseWkt(value); - else if (Buffer.isBuffer(value) || value instanceof BinaryReader) - return Geometry._parseWkb(value, options); - else - throw new Error('first argument must be a string or Buffer'); -}; - -Geometry._parseWkt = function (value) { - var wktParser, - srid; - - if (value instanceof WktParser) - wktParser = value; - else - wktParser = new WktParser(value); - - var match = wktParser.matchRegex([/^SRID=(\d+);/]); - if (match) - srid = parseInt(match[1], 10); - - var geometryType = wktParser.matchType(); - var dimension = wktParser.matchDimension(); - - var options = { - srid: srid, - hasZ: dimension.hasZ, - hasM: dimension.hasM - }; - - switch (geometryType) { - case Types.wkt.Point: - return Point._parseWkt(wktParser, options); - case Types.wkt.LineString: - return LineString._parseWkt(wktParser, options); - case Types.wkt.Polygon: - return Polygon._parseWkt(wktParser, options); - case Types.wkt.MultiPoint: - return MultiPoint._parseWkt(wktParser, options); - case Types.wkt.MultiLineString: - return MultiLineString._parseWkt(wktParser, options); - case Types.wkt.MultiPolygon: - return MultiPolygon._parseWkt(wktParser, options); - case Types.wkt.GeometryCollection: - return GeometryCollection._parseWkt(wktParser, options); - } -}; - -Geometry._parseWkb = function (value, parentOptions) { - var binaryReader, - wkbType, - geometryType, - options = {}; - - if (value instanceof BinaryReader) - binaryReader = value; - else - binaryReader = new BinaryReader(value); - - binaryReader.isBigEndian = !binaryReader.readInt8(); - - wkbType = binaryReader.readUInt32(); - - options.hasSrid = (wkbType & 0x20000000) === 0x20000000; - options.isEwkb = (wkbType & 0x20000000) || (wkbType & 0x40000000) || (wkbType & 0x80000000); - - if (options.hasSrid) - options.srid = binaryReader.readUInt32(); - - options.hasZ = false; - options.hasM = false; - - if (!options.isEwkb && (!parentOptions || !parentOptions.isEwkb)) { - if (wkbType >= 1000 && wkbType < 2000) { - options.hasZ = true; - geometryType = wkbType - 1000; - } - else if (wkbType >= 2000 && wkbType < 3000) { - options.hasM = true; - geometryType = wkbType - 2000; - } - else if (wkbType >= 3000 && wkbType < 4000) { - options.hasZ = true; - options.hasM = true; - geometryType = wkbType - 3000; - } - else { - geometryType = wkbType; - } - } - else { - if (wkbType & 0x80000000) - options.hasZ = true; - if (wkbType & 0x40000000) - options.hasM = true; - - geometryType = wkbType & 0xF; - } - - switch (geometryType) { - case Types.wkb.Point: - return Point._parseWkb(binaryReader, options); - case Types.wkb.LineString: - return LineString._parseWkb(binaryReader, options); - case Types.wkb.Polygon: - return Polygon._parseWkb(binaryReader, options); - case Types.wkb.MultiPoint: - return MultiPoint._parseWkb(binaryReader, options); - case Types.wkb.MultiLineString: - return MultiLineString._parseWkb(binaryReader, options); - case Types.wkb.MultiPolygon: - return MultiPolygon._parseWkb(binaryReader, options); - case Types.wkb.GeometryCollection: - return GeometryCollection._parseWkb(binaryReader, options); - default: - throw new Error('GeometryType ' + geometryType + ' not supported'); - } -}; - -Geometry.parseTwkb = function (value) { - var binaryReader, - options = {}; - - if (value instanceof BinaryReader) - binaryReader = value; - else - binaryReader = new BinaryReader(value); - - var type = binaryReader.readUInt8(); - var metadataHeader = binaryReader.readUInt8(); - - var geometryType = type & 0x0F; - options.precision = ZigZag.decode(type >> 4); - options.precisionFactor = Math.pow(10, options.precision); - - options.hasBoundingBox = metadataHeader >> 0 & 1; - options.hasSizeAttribute = metadataHeader >> 1 & 1; - options.hasIdList = metadataHeader >> 2 & 1; - options.hasExtendedPrecision = metadataHeader >> 3 & 1; - options.isEmpty = metadataHeader >> 4 & 1; - - if (options.hasExtendedPrecision) { - var extendedPrecision = binaryReader.readUInt8(); - options.hasZ = (extendedPrecision & 0x01) === 0x01; - options.hasM = (extendedPrecision & 0x02) === 0x02; - - options.zPrecision = ZigZag.decode((extendedPrecision & 0x1C) >> 2); - options.zPrecisionFactor = Math.pow(10, options.zPrecision); - - options.mPrecision = ZigZag.decode((extendedPrecision & 0xE0) >> 5); - options.mPrecisionFactor = Math.pow(10, options.mPrecision); - } - else { - options.hasZ = false; - options.hasM = false; - } - - if (options.hasSizeAttribute) - binaryReader.readVarInt(); - if (options.hasBoundingBox) { - var dimensions = 2; - - if (options.hasZ) - dimensions++; - if (options.hasM) - dimensions++; - - for (var i = 0; i < dimensions; i++) { - binaryReader.readVarInt(); - binaryReader.readVarInt(); - } - } - - switch (geometryType) { - case Types.wkb.Point: - return Point._parseTwkb(binaryReader, options); - case Types.wkb.LineString: - return LineString._parseTwkb(binaryReader, options); - case Types.wkb.Polygon: - return Polygon._parseTwkb(binaryReader, options); - case Types.wkb.MultiPoint: - return MultiPoint._parseTwkb(binaryReader, options); - case Types.wkb.MultiLineString: - return MultiLineString._parseTwkb(binaryReader, options); - case Types.wkb.MultiPolygon: - return MultiPolygon._parseTwkb(binaryReader, options); - case Types.wkb.GeometryCollection: - return GeometryCollection._parseTwkb(binaryReader, options); - default: - throw new Error('GeometryType ' + geometryType + ' not supported'); - } -}; - -Geometry.parseGeoJSON = function (value) { - return Geometry._parseGeoJSON(value); -}; - -Geometry._parseGeoJSON = function (value, isSubGeometry) { - var geometry; - - switch (value.type) { - case Types.geoJSON.Point: - geometry = Point._parseGeoJSON(value); break; - case Types.geoJSON.LineString: - geometry = LineString._parseGeoJSON(value); break; - case Types.geoJSON.Polygon: - geometry = Polygon._parseGeoJSON(value); break; - case Types.geoJSON.MultiPoint: - geometry = MultiPoint._parseGeoJSON(value); break; - case Types.geoJSON.MultiLineString: - geometry = MultiLineString._parseGeoJSON(value); break; - case Types.geoJSON.MultiPolygon: - geometry = MultiPolygon._parseGeoJSON(value); break; - case Types.geoJSON.GeometryCollection: - geometry = GeometryCollection._parseGeoJSON(value); break; - default: - throw new Error('GeometryType ' + value.type + ' not supported'); - } - - if (value.crs && value.crs.type && value.crs.type === 'name' && value.crs.properties && value.crs.properties.name) { - var crs = value.crs.properties.name; - - if (crs.indexOf('EPSG:') === 0) - geometry.srid = parseInt(crs.substring(5)); - else if (crs.indexOf('urn:ogc:def:crs:EPSG::') === 0) - geometry.srid = parseInt(crs.substring(22)); - else - throw new Error('Unsupported crs: ' + crs); - } - else if (!isSubGeometry) { - geometry.srid = 4326; - } - - return geometry; -}; - -Geometry.prototype.toEwkt = function () { - return 'SRID=' + this.srid + ';' + this.toWkt(); -}; - -Geometry.prototype.toEwkb = function () { - var ewkb = new BinaryWriter(this._getWkbSize() + 4); - var wkb = this.toWkb(); - - ewkb.writeInt8(1); - ewkb.writeUInt32LE((wkb.slice(1, 5).readUInt32LE(0) | 0x20000000) >>> 0, true); - ewkb.writeUInt32LE(this.srid); - - ewkb.writeBuffer(wkb.slice(5)); - - return ewkb.buffer; -}; - -Geometry.prototype._getWktType = function (wktType, isEmpty) { - var wkt = wktType; - - if (this.hasZ && this.hasM) - wkt += ' ZM '; - else if (this.hasZ) - wkt += ' Z '; - else if (this.hasM) - wkt += ' M '; - - if (isEmpty && !this.hasZ && !this.hasM) - wkt += ' '; - - if (isEmpty) - wkt += 'EMPTY'; - - return wkt; -}; - -Geometry.prototype._getWktCoordinate = function (point) { - var coordinates = point.x + ' ' + point.y; - - if (this.hasZ) - coordinates += ' ' + point.z; - if (this.hasM) - coordinates += ' ' + point.m; - - return coordinates; -}; - -Geometry.prototype._writeWkbType = function (wkb, geometryType, parentOptions) { - var dimensionType = 0; - - if (typeof this.srid === 'undefined' && (!parentOptions || typeof parentOptions.srid === 'undefined')) { - if (this.hasZ && this.hasM) - dimensionType += 3000; - else if (this.hasZ) - dimensionType += 1000; - else if (this.hasM) - dimensionType += 2000; - } - else { - if (this.hasZ) - dimensionType |= 0x80000000; - if (this.hasM) - dimensionType |= 0x40000000; - } - - wkb.writeUInt32LE((dimensionType + geometryType) >>> 0, true); -}; - -Geometry.getTwkbPrecision = function (xyPrecision, zPrecision, mPrecision) { - return { - xy: xyPrecision, - z: zPrecision, - m: mPrecision, - xyFactor: Math.pow(10, xyPrecision), - zFactor: Math.pow(10, zPrecision), - mFactor: Math.pow(10, mPrecision) - }; -}; - -Geometry.prototype._writeTwkbHeader = function (twkb, geometryType, precision, isEmpty) { - var type = (ZigZag.encode(precision.xy) << 4) + geometryType; - var metadataHeader = (this.hasZ || this.hasM) << 3; - metadataHeader += isEmpty << 4; - - twkb.writeUInt8(type); - twkb.writeUInt8(metadataHeader); - - if (this.hasZ || this.hasM) { - var extendedPrecision = 0; - if (this.hasZ) - extendedPrecision |= 0x1; - if (this.hasM) - extendedPrecision |= 0x2; - - twkb.writeUInt8(extendedPrecision); - } -}; - -Geometry.prototype.toGeoJSON = function (options) { - var geoJSON = {}; - - if (this.srid) { - if (options) { - if (options.shortCrs) { - geoJSON.crs = { - type: 'name', - properties: { - name: 'EPSG:' + this.srid - } - }; - } - else if (options.longCrs) { - geoJSON.crs = { - type: 'name', - properties: { - name: 'urn:ogc:def:crs:EPSG::' + this.srid - } - }; - } - } - } - - return geoJSON; -}; +module.exports = Geometry; + +var Types = require('./types'); +var Point = require('./point'); +var LineString = require('./linestring'); +var Polygon = require('./polygon'); +var MultiPoint = require('./multipoint'); +var MultiLineString = require('./multilinestring'); +var MultiPolygon = require('./multipolygon'); +var GeometryCollection = require('./geometrycollection'); +var BinaryReader = require('./binaryreader'); +var BinaryWriter = require('./binarywriter'); +var WktParser = require('./wktparser'); +var ZigZag = require('./zigzag.js'); + +function Geometry() { + this.srid = undefined; + this.hasZ = false; + this.hasM = false; +} + +Geometry.parse = function (value, options) { + var valueType = typeof value; + + if (valueType === 'string' || value instanceof WktParser) + return Geometry._parseWkt(value); + else if (Buffer.isBuffer(value) || value instanceof BinaryReader) + return Geometry._parseWkb(value, options); + else + throw new Error('first argument must be a string or Buffer'); +}; + +Geometry._parseWkt = function (value) { + var wktParser, + srid; + + if (value instanceof WktParser) + wktParser = value; + else + wktParser = new WktParser(value); + + var match = wktParser.matchRegex([/^SRID=(\d+);/]); + if (match) + srid = parseInt(match[1], 10); + + var geometryType = wktParser.matchType(); + var dimension = wktParser.matchDimension(); + + var options = { + srid: srid, + hasZ: dimension.hasZ, + hasM: dimension.hasM + }; + + switch (geometryType) { + case Types.wkt.Point: + return Point._parseWkt(wktParser, options); + case Types.wkt.LineString: + return LineString._parseWkt(wktParser, options); + case Types.wkt.Polygon: + return Polygon._parseWkt(wktParser, options); + case Types.wkt.MultiPoint: + return MultiPoint._parseWkt(wktParser, options); + case Types.wkt.MultiLineString: + return MultiLineString._parseWkt(wktParser, options); + case Types.wkt.MultiPolygon: + return MultiPolygon._parseWkt(wktParser, options); + case Types.wkt.GeometryCollection: + return GeometryCollection._parseWkt(wktParser, options); + } +}; + +Geometry._parseWkb = function (value, parentOptions) { + var binaryReader, + wkbType, + geometryType, + options = {}; + + if (value instanceof BinaryReader) + binaryReader = value; + else + binaryReader = new BinaryReader(value); + + binaryReader.isBigEndian = !binaryReader.readInt8(); + + wkbType = binaryReader.readUInt32(); + + options.hasSrid = (wkbType & 0x20000000) === 0x20000000; + options.isEwkb = (wkbType & 0x20000000) || (wkbType & 0x40000000) || (wkbType & 0x80000000); + + if (options.hasSrid) + options.srid = binaryReader.readUInt32(); + + options.hasZ = false; + options.hasM = false; + + if (!options.isEwkb && (!parentOptions || !parentOptions.isEwkb)) { + if (wkbType >= 1000 && wkbType < 2000) { + options.hasZ = true; + geometryType = wkbType - 1000; + } + else if (wkbType >= 2000 && wkbType < 3000) { + options.hasM = true; + geometryType = wkbType - 2000; + } + else if (wkbType >= 3000 && wkbType < 4000) { + options.hasZ = true; + options.hasM = true; + geometryType = wkbType - 3000; + } + else { + geometryType = wkbType; + } + } + else { + if (wkbType & 0x80000000) + options.hasZ = true; + if (wkbType & 0x40000000) + options.hasM = true; + + geometryType = wkbType & 0xF; + } + + switch (geometryType) { + case Types.wkb.Point: + return Point._parseWkb(binaryReader, options); + case Types.wkb.LineString: + return LineString._parseWkb(binaryReader, options); + case Types.wkb.Polygon: + return Polygon._parseWkb(binaryReader, options); + case Types.wkb.MultiPoint: + return MultiPoint._parseWkb(binaryReader, options); + case Types.wkb.MultiLineString: + return MultiLineString._parseWkb(binaryReader, options); + case Types.wkb.MultiPolygon: + return MultiPolygon._parseWkb(binaryReader, options); + case Types.wkb.GeometryCollection: + return GeometryCollection._parseWkb(binaryReader, options); + default: + throw new Error('GeometryType ' + geometryType + ' not supported'); + } +}; + +Geometry.parseTwkb = function (value) { + var binaryReader, + options = {}; + + if (value instanceof BinaryReader) + binaryReader = value; + else + binaryReader = new BinaryReader(value); + + var type = binaryReader.readUInt8(); + var metadataHeader = binaryReader.readUInt8(); + + var geometryType = type & 0x0F; + options.precision = ZigZag.decode(type >> 4); + options.precisionFactor = Math.pow(10, options.precision); + + options.hasBoundingBox = metadataHeader >> 0 & 1; + options.hasSizeAttribute = metadataHeader >> 1 & 1; + options.hasIdList = metadataHeader >> 2 & 1; + options.hasExtendedPrecision = metadataHeader >> 3 & 1; + options.isEmpty = metadataHeader >> 4 & 1; + + if (options.hasExtendedPrecision) { + var extendedPrecision = binaryReader.readUInt8(); + options.hasZ = (extendedPrecision & 0x01) === 0x01; + options.hasM = (extendedPrecision & 0x02) === 0x02; + + options.zPrecision = ZigZag.decode((extendedPrecision & 0x1C) >> 2); + options.zPrecisionFactor = Math.pow(10, options.zPrecision); + + options.mPrecision = ZigZag.decode((extendedPrecision & 0xE0) >> 5); + options.mPrecisionFactor = Math.pow(10, options.mPrecision); + } + else { + options.hasZ = false; + options.hasM = false; + } + + if (options.hasSizeAttribute) + binaryReader.readVarInt(); + if (options.hasBoundingBox) { + var dimensions = 2; + + if (options.hasZ) + dimensions++; + if (options.hasM) + dimensions++; + + for (var i = 0; i < dimensions; i++) { + binaryReader.readVarInt(); + binaryReader.readVarInt(); + } + } + + switch (geometryType) { + case Types.wkb.Point: + return Point._parseTwkb(binaryReader, options); + case Types.wkb.LineString: + return LineString._parseTwkb(binaryReader, options); + case Types.wkb.Polygon: + return Polygon._parseTwkb(binaryReader, options); + case Types.wkb.MultiPoint: + return MultiPoint._parseTwkb(binaryReader, options); + case Types.wkb.MultiLineString: + return MultiLineString._parseTwkb(binaryReader, options); + case Types.wkb.MultiPolygon: + return MultiPolygon._parseTwkb(binaryReader, options); + case Types.wkb.GeometryCollection: + return GeometryCollection._parseTwkb(binaryReader, options); + default: + throw new Error('GeometryType ' + geometryType + ' not supported'); + } +}; + +Geometry.parseGeoJSON = function (value) { + return Geometry._parseGeoJSON(value); +}; + +Geometry._parseGeoJSON = function (value, isSubGeometry) { + var geometry; + + switch (value.type) { + case Types.geoJSON.Point: + geometry = Point._parseGeoJSON(value); break; + case Types.geoJSON.LineString: + geometry = LineString._parseGeoJSON(value); break; + case Types.geoJSON.Polygon: + geometry = Polygon._parseGeoJSON(value); break; + case Types.geoJSON.MultiPoint: + geometry = MultiPoint._parseGeoJSON(value); break; + case Types.geoJSON.MultiLineString: + geometry = MultiLineString._parseGeoJSON(value); break; + case Types.geoJSON.MultiPolygon: + geometry = MultiPolygon._parseGeoJSON(value); break; + case Types.geoJSON.GeometryCollection: + geometry = GeometryCollection._parseGeoJSON(value); break; + default: + throw new Error('GeometryType ' + value.type + ' not supported'); + } + + if (value.crs && value.crs.type && value.crs.type === 'name' && value.crs.properties && value.crs.properties.name) { + var crs = value.crs.properties.name; + + if (crs.indexOf('EPSG:') === 0) + geometry.srid = parseInt(crs.substring(5)); + else if (crs.indexOf('urn:ogc:def:crs:EPSG::') === 0) + geometry.srid = parseInt(crs.substring(22)); + else + throw new Error('Unsupported crs: ' + crs); + } + else if (!isSubGeometry) { + geometry.srid = 4326; + } + + return geometry; +}; + +Geometry.prototype.toEwkt = function () { + return 'SRID=' + this.srid + ';' + this.toWkt(); +}; + +Geometry.prototype.toEwkb = function () { + var ewkb = new BinaryWriter(this._getWkbSize() + 4); + var wkb = this.toWkb(); + + ewkb.writeInt8(1); + ewkb.writeUInt32LE((wkb.slice(1, 5).readUInt32LE(0) | 0x20000000) >>> 0, true); + ewkb.writeUInt32LE(this.srid); + + ewkb.writeBuffer(wkb.slice(5)); + + return ewkb.buffer; +}; + +Geometry.prototype._getWktType = function (wktType, isEmpty) { + var wkt = wktType; + + if (this.hasZ && this.hasM) + wkt += ' ZM '; + else if (this.hasZ) + wkt += ' Z '; + else if (this.hasM) + wkt += ' M '; + + if (isEmpty && !this.hasZ && !this.hasM) + wkt += ' '; + + if (isEmpty) + wkt += 'EMPTY'; + + return wkt; +}; + +Geometry.prototype._getWktCoordinate = function (point) { + var coordinates = point.x + ' ' + point.y; + + if (this.hasZ) + coordinates += ' ' + point.z; + if (this.hasM) + coordinates += ' ' + point.m; + + return coordinates; +}; + +Geometry.prototype._writeWkbType = function (wkb, geometryType, parentOptions) { + var dimensionType = 0; + + if (typeof this.srid === 'undefined' && (!parentOptions || typeof parentOptions.srid === 'undefined')) { + if (this.hasZ && this.hasM) + dimensionType += 3000; + else if (this.hasZ) + dimensionType += 1000; + else if (this.hasM) + dimensionType += 2000; + } + else { + if (this.hasZ) + dimensionType |= 0x80000000; + if (this.hasM) + dimensionType |= 0x40000000; + } + + wkb.writeUInt32LE((dimensionType + geometryType) >>> 0, true); +}; + +Geometry.getTwkbPrecision = function (xyPrecision, zPrecision, mPrecision) { + return { + xy: xyPrecision, + z: zPrecision, + m: mPrecision, + xyFactor: Math.pow(10, xyPrecision), + zFactor: Math.pow(10, zPrecision), + mFactor: Math.pow(10, mPrecision) + }; +}; + +Geometry.prototype._writeTwkbHeader = function (twkb, geometryType, precision, isEmpty) { + var type = (ZigZag.encode(precision.xy) << 4) + geometryType; + var metadataHeader = (this.hasZ || this.hasM) << 3; + metadataHeader += isEmpty << 4; + + twkb.writeUInt8(type); + twkb.writeUInt8(metadataHeader); + + if (this.hasZ || this.hasM) { + var extendedPrecision = 0; + if (this.hasZ) + extendedPrecision |= 0x1; + if (this.hasM) + extendedPrecision |= 0x2; + + twkb.writeUInt8(extendedPrecision); + } +}; + +Geometry.prototype.toGeoJSON = function (options) { + var geoJSON = {}; + + if (this.srid) { + if (options) { + if (options.shortCrs) { + geoJSON.crs = { + type: 'name', + properties: { + name: 'EPSG:' + this.srid + } + }; + } + else if (options.longCrs) { + geoJSON.crs = { + type: 'name', + properties: { + name: 'urn:ogc:def:crs:EPSG::' + this.srid + } + }; + } + } + } + + return geoJSON; +}; diff --git a/backend/node_modules/wkx/lib/geometrycollection.js b/backend/node_modules/wkx/lib/geometrycollection.js index 393c16a..a886111 100644 --- a/backend/node_modules/wkx/lib/geometrycollection.js +++ b/backend/node_modules/wkx/lib/geometrycollection.js @@ -1,169 +1,169 @@ -module.exports = GeometryCollection; - -var util = require('util'); - -var Types = require('./types'); -var Geometry = require('./geometry'); -var BinaryWriter = require('./binarywriter'); - -function GeometryCollection(geometries, srid) { - Geometry.call(this); - - this.geometries = geometries || []; - this.srid = srid; - - if (this.geometries.length > 0) { - this.hasZ = this.geometries[0].hasZ; - this.hasM = this.geometries[0].hasM; - } -} - -util.inherits(GeometryCollection, Geometry); - -GeometryCollection.Z = function (geometries, srid) { - var geometryCollection = new GeometryCollection(geometries, srid); - geometryCollection.hasZ = true; - return geometryCollection; -}; - -GeometryCollection.M = function (geometries, srid) { - var geometryCollection = new GeometryCollection(geometries, srid); - geometryCollection.hasM = true; - return geometryCollection; -}; - -GeometryCollection.ZM = function (geometries, srid) { - var geometryCollection = new GeometryCollection(geometries, srid); - geometryCollection.hasZ = true; - geometryCollection.hasM = true; - return geometryCollection; -}; - -GeometryCollection._parseWkt = function (value, options) { - var geometryCollection = new GeometryCollection(); - geometryCollection.srid = options.srid; - geometryCollection.hasZ = options.hasZ; - geometryCollection.hasM = options.hasM; - - if (value.isMatch(['EMPTY'])) - return geometryCollection; - - value.expectGroupStart(); - - do { - geometryCollection.geometries.push(Geometry.parse(value)); - } while (value.isMatch([','])); - - value.expectGroupEnd(); - - return geometryCollection; -}; - -GeometryCollection._parseWkb = function (value, options) { - var geometryCollection = new GeometryCollection(); - geometryCollection.srid = options.srid; - geometryCollection.hasZ = options.hasZ; - geometryCollection.hasM = options.hasM; - - var geometryCount = value.readUInt32(); - - for (var i = 0; i < geometryCount; i++) - geometryCollection.geometries.push(Geometry.parse(value, options)); - - return geometryCollection; -}; - -GeometryCollection._parseTwkb = function (value, options) { - var geometryCollection = new GeometryCollection(); - geometryCollection.hasZ = options.hasZ; - geometryCollection.hasM = options.hasM; - - if (options.isEmpty) - return geometryCollection; - - var geometryCount = value.readVarInt(); - - for (var i = 0; i < geometryCount; i++) - geometryCollection.geometries.push(Geometry.parseTwkb(value)); - - return geometryCollection; -}; - -GeometryCollection._parseGeoJSON = function (value) { - var geometryCollection = new GeometryCollection(); - - for (var i = 0; i < value.geometries.length; i++) - geometryCollection.geometries.push(Geometry._parseGeoJSON(value.geometries[i], true)); - - if (geometryCollection.geometries.length > 0) - geometryCollection.hasZ = geometryCollection.geometries[0].hasZ; - - return geometryCollection; -}; - -GeometryCollection.prototype.toWkt = function () { - if (this.geometries.length === 0) - return this._getWktType(Types.wkt.GeometryCollection, true); - - var wkt = this._getWktType(Types.wkt.GeometryCollection, false) + '('; - - for (var i = 0; i < this.geometries.length; i++) - wkt += this.geometries[i].toWkt() + ','; - - wkt = wkt.slice(0, -1); - wkt += ')'; - - return wkt; -}; - -GeometryCollection.prototype.toWkb = function () { - var wkb = new BinaryWriter(this._getWkbSize()); - - wkb.writeInt8(1); - - this._writeWkbType(wkb, Types.wkb.GeometryCollection); - wkb.writeUInt32LE(this.geometries.length); - - for (var i = 0; i < this.geometries.length; i++) - wkb.writeBuffer(this.geometries[i].toWkb({ srid: this.srid })); - - return wkb.buffer; -}; - -GeometryCollection.prototype.toTwkb = function () { - var twkb = new BinaryWriter(0, true); - - var precision = Geometry.getTwkbPrecision(5, 0, 0); - var isEmpty = this.geometries.length === 0; - - this._writeTwkbHeader(twkb, Types.wkb.GeometryCollection, precision, isEmpty); - - if (this.geometries.length > 0) { - twkb.writeVarInt(this.geometries.length); - - for (var i = 0; i < this.geometries.length; i++) - twkb.writeBuffer(this.geometries[i].toTwkb()); - } - - return twkb.buffer; -}; - -GeometryCollection.prototype._getWkbSize = function () { - var size = 1 + 4 + 4; - - for (var i = 0; i < this.geometries.length; i++) - size += this.geometries[i]._getWkbSize(); - - return size; -}; - -GeometryCollection.prototype.toGeoJSON = function (options) { - var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); - geoJSON.type = Types.geoJSON.GeometryCollection; - geoJSON.geometries = []; - - for (var i = 0; i < this.geometries.length; i++) - geoJSON.geometries.push(this.geometries[i].toGeoJSON()); - - return geoJSON; -}; +module.exports = GeometryCollection; + +var util = require('util'); + +var Types = require('./types'); +var Geometry = require('./geometry'); +var BinaryWriter = require('./binarywriter'); + +function GeometryCollection(geometries, srid) { + Geometry.call(this); + + this.geometries = geometries || []; + this.srid = srid; + + if (this.geometries.length > 0) { + this.hasZ = this.geometries[0].hasZ; + this.hasM = this.geometries[0].hasM; + } +} + +util.inherits(GeometryCollection, Geometry); + +GeometryCollection.Z = function (geometries, srid) { + var geometryCollection = new GeometryCollection(geometries, srid); + geometryCollection.hasZ = true; + return geometryCollection; +}; + +GeometryCollection.M = function (geometries, srid) { + var geometryCollection = new GeometryCollection(geometries, srid); + geometryCollection.hasM = true; + return geometryCollection; +}; + +GeometryCollection.ZM = function (geometries, srid) { + var geometryCollection = new GeometryCollection(geometries, srid); + geometryCollection.hasZ = true; + geometryCollection.hasM = true; + return geometryCollection; +}; + +GeometryCollection._parseWkt = function (value, options) { + var geometryCollection = new GeometryCollection(); + geometryCollection.srid = options.srid; + geometryCollection.hasZ = options.hasZ; + geometryCollection.hasM = options.hasM; + + if (value.isMatch(['EMPTY'])) + return geometryCollection; + + value.expectGroupStart(); + + do { + geometryCollection.geometries.push(Geometry.parse(value)); + } while (value.isMatch([','])); + + value.expectGroupEnd(); + + return geometryCollection; +}; + +GeometryCollection._parseWkb = function (value, options) { + var geometryCollection = new GeometryCollection(); + geometryCollection.srid = options.srid; + geometryCollection.hasZ = options.hasZ; + geometryCollection.hasM = options.hasM; + + var geometryCount = value.readUInt32(); + + for (var i = 0; i < geometryCount; i++) + geometryCollection.geometries.push(Geometry.parse(value, options)); + + return geometryCollection; +}; + +GeometryCollection._parseTwkb = function (value, options) { + var geometryCollection = new GeometryCollection(); + geometryCollection.hasZ = options.hasZ; + geometryCollection.hasM = options.hasM; + + if (options.isEmpty) + return geometryCollection; + + var geometryCount = value.readVarInt(); + + for (var i = 0; i < geometryCount; i++) + geometryCollection.geometries.push(Geometry.parseTwkb(value)); + + return geometryCollection; +}; + +GeometryCollection._parseGeoJSON = function (value) { + var geometryCollection = new GeometryCollection(); + + for (var i = 0; i < value.geometries.length; i++) + geometryCollection.geometries.push(Geometry._parseGeoJSON(value.geometries[i], true)); + + if (geometryCollection.geometries.length > 0) + geometryCollection.hasZ = geometryCollection.geometries[0].hasZ; + + return geometryCollection; +}; + +GeometryCollection.prototype.toWkt = function () { + if (this.geometries.length === 0) + return this._getWktType(Types.wkt.GeometryCollection, true); + + var wkt = this._getWktType(Types.wkt.GeometryCollection, false) + '('; + + for (var i = 0; i < this.geometries.length; i++) + wkt += this.geometries[i].toWkt() + ','; + + wkt = wkt.slice(0, -1); + wkt += ')'; + + return wkt; +}; + +GeometryCollection.prototype.toWkb = function () { + var wkb = new BinaryWriter(this._getWkbSize()); + + wkb.writeInt8(1); + + this._writeWkbType(wkb, Types.wkb.GeometryCollection); + wkb.writeUInt32LE(this.geometries.length); + + for (var i = 0; i < this.geometries.length; i++) + wkb.writeBuffer(this.geometries[i].toWkb({ srid: this.srid })); + + return wkb.buffer; +}; + +GeometryCollection.prototype.toTwkb = function () { + var twkb = new BinaryWriter(0, true); + + var precision = Geometry.getTwkbPrecision(5, 0, 0); + var isEmpty = this.geometries.length === 0; + + this._writeTwkbHeader(twkb, Types.wkb.GeometryCollection, precision, isEmpty); + + if (this.geometries.length > 0) { + twkb.writeVarInt(this.geometries.length); + + for (var i = 0; i < this.geometries.length; i++) + twkb.writeBuffer(this.geometries[i].toTwkb()); + } + + return twkb.buffer; +}; + +GeometryCollection.prototype._getWkbSize = function () { + var size = 1 + 4 + 4; + + for (var i = 0; i < this.geometries.length; i++) + size += this.geometries[i]._getWkbSize(); + + return size; +}; + +GeometryCollection.prototype.toGeoJSON = function (options) { + var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); + geoJSON.type = Types.geoJSON.GeometryCollection; + geoJSON.geometries = []; + + for (var i = 0; i < this.geometries.length; i++) + geoJSON.geometries.push(this.geometries[i].toGeoJSON()); + + return geoJSON; +}; diff --git a/backend/node_modules/wkx/lib/linestring.js b/backend/node_modules/wkx/lib/linestring.js index 86ca088..fd245d9 100644 --- a/backend/node_modules/wkx/lib/linestring.js +++ b/backend/node_modules/wkx/lib/linestring.js @@ -1,178 +1,178 @@ -module.exports = LineString; - -var util = require('util'); - -var Geometry = require('./geometry'); -var Types = require('./types'); -var Point = require('./point'); -var BinaryWriter = require('./binarywriter'); - -function LineString(points, srid) { - Geometry.call(this); - - this.points = points || []; - this.srid = srid; - - if (this.points.length > 0) { - this.hasZ = this.points[0].hasZ; - this.hasM = this.points[0].hasM; - } -} - -util.inherits(LineString, Geometry); - -LineString.Z = function (points, srid) { - var lineString = new LineString(points, srid); - lineString.hasZ = true; - return lineString; -}; - -LineString.M = function (points, srid) { - var lineString = new LineString(points, srid); - lineString.hasM = true; - return lineString; -}; - -LineString.ZM = function (points, srid) { - var lineString = new LineString(points, srid); - lineString.hasZ = true; - lineString.hasM = true; - return lineString; -}; - -LineString._parseWkt = function (value, options) { - var lineString = new LineString(); - lineString.srid = options.srid; - lineString.hasZ = options.hasZ; - lineString.hasM = options.hasM; - - if (value.isMatch(['EMPTY'])) - return lineString; - - value.expectGroupStart(); - lineString.points.push.apply(lineString.points, value.matchCoordinates(options)); - value.expectGroupEnd(); - - return lineString; -}; - -LineString._parseWkb = function (value, options) { - var lineString = new LineString(); - lineString.srid = options.srid; - lineString.hasZ = options.hasZ; - lineString.hasM = options.hasM; - - var pointCount = value.readUInt32(); - - for (var i = 0; i < pointCount; i++) - lineString.points.push(Point._readWkbPoint(value, options)); - - return lineString; -}; - -LineString._parseTwkb = function (value, options) { - var lineString = new LineString(); - lineString.hasZ = options.hasZ; - lineString.hasM = options.hasM; - - if (options.isEmpty) - return lineString; - - var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); - var pointCount = value.readVarInt(); - - for (var i = 0; i < pointCount; i++) - lineString.points.push(Point._readTwkbPoint(value, options, previousPoint)); - - return lineString; -}; - -LineString._parseGeoJSON = function (value) { - var lineString = new LineString(); - - if (value.coordinates.length > 0) - lineString.hasZ = value.coordinates[0].length > 2; - - for (var i = 0; i < value.coordinates.length; i++) - lineString.points.push(Point._readGeoJSONPoint(value.coordinates[i])); - - return lineString; -}; - -LineString.prototype.toWkt = function () { - if (this.points.length === 0) - return this._getWktType(Types.wkt.LineString, true); - - return this._getWktType(Types.wkt.LineString, false) + this._toInnerWkt(); -}; - -LineString.prototype._toInnerWkt = function () { - var innerWkt = '('; - - for (var i = 0; i < this.points.length; i++) - innerWkt += this._getWktCoordinate(this.points[i]) + ','; - - innerWkt = innerWkt.slice(0, -1); - innerWkt += ')'; - - return innerWkt; -}; - -LineString.prototype.toWkb = function (parentOptions) { - var wkb = new BinaryWriter(this._getWkbSize()); - - wkb.writeInt8(1); - - this._writeWkbType(wkb, Types.wkb.LineString, parentOptions); - wkb.writeUInt32LE(this.points.length); - - for (var i = 0; i < this.points.length; i++) - this.points[i]._writeWkbPoint(wkb); - - return wkb.buffer; -}; - -LineString.prototype.toTwkb = function () { - var twkb = new BinaryWriter(0, true); - - var precision = Geometry.getTwkbPrecision(5, 0, 0); - var isEmpty = this.points.length === 0; - - this._writeTwkbHeader(twkb, Types.wkb.LineString, precision, isEmpty); - - if (this.points.length > 0) { - twkb.writeVarInt(this.points.length); - - var previousPoint = new Point(0, 0, 0, 0); - for (var i = 0; i < this.points.length; i++) - this.points[i]._writeTwkbPoint(twkb, precision, previousPoint); - } - - return twkb.buffer; -}; - -LineString.prototype._getWkbSize = function () { - var coordinateSize = 16; - - if (this.hasZ) - coordinateSize += 8; - if (this.hasM) - coordinateSize += 8; - - return 1 + 4 + 4 + (this.points.length * coordinateSize); -}; - -LineString.prototype.toGeoJSON = function (options) { - var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); - geoJSON.type = Types.geoJSON.LineString; - geoJSON.coordinates = []; - - for (var i = 0; i < this.points.length; i++) { - if (this.hasZ) - geoJSON.coordinates.push([this.points[i].x, this.points[i].y, this.points[i].z]); - else - geoJSON.coordinates.push([this.points[i].x, this.points[i].y]); - } - - return geoJSON; -}; +module.exports = LineString; + +var util = require('util'); + +var Geometry = require('./geometry'); +var Types = require('./types'); +var Point = require('./point'); +var BinaryWriter = require('./binarywriter'); + +function LineString(points, srid) { + Geometry.call(this); + + this.points = points || []; + this.srid = srid; + + if (this.points.length > 0) { + this.hasZ = this.points[0].hasZ; + this.hasM = this.points[0].hasM; + } +} + +util.inherits(LineString, Geometry); + +LineString.Z = function (points, srid) { + var lineString = new LineString(points, srid); + lineString.hasZ = true; + return lineString; +}; + +LineString.M = function (points, srid) { + var lineString = new LineString(points, srid); + lineString.hasM = true; + return lineString; +}; + +LineString.ZM = function (points, srid) { + var lineString = new LineString(points, srid); + lineString.hasZ = true; + lineString.hasM = true; + return lineString; +}; + +LineString._parseWkt = function (value, options) { + var lineString = new LineString(); + lineString.srid = options.srid; + lineString.hasZ = options.hasZ; + lineString.hasM = options.hasM; + + if (value.isMatch(['EMPTY'])) + return lineString; + + value.expectGroupStart(); + lineString.points.push.apply(lineString.points, value.matchCoordinates(options)); + value.expectGroupEnd(); + + return lineString; +}; + +LineString._parseWkb = function (value, options) { + var lineString = new LineString(); + lineString.srid = options.srid; + lineString.hasZ = options.hasZ; + lineString.hasM = options.hasM; + + var pointCount = value.readUInt32(); + + for (var i = 0; i < pointCount; i++) + lineString.points.push(Point._readWkbPoint(value, options)); + + return lineString; +}; + +LineString._parseTwkb = function (value, options) { + var lineString = new LineString(); + lineString.hasZ = options.hasZ; + lineString.hasM = options.hasM; + + if (options.isEmpty) + return lineString; + + var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); + var pointCount = value.readVarInt(); + + for (var i = 0; i < pointCount; i++) + lineString.points.push(Point._readTwkbPoint(value, options, previousPoint)); + + return lineString; +}; + +LineString._parseGeoJSON = function (value) { + var lineString = new LineString(); + + if (value.coordinates.length > 0) + lineString.hasZ = value.coordinates[0].length > 2; + + for (var i = 0; i < value.coordinates.length; i++) + lineString.points.push(Point._readGeoJSONPoint(value.coordinates[i])); + + return lineString; +}; + +LineString.prototype.toWkt = function () { + if (this.points.length === 0) + return this._getWktType(Types.wkt.LineString, true); + + return this._getWktType(Types.wkt.LineString, false) + this._toInnerWkt(); +}; + +LineString.prototype._toInnerWkt = function () { + var innerWkt = '('; + + for (var i = 0; i < this.points.length; i++) + innerWkt += this._getWktCoordinate(this.points[i]) + ','; + + innerWkt = innerWkt.slice(0, -1); + innerWkt += ')'; + + return innerWkt; +}; + +LineString.prototype.toWkb = function (parentOptions) { + var wkb = new BinaryWriter(this._getWkbSize()); + + wkb.writeInt8(1); + + this._writeWkbType(wkb, Types.wkb.LineString, parentOptions); + wkb.writeUInt32LE(this.points.length); + + for (var i = 0; i < this.points.length; i++) + this.points[i]._writeWkbPoint(wkb); + + return wkb.buffer; +}; + +LineString.prototype.toTwkb = function () { + var twkb = new BinaryWriter(0, true); + + var precision = Geometry.getTwkbPrecision(5, 0, 0); + var isEmpty = this.points.length === 0; + + this._writeTwkbHeader(twkb, Types.wkb.LineString, precision, isEmpty); + + if (this.points.length > 0) { + twkb.writeVarInt(this.points.length); + + var previousPoint = new Point(0, 0, 0, 0); + for (var i = 0; i < this.points.length; i++) + this.points[i]._writeTwkbPoint(twkb, precision, previousPoint); + } + + return twkb.buffer; +}; + +LineString.prototype._getWkbSize = function () { + var coordinateSize = 16; + + if (this.hasZ) + coordinateSize += 8; + if (this.hasM) + coordinateSize += 8; + + return 1 + 4 + 4 + (this.points.length * coordinateSize); +}; + +LineString.prototype.toGeoJSON = function (options) { + var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); + geoJSON.type = Types.geoJSON.LineString; + geoJSON.coordinates = []; + + for (var i = 0; i < this.points.length; i++) { + if (this.hasZ) + geoJSON.coordinates.push([this.points[i].x, this.points[i].y, this.points[i].z]); + else + geoJSON.coordinates.push([this.points[i].x, this.points[i].y]); + } + + return geoJSON; +}; diff --git a/backend/node_modules/wkx/lib/multilinestring.js b/backend/node_modules/wkx/lib/multilinestring.js index 42f8ff4..c417666 100644 --- a/backend/node_modules/wkx/lib/multilinestring.js +++ b/backend/node_modules/wkx/lib/multilinestring.js @@ -1,189 +1,189 @@ -module.exports = MultiLineString; - -var util = require('util'); - -var Types = require('./types'); -var Geometry = require('./geometry'); -var Point = require('./point'); -var LineString = require('./linestring'); -var BinaryWriter = require('./binarywriter'); - -function MultiLineString(lineStrings, srid) { - Geometry.call(this); - - this.lineStrings = lineStrings || []; - this.srid = srid; - - if (this.lineStrings.length > 0) { - this.hasZ = this.lineStrings[0].hasZ; - this.hasM = this.lineStrings[0].hasM; - } -} - -util.inherits(MultiLineString, Geometry); - -MultiLineString.Z = function (lineStrings, srid) { - var multiLineString = new MultiLineString(lineStrings, srid); - multiLineString.hasZ = true; - return multiLineString; -}; - -MultiLineString.M = function (lineStrings, srid) { - var multiLineString = new MultiLineString(lineStrings, srid); - multiLineString.hasM = true; - return multiLineString; -}; - -MultiLineString.ZM = function (lineStrings, srid) { - var multiLineString = new MultiLineString(lineStrings, srid); - multiLineString.hasZ = true; - multiLineString.hasM = true; - return multiLineString; -}; - -MultiLineString._parseWkt = function (value, options) { - var multiLineString = new MultiLineString(); - multiLineString.srid = options.srid; - multiLineString.hasZ = options.hasZ; - multiLineString.hasM = options.hasM; - - if (value.isMatch(['EMPTY'])) - return multiLineString; - - value.expectGroupStart(); - - do { - value.expectGroupStart(); - multiLineString.lineStrings.push(new LineString(value.matchCoordinates(options))); - value.expectGroupEnd(); - } while (value.isMatch([','])); - - value.expectGroupEnd(); - - return multiLineString; -}; - -MultiLineString._parseWkb = function (value, options) { - var multiLineString = new MultiLineString(); - multiLineString.srid = options.srid; - multiLineString.hasZ = options.hasZ; - multiLineString.hasM = options.hasM; - - var lineStringCount = value.readUInt32(); - - for (var i = 0; i < lineStringCount; i++) - multiLineString.lineStrings.push(Geometry.parse(value, options)); - - return multiLineString; -}; - -MultiLineString._parseTwkb = function (value, options) { - var multiLineString = new MultiLineString(); - multiLineString.hasZ = options.hasZ; - multiLineString.hasM = options.hasM; - - if (options.isEmpty) - return multiLineString; - - var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); - var lineStringCount = value.readVarInt(); - - for (var i = 0; i < lineStringCount; i++) { - var lineString = new LineString(); - lineString.hasZ = options.hasZ; - lineString.hasM = options.hasM; - - var pointCount = value.readVarInt(); - - for (var j = 0; j < pointCount; j++) - lineString.points.push(Point._readTwkbPoint(value, options, previousPoint)); - - multiLineString.lineStrings.push(lineString); - } - - return multiLineString; -}; - -MultiLineString._parseGeoJSON = function (value) { - var multiLineString = new MultiLineString(); - - if (value.coordinates.length > 0 && value.coordinates[0].length > 0) - multiLineString.hasZ = value.coordinates[0][0].length > 2; - - for (var i = 0; i < value.coordinates.length; i++) - multiLineString.lineStrings.push(LineString._parseGeoJSON({ coordinates: value.coordinates[i] })); - - return multiLineString; -}; - -MultiLineString.prototype.toWkt = function () { - if (this.lineStrings.length === 0) - return this._getWktType(Types.wkt.MultiLineString, true); - - var wkt = this._getWktType(Types.wkt.MultiLineString, false) + '('; - - for (var i = 0; i < this.lineStrings.length; i++) - wkt += this.lineStrings[i]._toInnerWkt() + ','; - - wkt = wkt.slice(0, -1); - wkt += ')'; - - return wkt; -}; - -MultiLineString.prototype.toWkb = function () { - var wkb = new BinaryWriter(this._getWkbSize()); - - wkb.writeInt8(1); - - this._writeWkbType(wkb, Types.wkb.MultiLineString); - wkb.writeUInt32LE(this.lineStrings.length); - - for (var i = 0; i < this.lineStrings.length; i++) - wkb.writeBuffer(this.lineStrings[i].toWkb({ srid: this.srid })); - - return wkb.buffer; -}; - -MultiLineString.prototype.toTwkb = function () { - var twkb = new BinaryWriter(0, true); - - var precision = Geometry.getTwkbPrecision(5, 0, 0); - var isEmpty = this.lineStrings.length === 0; - - this._writeTwkbHeader(twkb, Types.wkb.MultiLineString, precision, isEmpty); - - if (this.lineStrings.length > 0) { - twkb.writeVarInt(this.lineStrings.length); - - var previousPoint = new Point(0, 0, 0, 0); - for (var i = 0; i < this.lineStrings.length; i++) { - twkb.writeVarInt(this.lineStrings[i].points.length); - - for (var j = 0; j < this.lineStrings[i].points.length; j++) - this.lineStrings[i].points[j]._writeTwkbPoint(twkb, precision, previousPoint); - } - } - - return twkb.buffer; -}; - -MultiLineString.prototype._getWkbSize = function () { - var size = 1 + 4 + 4; - - for (var i = 0; i < this.lineStrings.length; i++) - size += this.lineStrings[i]._getWkbSize(); - - return size; -}; - -MultiLineString.prototype.toGeoJSON = function (options) { - var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); - geoJSON.type = Types.geoJSON.MultiLineString; - geoJSON.coordinates = []; - - for (var i = 0; i < this.lineStrings.length; i++) - geoJSON.coordinates.push(this.lineStrings[i].toGeoJSON().coordinates); - - return geoJSON; -}; +module.exports = MultiLineString; + +var util = require('util'); + +var Types = require('./types'); +var Geometry = require('./geometry'); +var Point = require('./point'); +var LineString = require('./linestring'); +var BinaryWriter = require('./binarywriter'); + +function MultiLineString(lineStrings, srid) { + Geometry.call(this); + + this.lineStrings = lineStrings || []; + this.srid = srid; + + if (this.lineStrings.length > 0) { + this.hasZ = this.lineStrings[0].hasZ; + this.hasM = this.lineStrings[0].hasM; + } +} + +util.inherits(MultiLineString, Geometry); + +MultiLineString.Z = function (lineStrings, srid) { + var multiLineString = new MultiLineString(lineStrings, srid); + multiLineString.hasZ = true; + return multiLineString; +}; + +MultiLineString.M = function (lineStrings, srid) { + var multiLineString = new MultiLineString(lineStrings, srid); + multiLineString.hasM = true; + return multiLineString; +}; + +MultiLineString.ZM = function (lineStrings, srid) { + var multiLineString = new MultiLineString(lineStrings, srid); + multiLineString.hasZ = true; + multiLineString.hasM = true; + return multiLineString; +}; + +MultiLineString._parseWkt = function (value, options) { + var multiLineString = new MultiLineString(); + multiLineString.srid = options.srid; + multiLineString.hasZ = options.hasZ; + multiLineString.hasM = options.hasM; + + if (value.isMatch(['EMPTY'])) + return multiLineString; + + value.expectGroupStart(); + + do { + value.expectGroupStart(); + multiLineString.lineStrings.push(new LineString(value.matchCoordinates(options))); + value.expectGroupEnd(); + } while (value.isMatch([','])); + + value.expectGroupEnd(); + + return multiLineString; +}; + +MultiLineString._parseWkb = function (value, options) { + var multiLineString = new MultiLineString(); + multiLineString.srid = options.srid; + multiLineString.hasZ = options.hasZ; + multiLineString.hasM = options.hasM; + + var lineStringCount = value.readUInt32(); + + for (var i = 0; i < lineStringCount; i++) + multiLineString.lineStrings.push(Geometry.parse(value, options)); + + return multiLineString; +}; + +MultiLineString._parseTwkb = function (value, options) { + var multiLineString = new MultiLineString(); + multiLineString.hasZ = options.hasZ; + multiLineString.hasM = options.hasM; + + if (options.isEmpty) + return multiLineString; + + var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); + var lineStringCount = value.readVarInt(); + + for (var i = 0; i < lineStringCount; i++) { + var lineString = new LineString(); + lineString.hasZ = options.hasZ; + lineString.hasM = options.hasM; + + var pointCount = value.readVarInt(); + + for (var j = 0; j < pointCount; j++) + lineString.points.push(Point._readTwkbPoint(value, options, previousPoint)); + + multiLineString.lineStrings.push(lineString); + } + + return multiLineString; +}; + +MultiLineString._parseGeoJSON = function (value) { + var multiLineString = new MultiLineString(); + + if (value.coordinates.length > 0 && value.coordinates[0].length > 0) + multiLineString.hasZ = value.coordinates[0][0].length > 2; + + for (var i = 0; i < value.coordinates.length; i++) + multiLineString.lineStrings.push(LineString._parseGeoJSON({ coordinates: value.coordinates[i] })); + + return multiLineString; +}; + +MultiLineString.prototype.toWkt = function () { + if (this.lineStrings.length === 0) + return this._getWktType(Types.wkt.MultiLineString, true); + + var wkt = this._getWktType(Types.wkt.MultiLineString, false) + '('; + + for (var i = 0; i < this.lineStrings.length; i++) + wkt += this.lineStrings[i]._toInnerWkt() + ','; + + wkt = wkt.slice(0, -1); + wkt += ')'; + + return wkt; +}; + +MultiLineString.prototype.toWkb = function () { + var wkb = new BinaryWriter(this._getWkbSize()); + + wkb.writeInt8(1); + + this._writeWkbType(wkb, Types.wkb.MultiLineString); + wkb.writeUInt32LE(this.lineStrings.length); + + for (var i = 0; i < this.lineStrings.length; i++) + wkb.writeBuffer(this.lineStrings[i].toWkb({ srid: this.srid })); + + return wkb.buffer; +}; + +MultiLineString.prototype.toTwkb = function () { + var twkb = new BinaryWriter(0, true); + + var precision = Geometry.getTwkbPrecision(5, 0, 0); + var isEmpty = this.lineStrings.length === 0; + + this._writeTwkbHeader(twkb, Types.wkb.MultiLineString, precision, isEmpty); + + if (this.lineStrings.length > 0) { + twkb.writeVarInt(this.lineStrings.length); + + var previousPoint = new Point(0, 0, 0, 0); + for (var i = 0; i < this.lineStrings.length; i++) { + twkb.writeVarInt(this.lineStrings[i].points.length); + + for (var j = 0; j < this.lineStrings[i].points.length; j++) + this.lineStrings[i].points[j]._writeTwkbPoint(twkb, precision, previousPoint); + } + } + + return twkb.buffer; +}; + +MultiLineString.prototype._getWkbSize = function () { + var size = 1 + 4 + 4; + + for (var i = 0; i < this.lineStrings.length; i++) + size += this.lineStrings[i]._getWkbSize(); + + return size; +}; + +MultiLineString.prototype.toGeoJSON = function (options) { + var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); + geoJSON.type = Types.geoJSON.MultiLineString; + geoJSON.coordinates = []; + + for (var i = 0; i < this.lineStrings.length; i++) + geoJSON.coordinates.push(this.lineStrings[i].toGeoJSON().coordinates); + + return geoJSON; +}; diff --git a/backend/node_modules/wkx/lib/multipoint.js b/backend/node_modules/wkx/lib/multipoint.js index ab50f53..7d1a887 100644 --- a/backend/node_modules/wkx/lib/multipoint.js +++ b/backend/node_modules/wkx/lib/multipoint.js @@ -1,172 +1,172 @@ -module.exports = MultiPoint; - -var util = require('util'); - -var Types = require('./types'); -var Geometry = require('./geometry'); -var Point = require('./point'); -var BinaryWriter = require('./binarywriter'); - -function MultiPoint(points, srid) { - Geometry.call(this); - - this.points = points || []; - this.srid = srid; - - if (this.points.length > 0) { - this.hasZ = this.points[0].hasZ; - this.hasM = this.points[0].hasM; - } -} - -util.inherits(MultiPoint, Geometry); - -MultiPoint.Z = function (points, srid) { - var multiPoint = new MultiPoint(points, srid); - multiPoint.hasZ = true; - return multiPoint; -}; - -MultiPoint.M = function (points, srid) { - var multiPoint = new MultiPoint(points, srid); - multiPoint.hasM = true; - return multiPoint; -}; - -MultiPoint.ZM = function (points, srid) { - var multiPoint = new MultiPoint(points, srid); - multiPoint.hasZ = true; - multiPoint.hasM = true; - return multiPoint; -}; - -MultiPoint._parseWkt = function (value, options) { - var multiPoint = new MultiPoint(); - multiPoint.srid = options.srid; - multiPoint.hasZ = options.hasZ; - multiPoint.hasM = options.hasM; - - if (value.isMatch(['EMPTY'])) - return multiPoint; - - value.expectGroupStart(); - multiPoint.points.push.apply(multiPoint.points, value.matchCoordinates(options)); - value.expectGroupEnd(); - - return multiPoint; -}; - -MultiPoint._parseWkb = function (value, options) { - var multiPoint = new MultiPoint(); - multiPoint.srid = options.srid; - multiPoint.hasZ = options.hasZ; - multiPoint.hasM = options.hasM; - - var pointCount = value.readUInt32(); - - for (var i = 0; i < pointCount; i++) - multiPoint.points.push(Geometry.parse(value, options)); - - return multiPoint; -}; - -MultiPoint._parseTwkb = function (value, options) { - var multiPoint = new MultiPoint(); - multiPoint.hasZ = options.hasZ; - multiPoint.hasM = options.hasM; - - if (options.isEmpty) - return multiPoint; - - var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); - var pointCount = value.readVarInt(); - - for (var i = 0; i < pointCount; i++) - multiPoint.points.push(Point._readTwkbPoint(value, options, previousPoint)); - - return multiPoint; -}; - -MultiPoint._parseGeoJSON = function (value) { - var multiPoint = new MultiPoint(); - - if (value.coordinates.length > 0) - multiPoint.hasZ = value.coordinates[0].length > 2; - - for (var i = 0; i < value.coordinates.length; i++) - multiPoint.points.push(Point._parseGeoJSON({ coordinates: value.coordinates[i] })); - - return multiPoint; -}; - -MultiPoint.prototype.toWkt = function () { - if (this.points.length === 0) - return this._getWktType(Types.wkt.MultiPoint, true); - - var wkt = this._getWktType(Types.wkt.MultiPoint, false) + '('; - - for (var i = 0; i < this.points.length; i++) - wkt += this._getWktCoordinate(this.points[i]) + ','; - - wkt = wkt.slice(0, -1); - wkt += ')'; - - return wkt; -}; - -MultiPoint.prototype.toWkb = function () { - var wkb = new BinaryWriter(this._getWkbSize()); - - wkb.writeInt8(1); - - this._writeWkbType(wkb, Types.wkb.MultiPoint); - wkb.writeUInt32LE(this.points.length); - - for (var i = 0; i < this.points.length; i++) - wkb.writeBuffer(this.points[i].toWkb({ srid: this.srid })); - - return wkb.buffer; -}; - -MultiPoint.prototype.toTwkb = function () { - var twkb = new BinaryWriter(0, true); - - var precision = Geometry.getTwkbPrecision(5, 0, 0); - var isEmpty = this.points.length === 0; - - this._writeTwkbHeader(twkb, Types.wkb.MultiPoint, precision, isEmpty); - - if (this.points.length > 0) { - twkb.writeVarInt(this.points.length); - - var previousPoint = new Point(0, 0, 0, 0); - for (var i = 0; i < this.points.length; i++) - this.points[i]._writeTwkbPoint(twkb, precision, previousPoint); - } - - return twkb.buffer; -}; - -MultiPoint.prototype._getWkbSize = function () { - var coordinateSize = 16; - - if (this.hasZ) - coordinateSize += 8; - if (this.hasM) - coordinateSize += 8; - - coordinateSize += 5; - - return 1 + 4 + 4 + (this.points.length * coordinateSize); -}; - -MultiPoint.prototype.toGeoJSON = function (options) { - var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); - geoJSON.type = Types.geoJSON.MultiPoint; - geoJSON.coordinates = []; - - for (var i = 0; i < this.points.length; i++) - geoJSON.coordinates.push(this.points[i].toGeoJSON().coordinates); - - return geoJSON; -}; +module.exports = MultiPoint; + +var util = require('util'); + +var Types = require('./types'); +var Geometry = require('./geometry'); +var Point = require('./point'); +var BinaryWriter = require('./binarywriter'); + +function MultiPoint(points, srid) { + Geometry.call(this); + + this.points = points || []; + this.srid = srid; + + if (this.points.length > 0) { + this.hasZ = this.points[0].hasZ; + this.hasM = this.points[0].hasM; + } +} + +util.inherits(MultiPoint, Geometry); + +MultiPoint.Z = function (points, srid) { + var multiPoint = new MultiPoint(points, srid); + multiPoint.hasZ = true; + return multiPoint; +}; + +MultiPoint.M = function (points, srid) { + var multiPoint = new MultiPoint(points, srid); + multiPoint.hasM = true; + return multiPoint; +}; + +MultiPoint.ZM = function (points, srid) { + var multiPoint = new MultiPoint(points, srid); + multiPoint.hasZ = true; + multiPoint.hasM = true; + return multiPoint; +}; + +MultiPoint._parseWkt = function (value, options) { + var multiPoint = new MultiPoint(); + multiPoint.srid = options.srid; + multiPoint.hasZ = options.hasZ; + multiPoint.hasM = options.hasM; + + if (value.isMatch(['EMPTY'])) + return multiPoint; + + value.expectGroupStart(); + multiPoint.points.push.apply(multiPoint.points, value.matchCoordinates(options)); + value.expectGroupEnd(); + + return multiPoint; +}; + +MultiPoint._parseWkb = function (value, options) { + var multiPoint = new MultiPoint(); + multiPoint.srid = options.srid; + multiPoint.hasZ = options.hasZ; + multiPoint.hasM = options.hasM; + + var pointCount = value.readUInt32(); + + for (var i = 0; i < pointCount; i++) + multiPoint.points.push(Geometry.parse(value, options)); + + return multiPoint; +}; + +MultiPoint._parseTwkb = function (value, options) { + var multiPoint = new MultiPoint(); + multiPoint.hasZ = options.hasZ; + multiPoint.hasM = options.hasM; + + if (options.isEmpty) + return multiPoint; + + var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); + var pointCount = value.readVarInt(); + + for (var i = 0; i < pointCount; i++) + multiPoint.points.push(Point._readTwkbPoint(value, options, previousPoint)); + + return multiPoint; +}; + +MultiPoint._parseGeoJSON = function (value) { + var multiPoint = new MultiPoint(); + + if (value.coordinates.length > 0) + multiPoint.hasZ = value.coordinates[0].length > 2; + + for (var i = 0; i < value.coordinates.length; i++) + multiPoint.points.push(Point._parseGeoJSON({ coordinates: value.coordinates[i] })); + + return multiPoint; +}; + +MultiPoint.prototype.toWkt = function () { + if (this.points.length === 0) + return this._getWktType(Types.wkt.MultiPoint, true); + + var wkt = this._getWktType(Types.wkt.MultiPoint, false) + '('; + + for (var i = 0; i < this.points.length; i++) + wkt += this._getWktCoordinate(this.points[i]) + ','; + + wkt = wkt.slice(0, -1); + wkt += ')'; + + return wkt; +}; + +MultiPoint.prototype.toWkb = function () { + var wkb = new BinaryWriter(this._getWkbSize()); + + wkb.writeInt8(1); + + this._writeWkbType(wkb, Types.wkb.MultiPoint); + wkb.writeUInt32LE(this.points.length); + + for (var i = 0; i < this.points.length; i++) + wkb.writeBuffer(this.points[i].toWkb({ srid: this.srid })); + + return wkb.buffer; +}; + +MultiPoint.prototype.toTwkb = function () { + var twkb = new BinaryWriter(0, true); + + var precision = Geometry.getTwkbPrecision(5, 0, 0); + var isEmpty = this.points.length === 0; + + this._writeTwkbHeader(twkb, Types.wkb.MultiPoint, precision, isEmpty); + + if (this.points.length > 0) { + twkb.writeVarInt(this.points.length); + + var previousPoint = new Point(0, 0, 0, 0); + for (var i = 0; i < this.points.length; i++) + this.points[i]._writeTwkbPoint(twkb, precision, previousPoint); + } + + return twkb.buffer; +}; + +MultiPoint.prototype._getWkbSize = function () { + var coordinateSize = 16; + + if (this.hasZ) + coordinateSize += 8; + if (this.hasM) + coordinateSize += 8; + + coordinateSize += 5; + + return 1 + 4 + 4 + (this.points.length * coordinateSize); +}; + +MultiPoint.prototype.toGeoJSON = function (options) { + var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); + geoJSON.type = Types.geoJSON.MultiPoint; + geoJSON.coordinates = []; + + for (var i = 0; i < this.points.length; i++) + geoJSON.coordinates.push(this.points[i].toGeoJSON().coordinates); + + return geoJSON; +}; diff --git a/backend/node_modules/wkx/lib/multipolygon.js b/backend/node_modules/wkx/lib/multipolygon.js index 099e8c4..5c03ed2 100644 --- a/backend/node_modules/wkx/lib/multipolygon.js +++ b/backend/node_modules/wkx/lib/multipolygon.js @@ -1,226 +1,226 @@ -module.exports = MultiPolygon; - -var util = require('util'); - -var Types = require('./types'); -var Geometry = require('./geometry'); -var Point = require('./point'); -var Polygon = require('./polygon'); -var BinaryWriter = require('./binarywriter'); - -function MultiPolygon(polygons, srid) { - Geometry.call(this); - - this.polygons = polygons || []; - this.srid = srid; - - if (this.polygons.length > 0) { - this.hasZ = this.polygons[0].hasZ; - this.hasM = this.polygons[0].hasM; - } -} - -util.inherits(MultiPolygon, Geometry); - -MultiPolygon.Z = function (polygons, srid) { - var multiPolygon = new MultiPolygon(polygons, srid); - multiPolygon.hasZ = true; - return multiPolygon; -}; - -MultiPolygon.M = function (polygons, srid) { - var multiPolygon = new MultiPolygon(polygons, srid); - multiPolygon.hasM = true; - return multiPolygon; -}; - -MultiPolygon.ZM = function (polygons, srid) { - var multiPolygon = new MultiPolygon(polygons, srid); - multiPolygon.hasZ = true; - multiPolygon.hasM = true; - return multiPolygon; -}; - -MultiPolygon._parseWkt = function (value, options) { - var multiPolygon = new MultiPolygon(); - multiPolygon.srid = options.srid; - multiPolygon.hasZ = options.hasZ; - multiPolygon.hasM = options.hasM; - - if (value.isMatch(['EMPTY'])) - return multiPolygon; - - value.expectGroupStart(); - - do { - value.expectGroupStart(); - - var exteriorRing = []; - var interiorRings = []; - - value.expectGroupStart(); - exteriorRing.push.apply(exteriorRing, value.matchCoordinates(options)); - value.expectGroupEnd(); - - while (value.isMatch([','])) { - value.expectGroupStart(); - interiorRings.push(value.matchCoordinates(options)); - value.expectGroupEnd(); - } - - multiPolygon.polygons.push(new Polygon(exteriorRing, interiorRings)); - - value.expectGroupEnd(); - - } while (value.isMatch([','])); - - value.expectGroupEnd(); - - return multiPolygon; -}; - -MultiPolygon._parseWkb = function (value, options) { - var multiPolygon = new MultiPolygon(); - multiPolygon.srid = options.srid; - multiPolygon.hasZ = options.hasZ; - multiPolygon.hasM = options.hasM; - - var polygonCount = value.readUInt32(); - - for (var i = 0; i < polygonCount; i++) - multiPolygon.polygons.push(Geometry.parse(value, options)); - - return multiPolygon; -}; - -MultiPolygon._parseTwkb = function (value, options) { - var multiPolygon = new MultiPolygon(); - multiPolygon.hasZ = options.hasZ; - multiPolygon.hasM = options.hasM; - - if (options.isEmpty) - return multiPolygon; - - var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); - var polygonCount = value.readVarInt(); - - for (var i = 0; i < polygonCount; i++) { - var polygon = new Polygon(); - polygon.hasZ = options.hasZ; - polygon.hasM = options.hasM; - - var ringCount = value.readVarInt(); - var exteriorRingCount = value.readVarInt(); - - for (var j = 0; j < exteriorRingCount; j++) - polygon.exteriorRing.push(Point._readTwkbPoint(value, options, previousPoint)); - - for (j = 1; j < ringCount; j++) { - var interiorRing = []; - - var interiorRingCount = value.readVarInt(); - - for (var k = 0; k < interiorRingCount; k++) - interiorRing.push(Point._readTwkbPoint(value, options, previousPoint)); - - polygon.interiorRings.push(interiorRing); - } - - multiPolygon.polygons.push(polygon); - } - - return multiPolygon; -}; - -MultiPolygon._parseGeoJSON = function (value) { - var multiPolygon = new MultiPolygon(); - - if (value.coordinates.length > 0 && value.coordinates[0].length > 0 && value.coordinates[0][0].length > 0) - multiPolygon.hasZ = value.coordinates[0][0][0].length > 2; - - for (var i = 0; i < value.coordinates.length; i++) - multiPolygon.polygons.push(Polygon._parseGeoJSON({ coordinates: value.coordinates[i] })); - - return multiPolygon; -}; - -MultiPolygon.prototype.toWkt = function () { - if (this.polygons.length === 0) - return this._getWktType(Types.wkt.MultiPolygon, true); - - var wkt = this._getWktType(Types.wkt.MultiPolygon, false) + '('; - - for (var i = 0; i < this.polygons.length; i++) - wkt += this.polygons[i]._toInnerWkt() + ','; - - wkt = wkt.slice(0, -1); - wkt += ')'; - - return wkt; -}; - -MultiPolygon.prototype.toWkb = function () { - var wkb = new BinaryWriter(this._getWkbSize()); - - wkb.writeInt8(1); - - this._writeWkbType(wkb, Types.wkb.MultiPolygon); - wkb.writeUInt32LE(this.polygons.length); - - for (var i = 0; i < this.polygons.length; i++) - wkb.writeBuffer(this.polygons[i].toWkb({ srid: this.srid })); - - return wkb.buffer; -}; - -MultiPolygon.prototype.toTwkb = function () { - var twkb = new BinaryWriter(0, true); - - var precision = Geometry.getTwkbPrecision(5, 0, 0); - var isEmpty = this.polygons.length === 0; - - this._writeTwkbHeader(twkb, Types.wkb.MultiPolygon, precision, isEmpty); - - if (this.polygons.length > 0) { - twkb.writeVarInt(this.polygons.length); - - var previousPoint = new Point(0, 0, 0, 0); - for (var i = 0; i < this.polygons.length; i++) { - twkb.writeVarInt(1 + this.polygons[i].interiorRings.length); - - twkb.writeVarInt(this.polygons[i].exteriorRing.length); - - for (var j = 0; j < this.polygons[i].exteriorRing.length; j++) - this.polygons[i].exteriorRing[j]._writeTwkbPoint(twkb, precision, previousPoint); - - for (j = 0; j < this.polygons[i].interiorRings.length; j++) { - twkb.writeVarInt(this.polygons[i].interiorRings[j].length); - - for (var k = 0; k < this.polygons[i].interiorRings[j].length; k++) - this.polygons[i].interiorRings[j][k]._writeTwkbPoint(twkb, precision, previousPoint); - } - } - } - - return twkb.buffer; -}; - -MultiPolygon.prototype._getWkbSize = function () { - var size = 1 + 4 + 4; - - for (var i = 0; i < this.polygons.length; i++) - size += this.polygons[i]._getWkbSize(); - - return size; -}; - -MultiPolygon.prototype.toGeoJSON = function (options) { - var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); - geoJSON.type = Types.geoJSON.MultiPolygon; - geoJSON.coordinates = []; - - for (var i = 0; i < this.polygons.length; i++) - geoJSON.coordinates.push(this.polygons[i].toGeoJSON().coordinates); - - return geoJSON; -}; +module.exports = MultiPolygon; + +var util = require('util'); + +var Types = require('./types'); +var Geometry = require('./geometry'); +var Point = require('./point'); +var Polygon = require('./polygon'); +var BinaryWriter = require('./binarywriter'); + +function MultiPolygon(polygons, srid) { + Geometry.call(this); + + this.polygons = polygons || []; + this.srid = srid; + + if (this.polygons.length > 0) { + this.hasZ = this.polygons[0].hasZ; + this.hasM = this.polygons[0].hasM; + } +} + +util.inherits(MultiPolygon, Geometry); + +MultiPolygon.Z = function (polygons, srid) { + var multiPolygon = new MultiPolygon(polygons, srid); + multiPolygon.hasZ = true; + return multiPolygon; +}; + +MultiPolygon.M = function (polygons, srid) { + var multiPolygon = new MultiPolygon(polygons, srid); + multiPolygon.hasM = true; + return multiPolygon; +}; + +MultiPolygon.ZM = function (polygons, srid) { + var multiPolygon = new MultiPolygon(polygons, srid); + multiPolygon.hasZ = true; + multiPolygon.hasM = true; + return multiPolygon; +}; + +MultiPolygon._parseWkt = function (value, options) { + var multiPolygon = new MultiPolygon(); + multiPolygon.srid = options.srid; + multiPolygon.hasZ = options.hasZ; + multiPolygon.hasM = options.hasM; + + if (value.isMatch(['EMPTY'])) + return multiPolygon; + + value.expectGroupStart(); + + do { + value.expectGroupStart(); + + var exteriorRing = []; + var interiorRings = []; + + value.expectGroupStart(); + exteriorRing.push.apply(exteriorRing, value.matchCoordinates(options)); + value.expectGroupEnd(); + + while (value.isMatch([','])) { + value.expectGroupStart(); + interiorRings.push(value.matchCoordinates(options)); + value.expectGroupEnd(); + } + + multiPolygon.polygons.push(new Polygon(exteriorRing, interiorRings)); + + value.expectGroupEnd(); + + } while (value.isMatch([','])); + + value.expectGroupEnd(); + + return multiPolygon; +}; + +MultiPolygon._parseWkb = function (value, options) { + var multiPolygon = new MultiPolygon(); + multiPolygon.srid = options.srid; + multiPolygon.hasZ = options.hasZ; + multiPolygon.hasM = options.hasM; + + var polygonCount = value.readUInt32(); + + for (var i = 0; i < polygonCount; i++) + multiPolygon.polygons.push(Geometry.parse(value, options)); + + return multiPolygon; +}; + +MultiPolygon._parseTwkb = function (value, options) { + var multiPolygon = new MultiPolygon(); + multiPolygon.hasZ = options.hasZ; + multiPolygon.hasM = options.hasM; + + if (options.isEmpty) + return multiPolygon; + + var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); + var polygonCount = value.readVarInt(); + + for (var i = 0; i < polygonCount; i++) { + var polygon = new Polygon(); + polygon.hasZ = options.hasZ; + polygon.hasM = options.hasM; + + var ringCount = value.readVarInt(); + var exteriorRingCount = value.readVarInt(); + + for (var j = 0; j < exteriorRingCount; j++) + polygon.exteriorRing.push(Point._readTwkbPoint(value, options, previousPoint)); + + for (j = 1; j < ringCount; j++) { + var interiorRing = []; + + var interiorRingCount = value.readVarInt(); + + for (var k = 0; k < interiorRingCount; k++) + interiorRing.push(Point._readTwkbPoint(value, options, previousPoint)); + + polygon.interiorRings.push(interiorRing); + } + + multiPolygon.polygons.push(polygon); + } + + return multiPolygon; +}; + +MultiPolygon._parseGeoJSON = function (value) { + var multiPolygon = new MultiPolygon(); + + if (value.coordinates.length > 0 && value.coordinates[0].length > 0 && value.coordinates[0][0].length > 0) + multiPolygon.hasZ = value.coordinates[0][0][0].length > 2; + + for (var i = 0; i < value.coordinates.length; i++) + multiPolygon.polygons.push(Polygon._parseGeoJSON({ coordinates: value.coordinates[i] })); + + return multiPolygon; +}; + +MultiPolygon.prototype.toWkt = function () { + if (this.polygons.length === 0) + return this._getWktType(Types.wkt.MultiPolygon, true); + + var wkt = this._getWktType(Types.wkt.MultiPolygon, false) + '('; + + for (var i = 0; i < this.polygons.length; i++) + wkt += this.polygons[i]._toInnerWkt() + ','; + + wkt = wkt.slice(0, -1); + wkt += ')'; + + return wkt; +}; + +MultiPolygon.prototype.toWkb = function () { + var wkb = new BinaryWriter(this._getWkbSize()); + + wkb.writeInt8(1); + + this._writeWkbType(wkb, Types.wkb.MultiPolygon); + wkb.writeUInt32LE(this.polygons.length); + + for (var i = 0; i < this.polygons.length; i++) + wkb.writeBuffer(this.polygons[i].toWkb({ srid: this.srid })); + + return wkb.buffer; +}; + +MultiPolygon.prototype.toTwkb = function () { + var twkb = new BinaryWriter(0, true); + + var precision = Geometry.getTwkbPrecision(5, 0, 0); + var isEmpty = this.polygons.length === 0; + + this._writeTwkbHeader(twkb, Types.wkb.MultiPolygon, precision, isEmpty); + + if (this.polygons.length > 0) { + twkb.writeVarInt(this.polygons.length); + + var previousPoint = new Point(0, 0, 0, 0); + for (var i = 0; i < this.polygons.length; i++) { + twkb.writeVarInt(1 + this.polygons[i].interiorRings.length); + + twkb.writeVarInt(this.polygons[i].exteriorRing.length); + + for (var j = 0; j < this.polygons[i].exteriorRing.length; j++) + this.polygons[i].exteriorRing[j]._writeTwkbPoint(twkb, precision, previousPoint); + + for (j = 0; j < this.polygons[i].interiorRings.length; j++) { + twkb.writeVarInt(this.polygons[i].interiorRings[j].length); + + for (var k = 0; k < this.polygons[i].interiorRings[j].length; k++) + this.polygons[i].interiorRings[j][k]._writeTwkbPoint(twkb, precision, previousPoint); + } + } + } + + return twkb.buffer; +}; + +MultiPolygon.prototype._getWkbSize = function () { + var size = 1 + 4 + 4; + + for (var i = 0; i < this.polygons.length; i++) + size += this.polygons[i]._getWkbSize(); + + return size; +}; + +MultiPolygon.prototype.toGeoJSON = function (options) { + var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); + geoJSON.type = Types.geoJSON.MultiPolygon; + geoJSON.coordinates = []; + + for (var i = 0; i < this.polygons.length; i++) + geoJSON.coordinates.push(this.polygons[i].toGeoJSON().coordinates); + + return geoJSON; +}; diff --git a/backend/node_modules/wkx/lib/point.js b/backend/node_modules/wkx/lib/point.js index 20bb1f8..a425a8e 100644 --- a/backend/node_modules/wkx/lib/point.js +++ b/backend/node_modules/wkx/lib/point.js @@ -1,217 +1,217 @@ -module.exports = Point; - -var util = require('util'); - -var Geometry = require('./geometry'); -var Types = require('./types'); -var BinaryWriter = require('./binarywriter'); -var ZigZag = require('./zigzag.js'); - -function Point(x, y, z, m, srid) { - Geometry.call(this); - - this.x = x; - this.y = y; - this.z = z; - this.m = m; - this.srid = srid; - - this.hasZ = typeof this.z !== 'undefined'; - this.hasM = typeof this.m !== 'undefined'; -} - -util.inherits(Point, Geometry); - -Point.Z = function (x, y, z, srid) { - var point = new Point(x, y, z, undefined, srid); - point.hasZ = true; - return point; -}; - -Point.M = function (x, y, m, srid) { - var point = new Point(x, y, undefined, m, srid); - point.hasM = true; - return point; -}; - -Point.ZM = function (x, y, z, m, srid) { - var point = new Point(x, y, z, m, srid); - point.hasZ = true; - point.hasM = true; - return point; -}; - -Point._parseWkt = function (value, options) { - var point = new Point(); - point.srid = options.srid; - point.hasZ = options.hasZ; - point.hasM = options.hasM; - - if (value.isMatch(['EMPTY'])) - return point; - - value.expectGroupStart(); - - var coordinate = value.matchCoordinate(options); - - point.x = coordinate.x; - point.y = coordinate.y; - point.z = coordinate.z; - point.m = coordinate.m; - - value.expectGroupEnd(); - - return point; -}; - -Point._parseWkb = function (value, options) { - var point = Point._readWkbPoint(value, options); - point.srid = options.srid; - return point; -}; - -Point._readWkbPoint = function (value, options) { - return new Point(value.readDouble(), value.readDouble(), - options.hasZ ? value.readDouble() : undefined, - options.hasM ? value.readDouble() : undefined); -}; - -Point._parseTwkb = function (value, options) { - var point = new Point(); - point.hasZ = options.hasZ; - point.hasM = options.hasM; - - if (options.isEmpty) - return point; - - point.x = ZigZag.decode(value.readVarInt()) / options.precisionFactor; - point.y = ZigZag.decode(value.readVarInt()) / options.precisionFactor; - point.z = options.hasZ ? ZigZag.decode(value.readVarInt()) / options.zPrecisionFactor : undefined; - point.m = options.hasM ? ZigZag.decode(value.readVarInt()) / options.mPrecisionFactor : undefined; - - return point; -}; - -Point._readTwkbPoint = function (value, options, previousPoint) { - previousPoint.x += ZigZag.decode(value.readVarInt()) / options.precisionFactor; - previousPoint.y += ZigZag.decode(value.readVarInt()) / options.precisionFactor; - - if (options.hasZ) - previousPoint.z += ZigZag.decode(value.readVarInt()) / options.zPrecisionFactor; - if (options.hasM) - previousPoint.m += ZigZag.decode(value.readVarInt()) / options.mPrecisionFactor; - - return new Point(previousPoint.x, previousPoint.y, previousPoint.z, previousPoint.m); -}; - -Point._parseGeoJSON = function (value) { - return Point._readGeoJSONPoint(value.coordinates); -}; - -Point._readGeoJSONPoint = function (coordinates) { - if (coordinates.length === 0) - return new Point(); - - if (coordinates.length > 2) - return new Point(coordinates[0], coordinates[1], coordinates[2]); - - return new Point(coordinates[0], coordinates[1]); -}; - -Point.prototype.toWkt = function () { - if (typeof this.x === 'undefined' && typeof this.y === 'undefined' && - typeof this.z === 'undefined' && typeof this.m === 'undefined') - return this._getWktType(Types.wkt.Point, true); - - return this._getWktType(Types.wkt.Point, false) + '(' + this._getWktCoordinate(this) + ')'; -}; - -Point.prototype.toWkb = function (parentOptions) { - var wkb = new BinaryWriter(this._getWkbSize()); - - wkb.writeInt8(1); - this._writeWkbType(wkb, Types.wkb.Point, parentOptions); - - if (typeof this.x === 'undefined' && typeof this.y === 'undefined') { - wkb.writeDoubleLE(NaN); - wkb.writeDoubleLE(NaN); - - if (this.hasZ) - wkb.writeDoubleLE(NaN); - if (this.hasM) - wkb.writeDoubleLE(NaN); - } - else { - this._writeWkbPoint(wkb); - } - - return wkb.buffer; -}; - -Point.prototype._writeWkbPoint = function (wkb) { - wkb.writeDoubleLE(this.x); - wkb.writeDoubleLE(this.y); - - if (this.hasZ) - wkb.writeDoubleLE(this.z); - if (this.hasM) - wkb.writeDoubleLE(this.m); -}; - -Point.prototype.toTwkb = function () { - var twkb = new BinaryWriter(0, true); - - var precision = Geometry.getTwkbPrecision(5, 0, 0); - var isEmpty = typeof this.x === 'undefined' && typeof this.y === 'undefined'; - - this._writeTwkbHeader(twkb, Types.wkb.Point, precision, isEmpty); - - if (!isEmpty) - this._writeTwkbPoint(twkb, precision, new Point(0, 0, 0, 0)); - - return twkb.buffer; -}; - -Point.prototype._writeTwkbPoint = function (twkb, precision, previousPoint) { - var x = this.x * precision.xyFactor; - var y = this.y * precision.xyFactor; - var z = this.z * precision.zFactor; - var m = this.m * precision.mFactor; - - twkb.writeVarInt(ZigZag.encode(x - previousPoint.x)); - twkb.writeVarInt(ZigZag.encode(y - previousPoint.y)); - if (this.hasZ) - twkb.writeVarInt(ZigZag.encode(z - previousPoint.z)); - if (this.hasM) - twkb.writeVarInt(ZigZag.encode(m - previousPoint.m)); - - previousPoint.x = x; - previousPoint.y = y; - previousPoint.z = z; - previousPoint.m = m; -}; - -Point.prototype._getWkbSize = function () { - var size = 1 + 4 + 8 + 8; - - if (this.hasZ) - size += 8; - if (this.hasM) - size += 8; - - return size; -}; - -Point.prototype.toGeoJSON = function (options) { - var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); - geoJSON.type = Types.geoJSON.Point; - - if (typeof this.x === 'undefined' && typeof this.y === 'undefined') - geoJSON.coordinates = []; - else if (typeof this.z !== 'undefined') - geoJSON.coordinates = [this.x, this.y, this.z]; - else - geoJSON.coordinates = [this.x, this.y]; - - return geoJSON; -}; +module.exports = Point; + +var util = require('util'); + +var Geometry = require('./geometry'); +var Types = require('./types'); +var BinaryWriter = require('./binarywriter'); +var ZigZag = require('./zigzag.js'); + +function Point(x, y, z, m, srid) { + Geometry.call(this); + + this.x = x; + this.y = y; + this.z = z; + this.m = m; + this.srid = srid; + + this.hasZ = typeof this.z !== 'undefined'; + this.hasM = typeof this.m !== 'undefined'; +} + +util.inherits(Point, Geometry); + +Point.Z = function (x, y, z, srid) { + var point = new Point(x, y, z, undefined, srid); + point.hasZ = true; + return point; +}; + +Point.M = function (x, y, m, srid) { + var point = new Point(x, y, undefined, m, srid); + point.hasM = true; + return point; +}; + +Point.ZM = function (x, y, z, m, srid) { + var point = new Point(x, y, z, m, srid); + point.hasZ = true; + point.hasM = true; + return point; +}; + +Point._parseWkt = function (value, options) { + var point = new Point(); + point.srid = options.srid; + point.hasZ = options.hasZ; + point.hasM = options.hasM; + + if (value.isMatch(['EMPTY'])) + return point; + + value.expectGroupStart(); + + var coordinate = value.matchCoordinate(options); + + point.x = coordinate.x; + point.y = coordinate.y; + point.z = coordinate.z; + point.m = coordinate.m; + + value.expectGroupEnd(); + + return point; +}; + +Point._parseWkb = function (value, options) { + var point = Point._readWkbPoint(value, options); + point.srid = options.srid; + return point; +}; + +Point._readWkbPoint = function (value, options) { + return new Point(value.readDouble(), value.readDouble(), + options.hasZ ? value.readDouble() : undefined, + options.hasM ? value.readDouble() : undefined); +}; + +Point._parseTwkb = function (value, options) { + var point = new Point(); + point.hasZ = options.hasZ; + point.hasM = options.hasM; + + if (options.isEmpty) + return point; + + point.x = ZigZag.decode(value.readVarInt()) / options.precisionFactor; + point.y = ZigZag.decode(value.readVarInt()) / options.precisionFactor; + point.z = options.hasZ ? ZigZag.decode(value.readVarInt()) / options.zPrecisionFactor : undefined; + point.m = options.hasM ? ZigZag.decode(value.readVarInt()) / options.mPrecisionFactor : undefined; + + return point; +}; + +Point._readTwkbPoint = function (value, options, previousPoint) { + previousPoint.x += ZigZag.decode(value.readVarInt()) / options.precisionFactor; + previousPoint.y += ZigZag.decode(value.readVarInt()) / options.precisionFactor; + + if (options.hasZ) + previousPoint.z += ZigZag.decode(value.readVarInt()) / options.zPrecisionFactor; + if (options.hasM) + previousPoint.m += ZigZag.decode(value.readVarInt()) / options.mPrecisionFactor; + + return new Point(previousPoint.x, previousPoint.y, previousPoint.z, previousPoint.m); +}; + +Point._parseGeoJSON = function (value) { + return Point._readGeoJSONPoint(value.coordinates); +}; + +Point._readGeoJSONPoint = function (coordinates) { + if (coordinates.length === 0) + return new Point(); + + if (coordinates.length > 2) + return new Point(coordinates[0], coordinates[1], coordinates[2]); + + return new Point(coordinates[0], coordinates[1]); +}; + +Point.prototype.toWkt = function () { + if (typeof this.x === 'undefined' && typeof this.y === 'undefined' && + typeof this.z === 'undefined' && typeof this.m === 'undefined') + return this._getWktType(Types.wkt.Point, true); + + return this._getWktType(Types.wkt.Point, false) + '(' + this._getWktCoordinate(this) + ')'; +}; + +Point.prototype.toWkb = function (parentOptions) { + var wkb = new BinaryWriter(this._getWkbSize()); + + wkb.writeInt8(1); + this._writeWkbType(wkb, Types.wkb.Point, parentOptions); + + if (typeof this.x === 'undefined' && typeof this.y === 'undefined') { + wkb.writeDoubleLE(NaN); + wkb.writeDoubleLE(NaN); + + if (this.hasZ) + wkb.writeDoubleLE(NaN); + if (this.hasM) + wkb.writeDoubleLE(NaN); + } + else { + this._writeWkbPoint(wkb); + } + + return wkb.buffer; +}; + +Point.prototype._writeWkbPoint = function (wkb) { + wkb.writeDoubleLE(this.x); + wkb.writeDoubleLE(this.y); + + if (this.hasZ) + wkb.writeDoubleLE(this.z); + if (this.hasM) + wkb.writeDoubleLE(this.m); +}; + +Point.prototype.toTwkb = function () { + var twkb = new BinaryWriter(0, true); + + var precision = Geometry.getTwkbPrecision(5, 0, 0); + var isEmpty = typeof this.x === 'undefined' && typeof this.y === 'undefined'; + + this._writeTwkbHeader(twkb, Types.wkb.Point, precision, isEmpty); + + if (!isEmpty) + this._writeTwkbPoint(twkb, precision, new Point(0, 0, 0, 0)); + + return twkb.buffer; +}; + +Point.prototype._writeTwkbPoint = function (twkb, precision, previousPoint) { + var x = this.x * precision.xyFactor; + var y = this.y * precision.xyFactor; + var z = this.z * precision.zFactor; + var m = this.m * precision.mFactor; + + twkb.writeVarInt(ZigZag.encode(x - previousPoint.x)); + twkb.writeVarInt(ZigZag.encode(y - previousPoint.y)); + if (this.hasZ) + twkb.writeVarInt(ZigZag.encode(z - previousPoint.z)); + if (this.hasM) + twkb.writeVarInt(ZigZag.encode(m - previousPoint.m)); + + previousPoint.x = x; + previousPoint.y = y; + previousPoint.z = z; + previousPoint.m = m; +}; + +Point.prototype._getWkbSize = function () { + var size = 1 + 4 + 8 + 8; + + if (this.hasZ) + size += 8; + if (this.hasM) + size += 8; + + return size; +}; + +Point.prototype.toGeoJSON = function (options) { + var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); + geoJSON.type = Types.geoJSON.Point; + + if (typeof this.x === 'undefined' && typeof this.y === 'undefined') + geoJSON.coordinates = []; + else if (typeof this.z !== 'undefined') + geoJSON.coordinates = [this.x, this.y, this.z]; + else + geoJSON.coordinates = [this.x, this.y]; + + return geoJSON; +}; diff --git a/backend/node_modules/wkx/lib/polygon.js b/backend/node_modules/wkx/lib/polygon.js index f54b878..1fccafb 100644 --- a/backend/node_modules/wkx/lib/polygon.js +++ b/backend/node_modules/wkx/lib/polygon.js @@ -1,288 +1,288 @@ -module.exports = Polygon; - -var util = require('util'); - -var Geometry = require('./geometry'); -var Types = require('./types'); -var Point = require('./point'); -var BinaryWriter = require('./binarywriter'); - -function Polygon(exteriorRing, interiorRings, srid) { - Geometry.call(this); - - this.exteriorRing = exteriorRing || []; - this.interiorRings = interiorRings || []; - this.srid = srid; - - if (this.exteriorRing.length > 0) { - this.hasZ = this.exteriorRing[0].hasZ; - this.hasM = this.exteriorRing[0].hasM; - } -} - -util.inherits(Polygon, Geometry); - -Polygon.Z = function (exteriorRing, interiorRings, srid) { - var polygon = new Polygon(exteriorRing, interiorRings, srid); - polygon.hasZ = true; - return polygon; -}; - -Polygon.M = function (exteriorRing, interiorRings, srid) { - var polygon = new Polygon(exteriorRing, interiorRings, srid); - polygon.hasM = true; - return polygon; -}; - -Polygon.ZM = function (exteriorRing, interiorRings, srid) { - var polygon = new Polygon(exteriorRing, interiorRings, srid); - polygon.hasZ = true; - polygon.hasM = true; - return polygon; -}; - -Polygon._parseWkt = function (value, options) { - var polygon = new Polygon(); - polygon.srid = options.srid; - polygon.hasZ = options.hasZ; - polygon.hasM = options.hasM; - - if (value.isMatch(['EMPTY'])) - return polygon; - - value.expectGroupStart(); - - value.expectGroupStart(); - polygon.exteriorRing.push.apply(polygon.exteriorRing, value.matchCoordinates(options)); - value.expectGroupEnd(); - - while (value.isMatch([','])) { - value.expectGroupStart(); - polygon.interiorRings.push(value.matchCoordinates(options)); - value.expectGroupEnd(); - } - - value.expectGroupEnd(); - - return polygon; -}; - -Polygon._parseWkb = function (value, options) { - var polygon = new Polygon(); - polygon.srid = options.srid; - polygon.hasZ = options.hasZ; - polygon.hasM = options.hasM; - - var ringCount = value.readUInt32(); - - if (ringCount > 0) { - var exteriorRingCount = value.readUInt32(); - - for (var i = 0; i < exteriorRingCount; i++) - polygon.exteriorRing.push(Point._readWkbPoint(value, options)); - - for (i = 1; i < ringCount; i++) { - var interiorRing = []; - - var interiorRingCount = value.readUInt32(); - - for (var j = 0; j < interiorRingCount; j++) - interiorRing.push(Point._readWkbPoint(value, options)); - - polygon.interiorRings.push(interiorRing); - } - } - - return polygon; -}; - -Polygon._parseTwkb = function (value, options) { - var polygon = new Polygon(); - polygon.hasZ = options.hasZ; - polygon.hasM = options.hasM; - - if (options.isEmpty) - return polygon; - - var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); - var ringCount = value.readVarInt(); - var exteriorRingCount = value.readVarInt(); - - for (var i = 0; i < exteriorRingCount; i++) - polygon.exteriorRing.push(Point._readTwkbPoint(value, options, previousPoint)); - - for (i = 1; i < ringCount; i++) { - var interiorRing = []; - - var interiorRingCount = value.readVarInt(); - - for (var j = 0; j < interiorRingCount; j++) - interiorRing.push(Point._readTwkbPoint(value, options, previousPoint)); - - polygon.interiorRings.push(interiorRing); - } - - return polygon; -}; - -Polygon._parseGeoJSON = function (value) { - var polygon = new Polygon(); - - if (value.coordinates.length > 0 && value.coordinates[0].length > 0) - polygon.hasZ = value.coordinates[0][0].length > 2; - - for (var i = 0; i < value.coordinates.length; i++) { - if (i > 0) - polygon.interiorRings.push([]); - - for (var j = 0; j < value.coordinates[i].length; j++) { - if (i === 0) - polygon.exteriorRing.push(Point._readGeoJSONPoint(value.coordinates[i][j])); - else - polygon.interiorRings[i - 1].push(Point._readGeoJSONPoint(value.coordinates[i][j])); - } - } - - return polygon; -}; - -Polygon.prototype.toWkt = function () { - if (this.exteriorRing.length === 0) - return this._getWktType(Types.wkt.Polygon, true); - - return this._getWktType(Types.wkt.Polygon, false) + this._toInnerWkt(); -}; - -Polygon.prototype._toInnerWkt = function () { - var innerWkt = '(('; - - for (var i = 0; i < this.exteriorRing.length; i++) - innerWkt += this._getWktCoordinate(this.exteriorRing[i]) + ','; - - innerWkt = innerWkt.slice(0, -1); - innerWkt += ')'; - - for (i = 0; i < this.interiorRings.length; i++) { - innerWkt += ',('; - - for (var j = 0; j < this.interiorRings[i].length; j++) { - innerWkt += this._getWktCoordinate(this.interiorRings[i][j]) + ','; - } - - innerWkt = innerWkt.slice(0, -1); - innerWkt += ')'; - } - - innerWkt += ')'; - - return innerWkt; -}; - -Polygon.prototype.toWkb = function (parentOptions) { - var wkb = new BinaryWriter(this._getWkbSize()); - - wkb.writeInt8(1); - - this._writeWkbType(wkb, Types.wkb.Polygon, parentOptions); - - if (this.exteriorRing.length > 0) { - wkb.writeUInt32LE(1 + this.interiorRings.length); - wkb.writeUInt32LE(this.exteriorRing.length); - } - else { - wkb.writeUInt32LE(0); - } - - for (var i = 0; i < this.exteriorRing.length; i++) - this.exteriorRing[i]._writeWkbPoint(wkb); - - for (i = 0; i < this.interiorRings.length; i++) { - wkb.writeUInt32LE(this.interiorRings[i].length); - - for (var j = 0; j < this.interiorRings[i].length; j++) - this.interiorRings[i][j]._writeWkbPoint(wkb); - } - - return wkb.buffer; -}; - -Polygon.prototype.toTwkb = function () { - var twkb = new BinaryWriter(0, true); - - var precision = Geometry.getTwkbPrecision(5, 0, 0); - var isEmpty = this.exteriorRing.length === 0; - - this._writeTwkbHeader(twkb, Types.wkb.Polygon, precision, isEmpty); - - if (this.exteriorRing.length > 0) { - twkb.writeVarInt(1 + this.interiorRings.length); - - twkb.writeVarInt(this.exteriorRing.length); - - var previousPoint = new Point(0, 0, 0, 0); - for (var i = 0; i < this.exteriorRing.length; i++) - this.exteriorRing[i]._writeTwkbPoint(twkb, precision, previousPoint); - - for (i = 0; i < this.interiorRings.length; i++) { - twkb.writeVarInt(this.interiorRings[i].length); - - for (var j = 0; j < this.interiorRings[i].length; j++) - this.interiorRings[i][j]._writeTwkbPoint(twkb, precision, previousPoint); - } - } - - return twkb.buffer; -}; - -Polygon.prototype._getWkbSize = function () { - var coordinateSize = 16; - - if (this.hasZ) - coordinateSize += 8; - if (this.hasM) - coordinateSize += 8; - - var size = 1 + 4 + 4; - - if (this.exteriorRing.length > 0) - size += 4 + (this.exteriorRing.length * coordinateSize); - - for (var i = 0; i < this.interiorRings.length; i++) - size += 4 + (this.interiorRings[i].length * coordinateSize); - - return size; -}; - -Polygon.prototype.toGeoJSON = function (options) { - var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); - geoJSON.type = Types.geoJSON.Polygon; - geoJSON.coordinates = []; - - if (this.exteriorRing.length > 0) { - var exteriorRing = []; - - for (var i = 0; i < this.exteriorRing.length; i++) { - if (this.hasZ) - exteriorRing.push([this.exteriorRing[i].x, this.exteriorRing[i].y, this.exteriorRing[i].z]); - else - exteriorRing.push([this.exteriorRing[i].x, this.exteriorRing[i].y]); - } - - geoJSON.coordinates.push(exteriorRing); - } - - for (var j = 0; j < this.interiorRings.length; j++) { - var interiorRing = []; - - for (var k = 0; k < this.interiorRings[j].length; k++) { - if (this.hasZ) - interiorRing.push([this.interiorRings[j][k].x, this.interiorRings[j][k].y, this.interiorRings[j][k].z]); - else - interiorRing.push([this.interiorRings[j][k].x, this.interiorRings[j][k].y]); - } - - geoJSON.coordinates.push(interiorRing); - } - - return geoJSON; -}; +module.exports = Polygon; + +var util = require('util'); + +var Geometry = require('./geometry'); +var Types = require('./types'); +var Point = require('./point'); +var BinaryWriter = require('./binarywriter'); + +function Polygon(exteriorRing, interiorRings, srid) { + Geometry.call(this); + + this.exteriorRing = exteriorRing || []; + this.interiorRings = interiorRings || []; + this.srid = srid; + + if (this.exteriorRing.length > 0) { + this.hasZ = this.exteriorRing[0].hasZ; + this.hasM = this.exteriorRing[0].hasM; + } +} + +util.inherits(Polygon, Geometry); + +Polygon.Z = function (exteriorRing, interiorRings, srid) { + var polygon = new Polygon(exteriorRing, interiorRings, srid); + polygon.hasZ = true; + return polygon; +}; + +Polygon.M = function (exteriorRing, interiorRings, srid) { + var polygon = new Polygon(exteriorRing, interiorRings, srid); + polygon.hasM = true; + return polygon; +}; + +Polygon.ZM = function (exteriorRing, interiorRings, srid) { + var polygon = new Polygon(exteriorRing, interiorRings, srid); + polygon.hasZ = true; + polygon.hasM = true; + return polygon; +}; + +Polygon._parseWkt = function (value, options) { + var polygon = new Polygon(); + polygon.srid = options.srid; + polygon.hasZ = options.hasZ; + polygon.hasM = options.hasM; + + if (value.isMatch(['EMPTY'])) + return polygon; + + value.expectGroupStart(); + + value.expectGroupStart(); + polygon.exteriorRing.push.apply(polygon.exteriorRing, value.matchCoordinates(options)); + value.expectGroupEnd(); + + while (value.isMatch([','])) { + value.expectGroupStart(); + polygon.interiorRings.push(value.matchCoordinates(options)); + value.expectGroupEnd(); + } + + value.expectGroupEnd(); + + return polygon; +}; + +Polygon._parseWkb = function (value, options) { + var polygon = new Polygon(); + polygon.srid = options.srid; + polygon.hasZ = options.hasZ; + polygon.hasM = options.hasM; + + var ringCount = value.readUInt32(); + + if (ringCount > 0) { + var exteriorRingCount = value.readUInt32(); + + for (var i = 0; i < exteriorRingCount; i++) + polygon.exteriorRing.push(Point._readWkbPoint(value, options)); + + for (i = 1; i < ringCount; i++) { + var interiorRing = []; + + var interiorRingCount = value.readUInt32(); + + for (var j = 0; j < interiorRingCount; j++) + interiorRing.push(Point._readWkbPoint(value, options)); + + polygon.interiorRings.push(interiorRing); + } + } + + return polygon; +}; + +Polygon._parseTwkb = function (value, options) { + var polygon = new Polygon(); + polygon.hasZ = options.hasZ; + polygon.hasM = options.hasM; + + if (options.isEmpty) + return polygon; + + var previousPoint = new Point(0, 0, options.hasZ ? 0 : undefined, options.hasM ? 0 : undefined); + var ringCount = value.readVarInt(); + var exteriorRingCount = value.readVarInt(); + + for (var i = 0; i < exteriorRingCount; i++) + polygon.exteriorRing.push(Point._readTwkbPoint(value, options, previousPoint)); + + for (i = 1; i < ringCount; i++) { + var interiorRing = []; + + var interiorRingCount = value.readVarInt(); + + for (var j = 0; j < interiorRingCount; j++) + interiorRing.push(Point._readTwkbPoint(value, options, previousPoint)); + + polygon.interiorRings.push(interiorRing); + } + + return polygon; +}; + +Polygon._parseGeoJSON = function (value) { + var polygon = new Polygon(); + + if (value.coordinates.length > 0 && value.coordinates[0].length > 0) + polygon.hasZ = value.coordinates[0][0].length > 2; + + for (var i = 0; i < value.coordinates.length; i++) { + if (i > 0) + polygon.interiorRings.push([]); + + for (var j = 0; j < value.coordinates[i].length; j++) { + if (i === 0) + polygon.exteriorRing.push(Point._readGeoJSONPoint(value.coordinates[i][j])); + else + polygon.interiorRings[i - 1].push(Point._readGeoJSONPoint(value.coordinates[i][j])); + } + } + + return polygon; +}; + +Polygon.prototype.toWkt = function () { + if (this.exteriorRing.length === 0) + return this._getWktType(Types.wkt.Polygon, true); + + return this._getWktType(Types.wkt.Polygon, false) + this._toInnerWkt(); +}; + +Polygon.prototype._toInnerWkt = function () { + var innerWkt = '(('; + + for (var i = 0; i < this.exteriorRing.length; i++) + innerWkt += this._getWktCoordinate(this.exteriorRing[i]) + ','; + + innerWkt = innerWkt.slice(0, -1); + innerWkt += ')'; + + for (i = 0; i < this.interiorRings.length; i++) { + innerWkt += ',('; + + for (var j = 0; j < this.interiorRings[i].length; j++) { + innerWkt += this._getWktCoordinate(this.interiorRings[i][j]) + ','; + } + + innerWkt = innerWkt.slice(0, -1); + innerWkt += ')'; + } + + innerWkt += ')'; + + return innerWkt; +}; + +Polygon.prototype.toWkb = function (parentOptions) { + var wkb = new BinaryWriter(this._getWkbSize()); + + wkb.writeInt8(1); + + this._writeWkbType(wkb, Types.wkb.Polygon, parentOptions); + + if (this.exteriorRing.length > 0) { + wkb.writeUInt32LE(1 + this.interiorRings.length); + wkb.writeUInt32LE(this.exteriorRing.length); + } + else { + wkb.writeUInt32LE(0); + } + + for (var i = 0; i < this.exteriorRing.length; i++) + this.exteriorRing[i]._writeWkbPoint(wkb); + + for (i = 0; i < this.interiorRings.length; i++) { + wkb.writeUInt32LE(this.interiorRings[i].length); + + for (var j = 0; j < this.interiorRings[i].length; j++) + this.interiorRings[i][j]._writeWkbPoint(wkb); + } + + return wkb.buffer; +}; + +Polygon.prototype.toTwkb = function () { + var twkb = new BinaryWriter(0, true); + + var precision = Geometry.getTwkbPrecision(5, 0, 0); + var isEmpty = this.exteriorRing.length === 0; + + this._writeTwkbHeader(twkb, Types.wkb.Polygon, precision, isEmpty); + + if (this.exteriorRing.length > 0) { + twkb.writeVarInt(1 + this.interiorRings.length); + + twkb.writeVarInt(this.exteriorRing.length); + + var previousPoint = new Point(0, 0, 0, 0); + for (var i = 0; i < this.exteriorRing.length; i++) + this.exteriorRing[i]._writeTwkbPoint(twkb, precision, previousPoint); + + for (i = 0; i < this.interiorRings.length; i++) { + twkb.writeVarInt(this.interiorRings[i].length); + + for (var j = 0; j < this.interiorRings[i].length; j++) + this.interiorRings[i][j]._writeTwkbPoint(twkb, precision, previousPoint); + } + } + + return twkb.buffer; +}; + +Polygon.prototype._getWkbSize = function () { + var coordinateSize = 16; + + if (this.hasZ) + coordinateSize += 8; + if (this.hasM) + coordinateSize += 8; + + var size = 1 + 4 + 4; + + if (this.exteriorRing.length > 0) + size += 4 + (this.exteriorRing.length * coordinateSize); + + for (var i = 0; i < this.interiorRings.length; i++) + size += 4 + (this.interiorRings[i].length * coordinateSize); + + return size; +}; + +Polygon.prototype.toGeoJSON = function (options) { + var geoJSON = Geometry.prototype.toGeoJSON.call(this, options); + geoJSON.type = Types.geoJSON.Polygon; + geoJSON.coordinates = []; + + if (this.exteriorRing.length > 0) { + var exteriorRing = []; + + for (var i = 0; i < this.exteriorRing.length; i++) { + if (this.hasZ) + exteriorRing.push([this.exteriorRing[i].x, this.exteriorRing[i].y, this.exteriorRing[i].z]); + else + exteriorRing.push([this.exteriorRing[i].x, this.exteriorRing[i].y]); + } + + geoJSON.coordinates.push(exteriorRing); + } + + for (var j = 0; j < this.interiorRings.length; j++) { + var interiorRing = []; + + for (var k = 0; k < this.interiorRings[j].length; k++) { + if (this.hasZ) + interiorRing.push([this.interiorRings[j][k].x, this.interiorRings[j][k].y, this.interiorRings[j][k].z]); + else + interiorRing.push([this.interiorRings[j][k].x, this.interiorRings[j][k].y]); + } + + geoJSON.coordinates.push(interiorRing); + } + + return geoJSON; +}; diff --git a/backend/node_modules/wkx/lib/types.js b/backend/node_modules/wkx/lib/types.js index 5d9f0b0..b21ee16 100644 --- a/backend/node_modules/wkx/lib/types.js +++ b/backend/node_modules/wkx/lib/types.js @@ -1,29 +1,29 @@ -module.exports = { - wkt: { - Point: 'POINT', - LineString: 'LINESTRING', - Polygon: 'POLYGON', - MultiPoint: 'MULTIPOINT', - MultiLineString: 'MULTILINESTRING', - MultiPolygon: 'MULTIPOLYGON', - GeometryCollection: 'GEOMETRYCOLLECTION' - }, - wkb: { - Point: 1, - LineString: 2, - Polygon: 3, - MultiPoint: 4, - MultiLineString: 5, - MultiPolygon: 6, - GeometryCollection: 7 - }, - geoJSON: { - Point: 'Point', - LineString: 'LineString', - Polygon: 'Polygon', - MultiPoint: 'MultiPoint', - MultiLineString: 'MultiLineString', - MultiPolygon: 'MultiPolygon', - GeometryCollection: 'GeometryCollection' - } -}; +module.exports = { + wkt: { + Point: 'POINT', + LineString: 'LINESTRING', + Polygon: 'POLYGON', + MultiPoint: 'MULTIPOINT', + MultiLineString: 'MULTILINESTRING', + MultiPolygon: 'MULTIPOLYGON', + GeometryCollection: 'GEOMETRYCOLLECTION' + }, + wkb: { + Point: 1, + LineString: 2, + Polygon: 3, + MultiPoint: 4, + MultiLineString: 5, + MultiPolygon: 6, + GeometryCollection: 7 + }, + geoJSON: { + Point: 'Point', + LineString: 'LineString', + Polygon: 'Polygon', + MultiPoint: 'MultiPoint', + MultiLineString: 'MultiLineString', + MultiPolygon: 'MultiPolygon', + GeometryCollection: 'GeometryCollection' + } +}; diff --git a/backend/node_modules/wkx/lib/wktparser.js b/backend/node_modules/wkx/lib/wktparser.js index 5d0b0df..ffb8a93 100644 --- a/backend/node_modules/wkx/lib/wktparser.js +++ b/backend/node_modules/wkx/lib/wktparser.js @@ -1,124 +1,124 @@ -module.exports = WktParser; - -var Types = require('./types'); -var Point = require('./point'); - -function WktParser(value) { - this.value = value; - this.position = 0; -} - -WktParser.prototype.match = function (tokens) { - this.skipWhitespaces(); - - for (var i = 0; i < tokens.length; i++) { - if (this.value.substring(this.position).indexOf(tokens[i]) === 0) { - this.position += tokens[i].length; - return tokens[i]; - } - } - - return null; -}; - -WktParser.prototype.matchRegex = function (tokens) { - this.skipWhitespaces(); - - for (var i = 0; i < tokens.length; i++) { - var match = this.value.substring(this.position).match(tokens[i]); - - if (match) { - this.position += match[0].length; - return match; - } - } - - return null; -}; - -WktParser.prototype.isMatch = function (tokens) { - this.skipWhitespaces(); - - for (var i = 0; i < tokens.length; i++) { - if (this.value.substring(this.position).indexOf(tokens[i]) === 0) { - this.position += tokens[i].length; - return true; - } - } - - return false; -}; - -WktParser.prototype.matchType = function () { - var geometryType = this.match([Types.wkt.Point, Types.wkt.LineString, Types.wkt.Polygon, Types.wkt.MultiPoint, - Types.wkt.MultiLineString, Types.wkt.MultiPolygon, Types.wkt.GeometryCollection]); - - if (!geometryType) - throw new Error('Expected geometry type'); - - return geometryType; -}; - -WktParser.prototype.matchDimension = function () { - var dimension = this.match(['ZM', 'Z', 'M']); - - switch (dimension) { - case 'ZM': return { hasZ: true, hasM: true }; - case 'Z': return { hasZ: true, hasM: false }; - case 'M': return { hasZ: false, hasM: true }; - default: return { hasZ: false, hasM: false }; - } -}; - -WktParser.prototype.expectGroupStart = function () { - if (!this.isMatch(['('])) - throw new Error('Expected group start'); -}; - -WktParser.prototype.expectGroupEnd = function () { - if (!this.isMatch([')'])) - throw new Error('Expected group end'); -}; - -WktParser.prototype.matchCoordinate = function (options) { - var match; - - if (options.hasZ && options.hasM) - match = this.matchRegex([/^(\S*)\s+(\S*)\s+(\S*)\s+([^\s,)]*)/]); - else if (options.hasZ || options.hasM) - match = this.matchRegex([/^(\S*)\s+(\S*)\s+([^\s,)]*)/]); - else - match = this.matchRegex([/^(\S*)\s+([^\s,)]*)/]); - - if (!match) - throw new Error('Expected coordinates'); - - if (options.hasZ && options.hasM) - return new Point(parseFloat(match[1]), parseFloat(match[2]), parseFloat(match[3]), parseFloat(match[4])); - else if (options.hasZ) - return new Point(parseFloat(match[1]), parseFloat(match[2]), parseFloat(match[3])); - else if (options.hasM) - return new Point(parseFloat(match[1]), parseFloat(match[2]), undefined, parseFloat(match[3])); - else - return new Point(parseFloat(match[1]), parseFloat(match[2])); -}; - -WktParser.prototype.matchCoordinates = function (options) { - var coordinates = []; - - do { - var startsWithBracket = this.isMatch(['(']); - - coordinates.push(this.matchCoordinate(options)); - - if (startsWithBracket) - this.expectGroupEnd(); - } while (this.isMatch([','])); - - return coordinates; -}; - -WktParser.prototype.skipWhitespaces = function () { - while (this.position < this.value.length && this.value[this.position] === ' ') - this.position++; -}; +module.exports = WktParser; + +var Types = require('./types'); +var Point = require('./point'); + +function WktParser(value) { + this.value = value; + this.position = 0; +} + +WktParser.prototype.match = function (tokens) { + this.skipWhitespaces(); + + for (var i = 0; i < tokens.length; i++) { + if (this.value.substring(this.position).indexOf(tokens[i]) === 0) { + this.position += tokens[i].length; + return tokens[i]; + } + } + + return null; +}; + +WktParser.prototype.matchRegex = function (tokens) { + this.skipWhitespaces(); + + for (var i = 0; i < tokens.length; i++) { + var match = this.value.substring(this.position).match(tokens[i]); + + if (match) { + this.position += match[0].length; + return match; + } + } + + return null; +}; + +WktParser.prototype.isMatch = function (tokens) { + this.skipWhitespaces(); + + for (var i = 0; i < tokens.length; i++) { + if (this.value.substring(this.position).indexOf(tokens[i]) === 0) { + this.position += tokens[i].length; + return true; + } + } + + return false; +}; + +WktParser.prototype.matchType = function () { + var geometryType = this.match([Types.wkt.Point, Types.wkt.LineString, Types.wkt.Polygon, Types.wkt.MultiPoint, + Types.wkt.MultiLineString, Types.wkt.MultiPolygon, Types.wkt.GeometryCollection]); + + if (!geometryType) + throw new Error('Expected geometry type'); + + return geometryType; +}; + +WktParser.prototype.matchDimension = function () { + var dimension = this.match(['ZM', 'Z', 'M']); + + switch (dimension) { + case 'ZM': return { hasZ: true, hasM: true }; + case 'Z': return { hasZ: true, hasM: false }; + case 'M': return { hasZ: false, hasM: true }; + default: return { hasZ: false, hasM: false }; + } +}; + +WktParser.prototype.expectGroupStart = function () { + if (!this.isMatch(['('])) + throw new Error('Expected group start'); +}; + +WktParser.prototype.expectGroupEnd = function () { + if (!this.isMatch([')'])) + throw new Error('Expected group end'); +}; + +WktParser.prototype.matchCoordinate = function (options) { + var match; + + if (options.hasZ && options.hasM) + match = this.matchRegex([/^(\S*)\s+(\S*)\s+(\S*)\s+([^\s,)]*)/]); + else if (options.hasZ || options.hasM) + match = this.matchRegex([/^(\S*)\s+(\S*)\s+([^\s,)]*)/]); + else + match = this.matchRegex([/^(\S*)\s+([^\s,)]*)/]); + + if (!match) + throw new Error('Expected coordinates'); + + if (options.hasZ && options.hasM) + return new Point(parseFloat(match[1]), parseFloat(match[2]), parseFloat(match[3]), parseFloat(match[4])); + else if (options.hasZ) + return new Point(parseFloat(match[1]), parseFloat(match[2]), parseFloat(match[3])); + else if (options.hasM) + return new Point(parseFloat(match[1]), parseFloat(match[2]), undefined, parseFloat(match[3])); + else + return new Point(parseFloat(match[1]), parseFloat(match[2])); +}; + +WktParser.prototype.matchCoordinates = function (options) { + var coordinates = []; + + do { + var startsWithBracket = this.isMatch(['(']); + + coordinates.push(this.matchCoordinate(options)); + + if (startsWithBracket) + this.expectGroupEnd(); + } while (this.isMatch([','])); + + return coordinates; +}; + +WktParser.prototype.skipWhitespaces = function () { + while (this.position < this.value.length && this.value[this.position] === ' ') + this.position++; +}; diff --git a/backend/node_modules/wkx/lib/wkx.d.ts b/backend/node_modules/wkx/lib/wkx.d.ts index 7c97c66..cfe7469 100644 --- a/backend/node_modules/wkx/lib/wkx.d.ts +++ b/backend/node_modules/wkx/lib/wkx.d.ts @@ -1,100 +1,100 @@ -/// - -declare module "wkx" { - - export class Geometry { - srid: number; - hasZ: boolean; - hasM: boolean; - - static parse(value: string | Buffer): Geometry; - static parseTwkb(value: Buffer): Geometry; - static parseGeoJSON(value: {}): Geometry; - - toWkt(): string; - toEwkt(): string; - toWkb(): Buffer; - toEwkb(): Buffer; - toTwkb(): Buffer; - toGeoJSON(options?: GeoJSONOptions): {}; - } - - export interface GeoJSONOptions { - shortCrs?: boolean; - longCrs?: boolean; - } - - export class Point extends Geometry { - x: number; - y: number; - z: number; - m: number; - - constructor(x?: number, y?: number, z?: number, m?: number, srid?: number); - - static Z(x: number, y: number, z: number, srid?: number): Point; - static M(x: number, y: number, m: number, srid?: number): Point; - static ZM(x: number, y: number, z: number, m: number, srid?: number): Point; - } - - export class LineString extends Geometry { - points: Point[]; - - constructor(points?: Point[], srid?: number); - - static Z(points?: Point[], srid?: number): LineString; - static M(points?: Point[], srid?: number): LineString; - static ZM(points?: Point[], srid?: number): LineString; - } - - export class Polygon extends Geometry { - exteriorRing: Point[]; - interiorRings: Point[][]; - - constructor(exteriorRing?: Point[], interiorRings?: Point[][], srid?: number); - - static Z(exteriorRing?: Point[], interiorRings?: Point[][], srid?: number): Polygon; - static M(exteriorRing?: Point[], interiorRings?: Point[][], srid?: number): Polygon; - static ZM(exteriorRing?: Point[], interiorRings?: Point[][], srid?: number): Polygon; - } - - export class MultiPoint extends Geometry { - points: Point[]; - - constructor(points?: Point[], srid?: number); - - static Z(points?: Point[], srid?: number): MultiPoint; - static M(points?: Point[], srid?: number): MultiPoint; - static ZM(points?: Point[], srid?: number): MultiPoint; - } - - export class MultiLineString extends Geometry { - lineStrings: LineString[]; - - constructor(lineStrings?: LineString[], srid?: number); - - static Z(lineStrings?: LineString[], srid?: number): MultiLineString; - static M(lineStrings?: LineString[], srid?: number): MultiLineString; - static ZM(lineStrings?: LineString[], srid?: number): MultiLineString; - } - - export class MultiPolygon extends Geometry { - polygons: Polygon[]; - - constructor(polygons?: Polygon[], srid?: number); - - static Z(polygons?: Polygon[], srid?: number): MultiPolygon; - static M(polygons?: Polygon[], srid?: number): MultiPolygon; - static ZM(polygons?: Polygon[], srid?: number): MultiPolygon; - } - - export class GeometryCollection extends Geometry { - geometries: Geometry[]; - - constructor(geometries?: Geometry[], srid?: number); - - static Z(geometries?: Geometry[], srid?: number): GeometryCollection; - static M(geometries?: Geometry[], srid?: number): GeometryCollection; - static ZM(geometries?: Geometry[], srid?: number): GeometryCollection; - } +/// + +declare module "wkx" { + + export class Geometry { + srid: number; + hasZ: boolean; + hasM: boolean; + + static parse(value: string | Buffer): Geometry; + static parseTwkb(value: Buffer): Geometry; + static parseGeoJSON(value: {}): Geometry; + + toWkt(): string; + toEwkt(): string; + toWkb(): Buffer; + toEwkb(): Buffer; + toTwkb(): Buffer; + toGeoJSON(options?: GeoJSONOptions): {}; + } + + export interface GeoJSONOptions { + shortCrs?: boolean; + longCrs?: boolean; + } + + export class Point extends Geometry { + x: number; + y: number; + z: number; + m: number; + + constructor(x?: number, y?: number, z?: number, m?: number, srid?: number); + + static Z(x: number, y: number, z: number, srid?: number): Point; + static M(x: number, y: number, m: number, srid?: number): Point; + static ZM(x: number, y: number, z: number, m: number, srid?: number): Point; + } + + export class LineString extends Geometry { + points: Point[]; + + constructor(points?: Point[], srid?: number); + + static Z(points?: Point[], srid?: number): LineString; + static M(points?: Point[], srid?: number): LineString; + static ZM(points?: Point[], srid?: number): LineString; + } + + export class Polygon extends Geometry { + exteriorRing: Point[]; + interiorRings: Point[][]; + + constructor(exteriorRing?: Point[], interiorRings?: Point[][], srid?: number); + + static Z(exteriorRing?: Point[], interiorRings?: Point[][], srid?: number): Polygon; + static M(exteriorRing?: Point[], interiorRings?: Point[][], srid?: number): Polygon; + static ZM(exteriorRing?: Point[], interiorRings?: Point[][], srid?: number): Polygon; + } + + export class MultiPoint extends Geometry { + points: Point[]; + + constructor(points?: Point[], srid?: number); + + static Z(points?: Point[], srid?: number): MultiPoint; + static M(points?: Point[], srid?: number): MultiPoint; + static ZM(points?: Point[], srid?: number): MultiPoint; + } + + export class MultiLineString extends Geometry { + lineStrings: LineString[]; + + constructor(lineStrings?: LineString[], srid?: number); + + static Z(lineStrings?: LineString[], srid?: number): MultiLineString; + static M(lineStrings?: LineString[], srid?: number): MultiLineString; + static ZM(lineStrings?: LineString[], srid?: number): MultiLineString; + } + + export class MultiPolygon extends Geometry { + polygons: Polygon[]; + + constructor(polygons?: Polygon[], srid?: number); + + static Z(polygons?: Polygon[], srid?: number): MultiPolygon; + static M(polygons?: Polygon[], srid?: number): MultiPolygon; + static ZM(polygons?: Polygon[], srid?: number): MultiPolygon; + } + + export class GeometryCollection extends Geometry { + geometries: Geometry[]; + + constructor(geometries?: Geometry[], srid?: number); + + static Z(geometries?: Geometry[], srid?: number): GeometryCollection; + static M(geometries?: Geometry[], srid?: number): GeometryCollection; + static ZM(geometries?: Geometry[], srid?: number): GeometryCollection; + } } \ No newline at end of file diff --git a/backend/node_modules/wkx/lib/wkx.js b/backend/node_modules/wkx/lib/wkx.js index e04ae06..48ba61e 100644 --- a/backend/node_modules/wkx/lib/wkx.js +++ b/backend/node_modules/wkx/lib/wkx.js @@ -1,9 +1,9 @@ -exports.Types = require('./types'); -exports.Geometry = require('./geometry'); -exports.Point = require('./point'); -exports.LineString = require('./linestring'); -exports.Polygon = require('./polygon'); -exports.MultiPoint = require('./multipoint'); -exports.MultiLineString = require('./multilinestring'); -exports.MultiPolygon = require('./multipolygon'); +exports.Types = require('./types'); +exports.Geometry = require('./geometry'); +exports.Point = require('./point'); +exports.LineString = require('./linestring'); +exports.Polygon = require('./polygon'); +exports.MultiPoint = require('./multipoint'); +exports.MultiLineString = require('./multilinestring'); +exports.MultiPolygon = require('./multipolygon'); exports.GeometryCollection = require('./geometrycollection'); \ No newline at end of file diff --git a/backend/node_modules/wkx/lib/zigzag.js b/backend/node_modules/wkx/lib/zigzag.js index b4dfeea..aceb238 100644 --- a/backend/node_modules/wkx/lib/zigzag.js +++ b/backend/node_modules/wkx/lib/zigzag.js @@ -1,8 +1,8 @@ -module.exports = { - encode: function (value) { - return (value << 1) ^ (value >> 31); - }, - decode: function (value) { - return (value >> 1) ^ (-(value & 1)); - } -}; +module.exports = { + encode: function (value) { + return (value << 1) ^ (value >> 31); + }, + decode: function (value) { + return (value >> 1) ^ (-(value & 1)); + } +}; diff --git a/backend/node_modules/wkx/package.json b/backend/node_modules/wkx/package.json index 7d2958e..cf663a5 100644 --- a/backend/node_modules/wkx/package.json +++ b/backend/node_modules/wkx/package.json @@ -1,50 +1,50 @@ -{ - "name": "wkx", - "version": "0.5.0", - "description": "A WKT/WKB/EWKT/EWKB/TWKB/GeoJSON parser and serializer", - "main": "lib/wkx.js", - "types": "lib/wkx.d.ts", - "files": [ - "dist/", - "lib/" - ], - "scripts": { - "test": "jshint . && nyc mocha", - "build": "mkdirp ./dist && browserify -r buffer -r ./lib/wkx.js:wkx ./lib/wkx.js > ./dist/wkx.js && uglifyjs -c -m -- ./dist/wkx.js > ./dist/wkx.min.js", - "coverage": "nyc report --reporter=text-lcov | coveralls" - }, - "author": "Christian Schwarz", - "license": "MIT", - "devDependencies": { - "async": "^3.2.0", - "browserify": "^16.5.0", - "coveralls": "^3.0.11", - "deep-eql": "^4.0.0", - "jshint": "^2.11.0", - "json-stringify-pretty-compact": "^2.0.0", - "mkdirp": "^1.0.3", - "mocha": "^7.1.1", - "nyc": "^15.0.0", - "pg": "^7.18.2", - "uglify-js": "^3.8.0" - }, - "repository": { - "type": "git", - "url": "http://github.com/cschwarz/wkx.git" - }, - "keywords": [ - "wkt", - "wkb", - "ewkt", - "ewkb", - "twkb", - "geojson", - "ogc", - "geometry", - "geography", - "spatial" - ], - "dependencies": { - "@types/node": "*" - } +{ + "name": "wkx", + "version": "0.5.0", + "description": "A WKT/WKB/EWKT/EWKB/TWKB/GeoJSON parser and serializer", + "main": "lib/wkx.js", + "types": "lib/wkx.d.ts", + "files": [ + "dist/", + "lib/" + ], + "scripts": { + "test": "jshint . && nyc mocha", + "build": "mkdirp ./dist && browserify -r buffer -r ./lib/wkx.js:wkx ./lib/wkx.js > ./dist/wkx.js && uglifyjs -c -m -- ./dist/wkx.js > ./dist/wkx.min.js", + "coverage": "nyc report --reporter=text-lcov | coveralls" + }, + "author": "Christian Schwarz", + "license": "MIT", + "devDependencies": { + "async": "^3.2.0", + "browserify": "^16.5.0", + "coveralls": "^3.0.11", + "deep-eql": "^4.0.0", + "jshint": "^2.11.0", + "json-stringify-pretty-compact": "^2.0.0", + "mkdirp": "^1.0.3", + "mocha": "^7.1.1", + "nyc": "^15.0.0", + "pg": "^7.18.2", + "uglify-js": "^3.8.0" + }, + "repository": { + "type": "git", + "url": "http://github.com/cschwarz/wkx.git" + }, + "keywords": [ + "wkt", + "wkb", + "ewkt", + "ewkb", + "twkb", + "geojson", + "ogc", + "geometry", + "geography", + "spatial" + ], + "dependencies": { + "@types/node": "*" + } } \ No newline at end of file diff --git a/backend/routes/diaryRoutes.js b/backend/routes/diaryRoutes.js new file mode 100644 index 0000000..f63dec9 --- /dev/null +++ b/backend/routes/diaryRoutes.js @@ -0,0 +1,11 @@ +import express from 'express'; +import { authenticate } from '../middleware/authMiddleware.js'; +import { getDatesForClub, createDateForClub, updateTrainingTimes } from '../controllers/diaryController.js'; + +const router = express.Router(); + +router.get('/:clubId', authenticate, getDatesForClub); +router.post('/:clubId', authenticate, createDateForClub); +router.put('/:clubId', authenticate, updateTrainingTimes); + +export default router; diff --git a/backend/routes/memberRoutes.js b/backend/routes/memberRoutes.js index 9ffd7da..b0e5010 100644 --- a/backend/routes/memberRoutes.js +++ b/backend/routes/memberRoutes.js @@ -1,10 +1,11 @@ -import { getClubMembers, getWaitingApprovals } from '../controllers/memberController.js'; +import { getClubMembers, getWaitingApprovals, setClubMembers } from '../controllers/memberController.js'; import express from 'express'; import { authenticate } from '../middleware/authMiddleware.js'; const router = express.Router(); -router.post('/', authenticate, getClubMembers); +router.get('/:id', authenticate, getClubMembers); +router.post('/:id', authenticate, setClubMembers); router.get('/notapproved/:id', authenticate, getWaitingApprovals); export default router; diff --git a/backend/server.js b/backend/server.js index cd6b60c..005414e 100644 --- a/backend/server.js +++ b/backend/server.js @@ -2,10 +2,13 @@ import express from 'express'; import path from 'path'; import { fileURLToPath } from 'url'; import sequelize from './database.js'; -import './models/index.js'; // Stellt sicher, dass die Modelle und Beziehungen geladen werden +import { User, Log, Club, UserClub } from './models/index.js'; import authRoutes from './routes/authRoutes.js'; -import clubRoutes from './routes/clubRoutes.js' +import clubRoutes from './routes/clubRoutes.js'; +import diaryRoutes from './routes/diaryRoutes.js'; import memberRoutes from './routes/memberRoutes.js'; +import Member from './models/Member.js'; +import DiaryDate from './models/DiaryDates.js'; const app = express(); const port = process.env.PORT || 3000; @@ -17,6 +20,7 @@ app.use(express.json()); app.use('/api/auth', authRoutes); app.use('/api/clubs', clubRoutes); app.use('/api/clubmembers', memberRoutes); +app.use('/api/diary', diaryRoutes); app.use(express.static(path.join(__dirname, '../frontend/dist'))); @@ -24,10 +28,19 @@ app.get('*', (req, res) => { res.sendFile(path.join(__dirname, '../frontend/dist/index.html')); }); -sequelize.sync({ alter: true }).then(() => { - console.log('Database synchronized'); -}); - -app.listen(port, () => { - console.log(`Server is running on http://localhost:${port}`); -}); +(async () => { + try { + await sequelize.authenticate(); + await User.sync({ alter: true }); + await Club.sync({ alter: true }); + await UserClub.sync({ alter: true }); + await Log.sync({ alter: true }); + await Member.sync({ alter: true }); + await DiaryDate.sync({ alter: true }); + app.listen(port, () => { + console.log(`Server is running on http://localhost:${port}`); + }); + } catch (err) { + console.error('Unable to synchronize the database:', err); + } +})(); diff --git a/backend/services/authService.js b/backend/services/authService.js index 2c48b47..bdaab8a 100644 --- a/backend/services/authService.js +++ b/backend/services/authService.js @@ -4,10 +4,15 @@ import User from '../models/User.js'; import { sendActivationEmail } from './emailService.js'; const register = async (email, password) => { - const activationCode = Math.random().toString(36).substring(2, 15); - const user = await User.create({ email, password, activationCode }); - await sendActivationEmail(email, activationCode); - return user; + try { + const activationCode = Math.random().toString(36).substring(2, 15); + const user = await User.create({ email, password, activationCode }); + await sendActivationEmail(email, activationCode); + return user; + } catch (error) { + console.log(error); + return null; + } }; const activateUser = async (activationCode) => { @@ -21,11 +26,12 @@ const activateUser = async (activationCode) => { const login = async (email, password) => { const user = await User.findOne({ where: { email } }); - if (!user || !user.isActive) throw new Error('Invalid email or password'); + if (!user || !user.isActive) throw new Error('Invalid email or password.'); const isPasswordValid = await bcrypt.compare(password, user.password); - if (!isPasswordValid) throw new Error('Invalid email or password'); + if (!isPasswordValid) throw new Error('Invalid email or password!'); const token = jwt.sign({ userId: user.hashedId }, process.env.JWT_SECRET, { expiresIn: '1h' }); - await user.update({ hashedId: token }); + user.authCode = token; + await user.save(); return { token }; }; diff --git a/backend/services/diaryService.js b/backend/services/diaryService.js new file mode 100644 index 0000000..8a7a55f --- /dev/null +++ b/backend/services/diaryService.js @@ -0,0 +1,70 @@ +import DiaryDate from '../models/DiaryDates.js'; +import Club from '../models/Club.js'; +import { checkAccess } from '../utils/userUtils.js'; +import HttpError from '../exceptions/HttpError.js'; + +class DiaryService { + async getDatesForClub(userToken, clubId) { + console.log('[DiaryService::getDatesForClub] - Check user access'); + await checkAccess(userToken, clubId); + console.log('[DiaryService::getDatesForClub] - Validate club existence'); + const club = await Club.findByPk(clubId); + if (!club) { + throw new HttpError('Club not found', 404); + } + console.log('[DiaryService::getDatesForClub] - Load diary dates'); + const dates = await DiaryDate.findAll({ + where: { clubId }, + order: [['date', 'ASC'], ['trainingStart', 'ASC']] + }); + + return dates; + } + + async createDateForClub(userToken, clubId, date, trainingStart, trainingEnd) { + console.log('[DiaryService::createDateForClub] - Check user access'); + await checkAccess(userToken, clubId); + console.log('[DiaryService::createDateForClub] - Validate club existence'); + const club = await Club.findByPk(clubId); + if (!club) { + throw new HttpError('Club not found', 404); + } + console.log('[DiaryService::createDateForClub] - Validate date'); + const parsedDate = new Date(date); + if (isNaN(parsedDate.getTime())) { + throw new HttpError('Invalid date format', 400); + } + if (trainingStart && trainingEnd && trainingStart >= trainingEnd) { + throw new HttpError('Training start time must be before training end time', 400); + } + console.log('[DiaryService::createDateForClub] - Create new diary date'); + const newDate = await DiaryDate.create({ + date: parsedDate, + clubId, + trainingStart: trainingStart || null, + trainingEnd: trainingEnd || null, + }); + + return newDate; + } + + async updateTrainingTimes(userToken, clubId, date, trainingStart, trainingEnd) { + console.log('[DiaryService::updateTrainingTimes] - Check user access'); + await checkAccess(userToken, clubId); + console.log('[DiaryService::updateTrainingTimes] - Validate date'); + const diaryDate = await DiaryDate.findOne({ where: { clubId, date } }); + if (!diaryDate) { + throw new HttpError('Diary entry not found', 404); + } + if (trainingStart && trainingEnd && trainingStart >= trainingEnd) { + throw new HttpError('Training start time must be before training end time', 400); + } + console.log('[DiaryService::updateTrainingTimes] - Update training times'); + diaryDate.trainingStart = trainingStart || null; + diaryDate.trainingEnd = trainingEnd || null; + await diaryDate.save(); + return diaryDate; + } +} + +export default DiaryService; diff --git a/backend/services/emailService.js b/backend/services/emailService.js index 1fcdf52..793740c 100644 --- a/backend/services/emailService.js +++ b/backend/services/emailService.js @@ -3,17 +3,17 @@ import nodemailer from 'nodemailer'; const transporter = nodemailer.createTransport({ service: 'Gmail', auth: { - user: process.env.EMAIL_USER, - pass: process.env.EMAIL_PASS, + user: process.env.EMAIL_USER, + pass: process.env.EMAIL_PASS, }, }); - + const sendActivationEmail = async (email, activationCode) => { const mailOptions = { from: process.env.EMAIL_USER, to: email, subject: 'Account Activation', - text: `Activate your account by clicking the following link: ${process.env.BASE_URL}/api/auth/activate/${activationCode}`, + text: `Activate your account by clicking the following link: ${process.env.BASE_URL}/activate/${activationCode}`, }; await transporter.sendMail(mailOptions); }; diff --git a/backend/services/memberService.js b/backend/services/memberService.js index 0e11ba9..2f82f2c 100644 --- a/backend/services/memberService.js +++ b/backend/services/memberService.js @@ -1,19 +1,81 @@ import UserClub from "../models/UserClub.js"; import { checkAccess } from "../utils/userUtils.js"; +import { getUserByToken } from "../utils/userUtils.js"; +import HttpError from "../exceptions/HttpError.js"; +import Member from "../models/Member.js"; +import { response } from "express"; class MemberService { async getApprovalRequests(userToken, clubId) { - checkAccess(userToken, clubId); - return UserClub.findAll({ + console.log('[MemberService::getApprovalRequest] - Check user access'); + await checkAccess(userToken, clubId); + console.log('[MemberService::getApprovalRequest] - Load user'); + const user = await getUserByToken(userToken); + console.log('[MemberService::getApprovalRequest] - Load userclub'); + return await UserClub.findAll({ where: { clubId: clubId, - approved: false + approved: false, + userId: user.id } }); } - async getClubMembers(clubId) { - + async getClubMembers(userToken, clubId) { + console.log('[getClubMembers] - Check access'); + await checkAccess(userToken, clubId); + console.log('[getClubMembers] - Find members'); + const members = await Member.findAll({ where: { clubId: clubId }}); + console.log('[getClubMembers] - return members'); + return members; + } + + async setClubMember(userToken, clubId, memberId, firstName, lastName, street, city, birthdate, phone, email) { + try { + console.log('[setClubMembers] - Check access'); + await checkAccess(userToken, clubId); + console.log('[setClubMembers] - set default member'); + let member = null; + console.log('[setClubMembers] - load member if possible'); + if (memberId) { + member = await Member.findOne({ where: { id: memberId }}); + } + console.log('[setClubMembers] - set member'); + if (member) { + member.firstName = firstName; + member.lastName = lastName; + member.street = street; + member.city = city; + member.birthDate = birthdate; + member.phone = phone; + member.email = email; + await member.save(); + } else { + await Member.create({ + firstName: firstName, + lastName: lastName, + street: street, + city: city, + birthDate: birthdate, + phone: phone, + email: email, + clubId: clubId, + }); + } + console.log('[setClubMembers] - load club members'); + const members = await this.getClubMembers(userToken, clubId); + console.log('[setClubMembers] - return response'); + return { + status: 200, + response: members, + } + } catch (error) { + console.log(error); + return { + status: error.statusCode || 500, + response: { error: "nocreation" } + } + } } } diff --git a/backend/utils/encrypt.js b/backend/utils/encrypt.js index 91ece5c..f4f2f5a 100644 --- a/backend/utils/encrypt.js +++ b/backend/utils/encrypt.js @@ -5,12 +5,17 @@ const createHash = (value) => { } function encryptData(data) { - const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(process.env.ENCRYPTION_KEY, 'hex'), Buffer.alloc(16, 0)); - let encrypted = cipher.update(data, 'utf8', 'hex'); - encrypted += cipher.final('hex'); - return encrypted; -} - + try { + const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(process.env.ENCRYPTION_KEY, 'hex'), Buffer.alloc(16, 0)); + let encrypted = cipher.update(data, 'utf8', 'hex'); + encrypted += cipher.final('hex'); + return encrypted; + } catch (error) { + console.log(error, data, process.env.ENCRYPTION_KEY, typeof data, process.env.ENCRYPTION_KEY.length); + return ''; + } +} + function decryptData(data) { const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(process.env.ENCRYPTION_KEY, 'hex'), Buffer.alloc(16, 0)); let decrypted = decipher.update(data, 'hex', 'utf8'); @@ -18,4 +23,4 @@ function decryptData(data) { return decrypted; } -export default { createHash, encryptData, decryptData }; \ No newline at end of file +export { createHash, encryptData, decryptData }; \ No newline at end of file diff --git a/backend/utils/userUtils.js b/backend/utils/userUtils.js index 17e572a..13655b8 100644 --- a/backend/utils/userUtils.js +++ b/backend/utils/userUtils.js @@ -1,29 +1,44 @@ import User from '../models/User.js' import UserClub from '../models/UserClub.js'; +import HttpError from '../exceptions/HttpError.js'; export const getUserByToken = async(token) => { - const user = await User.findOne({ - where: [ - {hashed_id: token} - ] - }); - return user; + try { + const user = await User.findOne({ + where: [ + {auth_code: token} + ] + }); + return user; + } catch (error) { + console.log(error); + const err = new HttpError('noaccess', 403); + throw err; + } } export const hasUserClubAccess = async(userId, clubId) => { - const userClub = UserClub.findOne({ - where: { - userId: userId, - clubId: clubId, - approved: true - } - }); - return userClub !== null; + try { + console.log('[hasUserClubAccess]'); + const userClub = await UserClub.findOne({ + where: { + user_id: userId, + club_id: clubId, + approved: true + } + }); + return userClub !== null; + } catch(error) { + console.log(error); + throw new HttpError('notfound', 500); + } } export const checkAccess = async(userToken, clubId) => { - const user = getUserByToken(userToken); - if (!hasUserClubAccess(user.id, clubId)) { - throw new Error('noaccess'); + const user = await getUserByToken(userToken); + if (!await hasUserClubAccess(user.id, clubId)) { + console.log('no club access'); + const err = new HttpError('noaccess', 403); + throw err; } } \ No newline at end of file diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 4764f73..1b27110 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -1,15 +1,29 @@ @@ -40,7 +54,7 @@ export default { } }, methods: { - ...mapActions(['setCurrentClub', 'setClubs']), + ...mapActions(['setCurrentClub', 'setClubs', 'logout']), loadClub() { this.setCurrentClub(this.currentClub); this.$router.push(`/showclub/${this.currentClub}`); @@ -61,13 +75,14 @@ export default { display: flex; height: 100%; overflow: hidden; - flex: 1; } .navigation { width: 10em; background-color: #e0e0e0; + display: flex; + flex-direction: column; } -router-view { +.content { flex: 1; } diff --git a/frontend/src/router.js b/frontend/src/router.js index 87fc874..77acc08 100644 --- a/frontend/src/router.js +++ b/frontend/src/router.js @@ -5,6 +5,8 @@ import Activate from './views/Activate.vue'; import Home from './views/Home.vue'; import CreateClub from './views/CreateClub.vue'; import ClubView from './views/ClubView.vue'; +import MembersView from './views/MembersView.vue'; +import DiaryView from './views/DiaryView.vue'; const routes = [ { path: '/register', component: Register }, @@ -13,6 +15,8 @@ const routes = [ { path: '/', component: Home }, { path: '/createclub', component: CreateClub }, { path: '/showclub/:1', component: ClubView }, + { path: '/members', component: MembersView }, + { path: '/diary', component: DiaryView }, ]; const router = createRouter({ diff --git a/frontend/src/store.js b/frontend/src/store.js index a5477b4..2270908 100644 --- a/frontend/src/store.js +++ b/frontend/src/store.js @@ -44,6 +44,7 @@ const store = createStore({ logout({ commit }) { commit('clearToken'); commit('clearUsername'); + router.push("/"); }, setCurrentClub({ commit }, club) { console.log('action', club); diff --git a/frontend/src/views/ClubView.vue b/frontend/src/views/ClubView.vue index dc820ca..54b7492 100644 --- a/frontend/src/views/ClubView.vue +++ b/frontend/src/views/ClubView.vue @@ -8,7 +8,9 @@

Mitglieder

- +
    +
  • {{ member.lastName }}, {{ member.firstName }}
  • +

Trainingstagebuch

@@ -78,4 +80,10 @@ export default { h2 { display: block; } + +ul { + list-style-type: none; + padding: 0; + margin: 0; +} diff --git a/frontend/src/views/DiaryView.vue b/frontend/src/views/DiaryView.vue new file mode 100644 index 0000000..ab355a5 --- /dev/null +++ b/frontend/src/views/DiaryView.vue @@ -0,0 +1,158 @@ + + + + + diff --git a/frontend/src/views/MembersView.vue b/frontend/src/views/MembersView.vue new file mode 100644 index 0000000..f15e688 --- /dev/null +++ b/frontend/src/views/MembersView.vue @@ -0,0 +1,175 @@ + + + + + \ No newline at end of file