full settings overhaul
This commit is contained in:
266
web/src/lib/vendor/easy-fit/binary.ts
vendored
Normal file
266
web/src/lib/vendor/easy-fit/binary.ts
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
import { FIT } from "./fit";
|
||||
import { getFitMessage, getFitMessageBaseType } from "./messages";
|
||||
|
||||
export { addEndian, readRecord, getArrayBuffer, calculateCRC };
|
||||
|
||||
|
||||
function addEndian(littleEndian: boolean, bytes: any[]) {
|
||||
var result = 0;
|
||||
if (!littleEndian) bytes.reverse();
|
||||
for (var i = 0; i < bytes.length; i++) {
|
||||
result += bytes[i] << (i << 3) >>> 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function readData(blob: Uint8Array, fDef: { endianAbility: boolean; size: number; littleEndian: boolean; type: string; }, startIndex: number) {
|
||||
if (fDef.endianAbility === true) {
|
||||
var temp = [];
|
||||
for (var i = 0; i < fDef.size; i++) {
|
||||
temp.push(blob[startIndex + i]);
|
||||
}
|
||||
var uint32Rep = addEndian(fDef.littleEndian, temp);
|
||||
|
||||
if (fDef.type === 'sint32') {
|
||||
return uint32Rep >> 0;
|
||||
}
|
||||
|
||||
return uint32Rep;
|
||||
}
|
||||
return blob[startIndex];
|
||||
}
|
||||
|
||||
function formatByType(data: number, type: string | number, scale: number, offset: number) {
|
||||
switch (type) {
|
||||
case 'date_time':
|
||||
return new Date(data * 1000 + 631065600000);
|
||||
case 'sint32':
|
||||
case 'sint16':
|
||||
return data * FIT.scConst;
|
||||
case 'uint32':
|
||||
case 'uint16':
|
||||
return scale ? data / scale + offset : data;
|
||||
default:
|
||||
if (FIT.types[type]) {
|
||||
return FIT.types[type][data];
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
function isInvalidValue(data: number, type: string) {
|
||||
switch (type) {
|
||||
case 'enum':
|
||||
return data === 0xFF;
|
||||
case 'sint8':
|
||||
return data === 0x7F;
|
||||
case 'uint8':
|
||||
return data === 0xFF;
|
||||
case 'sint16':
|
||||
return data === 0x7FFF;
|
||||
case 'unit16':
|
||||
return data === 0xFFFF;
|
||||
case 'sint32':
|
||||
return data === 0x7FFFFFFF;
|
||||
case 'uint32':
|
||||
return data === 0xFFFFFFFF;
|
||||
case 'string':
|
||||
return data === 0x00;
|
||||
case 'float32':
|
||||
return data === 0xFFFFFFFF;
|
||||
case 'float64':
|
||||
return data === 0xFFFFFFFFFFFFFFFF;
|
||||
case 'uint8z':
|
||||
return data === 0x00;
|
||||
case 'uint16z':
|
||||
return data === 0x0000;
|
||||
case 'uint32z':
|
||||
return data === 0x000000;
|
||||
case 'byte':
|
||||
return data === 0xFF;
|
||||
case 'sint64':
|
||||
return data === 0x7FFFFFFFFFFFFFFF;
|
||||
case 'uint64':
|
||||
return data === 0xFFFFFFFFFFFFFFFF;
|
||||
case 'uint64z':
|
||||
return data === 0x0000000000000000;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function convertTo(data: number, unitsList: string, speedUnit: string | number) {
|
||||
var unitObj = FIT.options[unitsList][speedUnit];
|
||||
return unitObj ? data * unitObj.multiplier + unitObj.offset : data;
|
||||
}
|
||||
|
||||
function applyOptions(data: number, field: any, options: { speedUnit?: string | number; lengthUnit?: string | number; temperatureUnit?: string | number; }) {
|
||||
switch (field) {
|
||||
case 'speed':
|
||||
case 'enhanced_speed':
|
||||
case 'vertical_speed':
|
||||
case 'avg_speed':
|
||||
case 'max_speed':
|
||||
case 'speed_1s':
|
||||
case 'ball_speed':
|
||||
case 'enhanced_avg_speed':
|
||||
case 'enhanced_max_speed':
|
||||
case 'avg_pos_vertical_speed':
|
||||
case 'max_pos_vertical_speed':
|
||||
case 'avg_neg_vertical_speed':
|
||||
case 'max_neg_vertical_speed':
|
||||
return convertTo(data, 'speedUnits', options.speedUnit ?? 0);
|
||||
case 'distance':
|
||||
case 'total_distance':
|
||||
case 'enhanced_avg_altitude':
|
||||
case 'enhanced_min_altitude':
|
||||
case 'enhanced_max_altitude':
|
||||
case 'enhanced_altitude':
|
||||
case 'height':
|
||||
case 'odometer':
|
||||
case 'avg_stroke_distance':
|
||||
case 'min_altitude':
|
||||
case 'avg_altitude':
|
||||
case 'max_altitude':
|
||||
case 'total_ascent':
|
||||
case 'total_descent':
|
||||
case 'altitude':
|
||||
case 'cycle_length':
|
||||
case 'auto_wheelsize':
|
||||
case 'custom_wheelsize':
|
||||
case 'gps_accuracy':
|
||||
return convertTo(data, 'lengthUnits', options.lengthUnit ?? 0);
|
||||
case 'temperature':
|
||||
case 'avg_temperature':
|
||||
case 'max_temperature':
|
||||
return convertTo(data, 'temperatureUnits', options.temperatureUnit ?? 0);
|
||||
default:
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
function readRecord(blob: Uint8Array, messageTypes: Record<number, any>, startIndex: number, options: { elapsedRecordField?: any; speedUnit?: string | number; lengthUnit?: string | number; temperatureUnit?: string | number; }, startDate: number | undefined) {
|
||||
var recordHeader = blob[startIndex];
|
||||
var localMessageType = recordHeader & 15;
|
||||
|
||||
if ((recordHeader & 64) === 64) {
|
||||
// is definition message
|
||||
// startIndex + 1 is reserved
|
||||
|
||||
var lEnd = blob[startIndex + 2] === 0;
|
||||
var mTypeDef: { littleEndian: boolean, globalMessageNumber: number, numberOfFields: number, fieldDefs: any[] } = {
|
||||
littleEndian: lEnd,
|
||||
globalMessageNumber: addEndian(lEnd, [blob[startIndex + 3], blob[startIndex + 4]]),
|
||||
numberOfFields: blob[startIndex + 5],
|
||||
fieldDefs: []
|
||||
};
|
||||
|
||||
var _message = getFitMessage(mTypeDef.globalMessageNumber);
|
||||
|
||||
for (var i = 0; i < mTypeDef.numberOfFields; i++) {
|
||||
var fDefIndex = startIndex + 6 + i * 3;
|
||||
var baseType = blob[fDefIndex + 2];
|
||||
|
||||
var _message$getAttribute = _message.getAttributes(blob[fDefIndex]),
|
||||
field = _message$getAttribute.field,
|
||||
type = _message$getAttribute.type;
|
||||
|
||||
var fDef = {
|
||||
type: type,
|
||||
fDefNo: blob[fDefIndex],
|
||||
size: blob[fDefIndex + 1],
|
||||
endianAbility: (baseType & 128) === 128,
|
||||
littleEndian: lEnd,
|
||||
baseTypeNo: baseType & 15,
|
||||
name: field,
|
||||
dataType: getFitMessageBaseType(baseType & 15)
|
||||
};
|
||||
|
||||
mTypeDef.fieldDefs.push(fDef);
|
||||
}
|
||||
messageTypes[localMessageType] = mTypeDef;
|
||||
|
||||
return {
|
||||
messageType: 'fieldDescription',
|
||||
nextIndex: startIndex + 6 + mTypeDef.numberOfFields * 3
|
||||
};
|
||||
}
|
||||
|
||||
var messageType: { littleEndian: boolean, globalMessageNumber: number, numberOfFields: number, fieldDefs: any[] } | undefined = void 0;
|
||||
|
||||
if (messageTypes[localMessageType]) {
|
||||
messageType = messageTypes[localMessageType];
|
||||
} else {
|
||||
messageType = messageTypes[0];
|
||||
}
|
||||
|
||||
// TODO: handle compressed header ((recordHeader & 128) == 128)
|
||||
|
||||
// uncompressed header
|
||||
var messageSize = 0;
|
||||
var readDataFromIndex = startIndex + 1;
|
||||
var fields: any = {};
|
||||
var message = getFitMessage(messageType?.globalMessageNumber);
|
||||
|
||||
for (var _i = 0; _i < (messageType?.fieldDefs.length ?? 0); _i++) {
|
||||
var _fDef = messageType?.fieldDefs[_i];
|
||||
var data = readData(blob, _fDef, readDataFromIndex);
|
||||
|
||||
if (!isInvalidValue(data, _fDef.type)) {
|
||||
var _message$getAttribute2 = message.getAttributes(_fDef.fDefNo),
|
||||
field = _message$getAttribute2.field,
|
||||
type = _message$getAttribute2.type,
|
||||
scale = _message$getAttribute2.scale,
|
||||
offset = _message$getAttribute2.offset;
|
||||
|
||||
if (field !== 'unknown' && field !== '' && field !== undefined) {
|
||||
fields[field] = applyOptions(formatByType(data, type, scale, offset), field, options);
|
||||
}
|
||||
|
||||
if (message.name === 'record' && options.elapsedRecordField) {
|
||||
fields.elapsed_time = (fields.timestamp - (startDate ?? 0)) / 1000;
|
||||
}
|
||||
}
|
||||
|
||||
readDataFromIndex += _fDef.size;
|
||||
messageSize += _fDef.size;
|
||||
}
|
||||
|
||||
var result = {
|
||||
messageType: message.name,
|
||||
nextIndex: startIndex + messageSize + 1,
|
||||
message: fields
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function getArrayBuffer(buffer: ArrayBuffer | number[]) {
|
||||
if (buffer instanceof ArrayBuffer) {
|
||||
return buffer;
|
||||
}
|
||||
var ab = new ArrayBuffer(buffer.length);
|
||||
var view = new Uint8Array(ab);
|
||||
for (var i = 0; i < buffer.length; ++i) {
|
||||
view[i] = buffer[i];
|
||||
}
|
||||
return ab;
|
||||
}
|
||||
|
||||
function calculateCRC(blob: Uint8Array, start: number, end: number) {
|
||||
var crcTable = [0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400];
|
||||
|
||||
var crc = 0;
|
||||
for (var i = start; i < end; i++) {
|
||||
var byte = blob[i];
|
||||
var tmp = crcTable[crc & 0xF];
|
||||
crc = crc >> 4 & 0x0FFF;
|
||||
crc = crc ^ tmp ^ crcTable[byte & 0xF];
|
||||
tmp = crcTable[crc & 0xF];
|
||||
crc = crc >> 4 & 0x0FFF;
|
||||
crc = crc ^ tmp ^ crcTable[byte >> 4 & 0xF];
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
156
web/src/lib/vendor/easy-fit/easy-fit.ts
vendored
Normal file
156
web/src/lib/vendor/easy-fit/easy-fit.ts
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
import { calculateCRC, getArrayBuffer, readRecord } from "./binary";
|
||||
|
||||
type Options = {
|
||||
force: boolean,
|
||||
speedUnit: 'm/s' | 'km/h' | 'mph',
|
||||
lengthUnit: 'm' | 'km' | 'mi',
|
||||
temperatureUnit: 'celsius' | 'fahrenheit',
|
||||
elapsedRecordField: boolean,
|
||||
mode: 'cascade' | 'list' | 'both'
|
||||
}
|
||||
|
||||
class EasyFit {
|
||||
options: Options;
|
||||
constructor(
|
||||
options?: Options
|
||||
) {
|
||||
this.options = options || {
|
||||
force: true,
|
||||
speedUnit: 'm/s',
|
||||
lengthUnit: 'm',
|
||||
temperatureUnit: 'celsius',
|
||||
elapsedRecordField: false,
|
||||
mode: 'list'
|
||||
};
|
||||
}
|
||||
|
||||
parse(content: ArrayBuffer, callback: { (error: string, data: any): void; (arg0: string | null, arg1: {}): void; }) {
|
||||
var blob = new Uint8Array(getArrayBuffer(content));
|
||||
|
||||
if (blob.length < 12) {
|
||||
callback('File to small to be a FIT file', {});
|
||||
if (!this.options.force) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var headerLength = blob[0];
|
||||
if (headerLength !== 14 && headerLength !== 12) {
|
||||
callback('Incorrect header size', {});
|
||||
if (!this.options.force) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var fileTypeString = '';
|
||||
for (var i = 8; i < 12; i++) {
|
||||
fileTypeString += String.fromCharCode(blob[i]);
|
||||
}
|
||||
if (fileTypeString !== '.FIT') {
|
||||
callback('Missing \'.FIT\' in header', {});
|
||||
if (!this.options.force) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (headerLength === 14) {
|
||||
var crcHeader = blob[12] + (blob[13] << 8);
|
||||
var crcHeaderCalc = calculateCRC(blob, 0, 12);
|
||||
if (crcHeader !== crcHeaderCalc) {
|
||||
// callback('Header CRC mismatch', {});
|
||||
// TODO: fix Header CRC check
|
||||
if (!this.options.force) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
var dataLength = blob[4] + (blob[5] << 8) + (blob[6] << 16) + (blob[7] << 24);
|
||||
var crcStart = dataLength + headerLength;
|
||||
var crcFile = blob[crcStart] + (blob[crcStart + 1] << 8);
|
||||
var crcFileCalc = calculateCRC(blob, headerLength === 12 ? 0 : headerLength, crcStart);
|
||||
|
||||
if (crcFile !== crcFileCalc) {
|
||||
// callback('File CRC mismatch', {});
|
||||
// TODO: fix File CRC check
|
||||
if (!this.options.force) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var fitObj = {};
|
||||
var sessions = [];
|
||||
var laps = [];
|
||||
var records = [];
|
||||
var events = [];
|
||||
|
||||
var tempLaps = [];
|
||||
var tempRecords = [];
|
||||
|
||||
var loopIndex = headerLength;
|
||||
var messageTypes: Record<number, any> = [];
|
||||
|
||||
var isModeCascade = this.options.mode === 'cascade';
|
||||
var isCascadeNeeded = isModeCascade || this.options.mode === 'both';
|
||||
|
||||
var startDate = void 0;
|
||||
|
||||
while (loopIndex < crcStart) {
|
||||
var _readRecord = readRecord(blob, messageTypes, loopIndex, this.options, startDate),
|
||||
nextIndex = _readRecord.nextIndex,
|
||||
messageType = _readRecord.messageType,
|
||||
message = _readRecord.message;
|
||||
|
||||
loopIndex = nextIndex;
|
||||
switch (messageType) {
|
||||
case 'lap':
|
||||
if (isCascadeNeeded) {
|
||||
message.records = tempRecords;
|
||||
tempRecords = [];
|
||||
tempLaps.push(message);
|
||||
}
|
||||
laps.push(message);
|
||||
break;
|
||||
case 'session':
|
||||
if (isCascadeNeeded) {
|
||||
message.laps = tempLaps;
|
||||
tempLaps = [];
|
||||
}
|
||||
sessions.push(message);
|
||||
break;
|
||||
case 'event':
|
||||
events.push(message);
|
||||
break;
|
||||
case 'record':
|
||||
if (!startDate) {
|
||||
startDate = message.timestamp;
|
||||
message.elapsed_time = 0;
|
||||
}
|
||||
records.push(message);
|
||||
if (isCascadeNeeded) {
|
||||
tempRecords.push(message);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (messageType !== '') {
|
||||
fitObj[messageType] = message;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isCascadeNeeded) {
|
||||
fitObj.activity.sessions = sessions;
|
||||
fitObj.activity.events = events;
|
||||
}
|
||||
if (!isModeCascade) {
|
||||
fitObj.sessions = sessions;
|
||||
fitObj.laps = laps;
|
||||
fitObj.records = records;
|
||||
fitObj.events = events;
|
||||
}
|
||||
|
||||
callback(null, fitObj);
|
||||
}
|
||||
}
|
||||
|
||||
export default EasyFit
|
||||
2437
web/src/lib/vendor/easy-fit/fit.ts
vendored
Normal file
2437
web/src/lib/vendor/easy-fit/fit.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
16
web/src/lib/vendor/easy-fit/messages.ts
vendored
Normal file
16
web/src/lib/vendor/easy-fit/messages.ts
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
export { getFitMessage, getFitMessageBaseType }
|
||||
|
||||
import { getFieldObject, getMessageName } from "./fit"
|
||||
|
||||
function getFitMessage(messageNum: any) {
|
||||
return {
|
||||
name: getMessageName(messageNum),
|
||||
getAttributes: function getAttributes(fieldNum: any) {
|
||||
return getFieldObject(fieldNum, messageNum);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function getFitMessageBaseType(foo: any) {
|
||||
return foo;
|
||||
}
|
||||
39
web/src/lib/vendor/geoJSONToGPX/index.d.ts
vendored
39
web/src/lib/vendor/geoJSONToGPX/index.d.ts
vendored
@@ -1,39 +0,0 @@
|
||||
import { Feature, FeatureCollection } from 'geojson';
|
||||
declare interface Bounds {
|
||||
minlat: string;
|
||||
minlon: string;
|
||||
maxlat: string;
|
||||
maxlon: string;
|
||||
}
|
||||
declare interface Copyright {
|
||||
author?: string;
|
||||
year?: string;
|
||||
license?: string;
|
||||
}
|
||||
declare interface Link {
|
||||
href: string;
|
||||
text?: string;
|
||||
type?: string;
|
||||
}
|
||||
declare interface Person {
|
||||
name?: string;
|
||||
email?: string;
|
||||
link?: Link;
|
||||
}
|
||||
declare interface MetaData {
|
||||
name?: string;
|
||||
desc?: string;
|
||||
author?: Person;
|
||||
copyright?: Copyright;
|
||||
link?: Link;
|
||||
time?: string;
|
||||
keywords?: string;
|
||||
bounds?: Bounds;
|
||||
}
|
||||
export declare interface Options {
|
||||
creator?: string;
|
||||
version?: string;
|
||||
metadata?: MetaData;
|
||||
}
|
||||
export default function GeoJsonToGpx(geoJson: Feature | FeatureCollection, options?: Options, implementation?: DOMImplementation): XMLDocument;
|
||||
export {};
|
||||
155
web/src/lib/vendor/geoJSONToGPX/index.js
vendored
155
web/src/lib/vendor/geoJSONToGPX/index.js
vendored
@@ -1,155 +0,0 @@
|
||||
export default function GeoJsonToGpx(geoJson, options, implementation) {
|
||||
if (implementation === void 0) { implementation = document.implementation; }
|
||||
var doc = implementation.createDocument('http://www.topografix.com/GPX/1/1', '');
|
||||
var instruct = doc.createProcessingInstruction('xml', 'version="1.0" encoding="UTF-8"');
|
||||
doc.appendChild(instruct);
|
||||
var defaultPackageName = '@dwayneparton/geojson-to-gpx';
|
||||
var creator = (options === null || options === void 0 ? void 0 : options.creator) || defaultPackageName;
|
||||
var createElementWithNS = function (tagName) {
|
||||
return doc.createElementNS('http://www.topografix.com/GPX/1/1', tagName);
|
||||
};
|
||||
var gpx = createElementWithNS('gpx');
|
||||
gpx.setAttribute('version', '1.1');
|
||||
gpx.setAttribute('creator', creator);
|
||||
var wpts = [];
|
||||
var trks = [];
|
||||
function createTagInParentElement(parent, tagName, content) {
|
||||
if (content === undefined) {
|
||||
return;
|
||||
}
|
||||
var element = createElementWithNS(tagName);
|
||||
var contentEl = doc.createTextNode(String(content));
|
||||
element.appendChild(contentEl);
|
||||
parent.appendChild(element);
|
||||
}
|
||||
function addSupportedPropertiesFromObject(el, supports, properties) {
|
||||
if (properties && typeof properties === 'object') {
|
||||
supports.forEach(function (key) {
|
||||
var value = properties[key];
|
||||
if (value && typeof value === 'string' && supports.includes(key)) {
|
||||
createTagInParentElement(el, key, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
function createLinkInParentElement(parent, props) {
|
||||
var href = props.href;
|
||||
if (!href) {
|
||||
return;
|
||||
}
|
||||
var el = createElementWithNS('link');
|
||||
el.setAttribute('href', href);
|
||||
addSupportedPropertiesFromObject(el, ['text', 'type'], props);
|
||||
parent.appendChild(el);
|
||||
}
|
||||
function createTrk(properties) {
|
||||
var el = createElementWithNS('trk');
|
||||
var supports = ['name', 'desc', 'src', 'type'];
|
||||
addSupportedPropertiesFromObject(el, supports, properties);
|
||||
return el;
|
||||
}
|
||||
function createPt(type, position, properties) {
|
||||
var lon = position[0], lat = position[1], ele = position[2], time = position[3];
|
||||
var el = createElementWithNS(type);
|
||||
el.setAttribute('lat', String(lat));
|
||||
el.setAttribute('lon', String(lon));
|
||||
createTagInParentElement(el, 'ele', ele);
|
||||
createTagInParentElement(el, 'time', time);
|
||||
var supports = ['name', 'desc', 'src', 'type'];
|
||||
addSupportedPropertiesFromObject(el, supports, properties);
|
||||
return el;
|
||||
}
|
||||
function createTrkSeg(coordinates) {
|
||||
var el = createElementWithNS('trkseg');
|
||||
coordinates.forEach(function (point) {
|
||||
el.appendChild(createPt('trkpt', point));
|
||||
});
|
||||
return el;
|
||||
}
|
||||
function interpretFeature(feature) {
|
||||
var geometry = feature.geometry, properties = feature.properties;
|
||||
var type = geometry.type;
|
||||
switch (type) {
|
||||
case 'Polygon':
|
||||
break;
|
||||
case 'Point': {
|
||||
wpts.push(createPt('wpt', geometry.coordinates, properties));
|
||||
break;
|
||||
}
|
||||
case 'MultiPoint': {
|
||||
geometry.coordinates.forEach(function (coord) {
|
||||
wpts.push(createPt('wpt', coord, properties));
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'LineString': {
|
||||
var lineTrk = createTrk(properties);
|
||||
var trkseg = createTrkSeg(geometry.coordinates);
|
||||
lineTrk.appendChild(trkseg);
|
||||
trks.push(lineTrk);
|
||||
break;
|
||||
}
|
||||
case 'MultiLineString': {
|
||||
var trk_1 = createTrk(properties);
|
||||
geometry.coordinates.forEach(function (pos) {
|
||||
var trkseg = createTrkSeg(pos);
|
||||
trk_1.appendChild(trkseg);
|
||||
});
|
||||
trks.push(trk_1);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (options && typeof options.metadata === 'object') {
|
||||
var meta = options.metadata;
|
||||
var metadata = createElementWithNS('metadata');
|
||||
createTagInParentElement(metadata, 'name', meta.name);
|
||||
createTagInParentElement(metadata, 'desc', meta.desc);
|
||||
if (meta.author && typeof meta.author === 'object') {
|
||||
var author = createElementWithNS('author');
|
||||
createTagInParentElement(author, 'name', meta.author.name);
|
||||
createTagInParentElement(author, 'email', meta.author.email);
|
||||
if (meta.author.link && typeof meta.author.link === 'object') {
|
||||
createLinkInParentElement(author, meta.author.link);
|
||||
}
|
||||
metadata.appendChild(author);
|
||||
}
|
||||
if (typeof meta.copyright === 'object') {
|
||||
var copyright = createElementWithNS('copyright');
|
||||
if (meta.copyright.author) {
|
||||
copyright.setAttribute('author', meta.copyright.author);
|
||||
}
|
||||
createTagInParentElement(copyright, 'year', meta.copyright.year);
|
||||
createTagInParentElement(copyright, 'license', meta.copyright.license);
|
||||
metadata.appendChild(copyright);
|
||||
}
|
||||
if (typeof meta.link === 'object') {
|
||||
createLinkInParentElement(metadata, meta.link);
|
||||
}
|
||||
createTagInParentElement(metadata, 'time', meta.time);
|
||||
createTagInParentElement(metadata, 'keywords', meta.keywords);
|
||||
gpx.appendChild(metadata);
|
||||
}
|
||||
var type = geoJson.type;
|
||||
switch (type) {
|
||||
case 'Feature': {
|
||||
interpretFeature(geoJson);
|
||||
break;
|
||||
}
|
||||
case 'FeatureCollection': {
|
||||
var features = geoJson.features;
|
||||
features.forEach(function (feature) {
|
||||
interpretFeature(feature);
|
||||
});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
wpts.forEach(function (wpt) { return gpx.appendChild(wpt); });
|
||||
trks.forEach(function (trk) { return gpx.appendChild(trk); });
|
||||
doc.appendChild(gpx);
|
||||
return doc;
|
||||
}
|
||||
@@ -134,7 +134,9 @@ export const createForm = (config) => {
|
||||
return clearErrorsAndSubmit(values);
|
||||
} else {
|
||||
errors.set(error);
|
||||
onError(error)
|
||||
if(onError) {
|
||||
onError(error)
|
||||
}
|
||||
isSubmitting.set(false);
|
||||
}
|
||||
})
|
||||
@@ -156,7 +158,9 @@ export const createForm = (config) => {
|
||||
yupErrors.inner.map((error) =>
|
||||
util.set(updatedErrors, error.path, error.message),
|
||||
);
|
||||
onError(updatedErrors)
|
||||
if(onError) {
|
||||
onError(updatedErrors)
|
||||
}
|
||||
errors.set(updatedErrors);
|
||||
}
|
||||
isSubmitting.set(false);
|
||||
|
||||
Reference in New Issue
Block a user