@tak-ps/node-cot 2.8.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +4 -52
- package/.github/workflows/release.yml +4 -1
- package/CHANGELOG.md +8 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/{lib → dist/lib}/color.js +15 -13
- package/dist/lib/color.js.map +1 -0
- package/dist/lib/util.js +101 -0
- package/dist/lib/util.js.map +1 -0
- package/dist/lib/xml.js +171 -0
- package/dist/lib/xml.js.map +1 -0
- package/dist/test/cot.test.js +231 -0
- package/dist/test/cot.test.js.map +1 -0
- package/dist/test/from_geojson.test.js +158 -0
- package/dist/test/from_geojson.test.js.map +1 -0
- package/dist/test/util.test.js +25 -0
- package/dist/test/util.test.js.map +1 -0
- package/lib/color.ts +53 -0
- package/lib/util.ts +123 -0
- package/lib/{xml.js → xml.ts} +68 -23
- package/package.json +19 -7
- package/tsconfig.json +26 -0
- package/lib/util.js +0 -111
- package/package-lock.json +0 -2567
- /package/{index.js → index.ts} +0 -0
- /package/test/{cot.test.js → cot.test.ts} +0 -0
- /package/test/{from_geojson.test.js → from_geojson.test.ts} +0 -0
- /package/test/{util.test.js → util.test.ts} +0 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import test from 'tape';
|
|
2
|
+
import { XML } from '../index.js';
|
|
3
|
+
test('Decode COT message', (t) => {
|
|
4
|
+
const packet = '<event version="2.0" uid="ANDROID-deadbeef" type="a-f-G-U-C" how="m-g" time="2021-02-27T20:32:24.771Z" start="2021-02-27T20:32:24.771Z" stale="2021-02-27T20:38:39.771Z"><point lat="1.234567" lon="-3.141592" hae="-25.7" ce="9.9" le="9999999.0"/><detail><takv os="29" version="4.0.0.0 (deadbeef).1234567890-CIV" device="Some Android Device" platform="ATAK-CIV"/><contact xmppUsername="xmpp@host.com" endpoint="*:-1:stcp" callsign="JENNY"/><uid Droid="JENNY"/><precisionlocation altsrc="GPS" geopointsrc="GPS"/><__group role="Team Member" name="Cyan"/><status battery="78"/><track course="80.24833892285461" speed="0.0"/></detail></event>';
|
|
5
|
+
t.deepEquals((new XML(packet)).raw, {
|
|
6
|
+
'event': {
|
|
7
|
+
'_attributes': {
|
|
8
|
+
'version': '2.0',
|
|
9
|
+
'uid': 'ANDROID-deadbeef',
|
|
10
|
+
'type': 'a-f-G-U-C',
|
|
11
|
+
'how': 'm-g',
|
|
12
|
+
'time': '2021-02-27T20:32:24.771Z',
|
|
13
|
+
'start': '2021-02-27T20:32:24.771Z',
|
|
14
|
+
'stale': '2021-02-27T20:38:39.771Z'
|
|
15
|
+
},
|
|
16
|
+
'point': {
|
|
17
|
+
'_attributes': {
|
|
18
|
+
'lat': 1.234567,
|
|
19
|
+
'lon': -3.141592,
|
|
20
|
+
'hae': -25.7,
|
|
21
|
+
'ce': 9.9,
|
|
22
|
+
'le': 9999999.0
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
'detail': {
|
|
26
|
+
'takv': {
|
|
27
|
+
'_attributes': {
|
|
28
|
+
'os': '29',
|
|
29
|
+
'version': '4.0.0.0 (deadbeef).1234567890-CIV',
|
|
30
|
+
'device': 'Some Android Device',
|
|
31
|
+
'platform': 'ATAK-CIV'
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
'contact': {
|
|
35
|
+
'_attributes': {
|
|
36
|
+
'xmppUsername': 'xmpp@host.com',
|
|
37
|
+
'endpoint': '*:-1:stcp',
|
|
38
|
+
'callsign': 'JENNY'
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
'uid': { '_attributes': { 'Droid': 'JENNY' } },
|
|
42
|
+
'precisionlocation': { '_attributes': { 'altsrc': 'GPS', 'geopointsrc': 'GPS' } },
|
|
43
|
+
'__group': { '_attributes': { 'role': 'Team Member', 'name': 'Cyan' } },
|
|
44
|
+
'status': { '_attributes': { 'battery': '78' } },
|
|
45
|
+
'track': { '_attributes': { 'course': '80.24833892285461', 'speed': '0.0' } }
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
t.end();
|
|
50
|
+
});
|
|
51
|
+
test('Decode COT message', (t) => {
|
|
52
|
+
const packet = '<event version="2.0" uid="TEST-deadbeef" type="a" how="m-g" time="2021-03-12T15:49:07.138Z" start="2021-03-12T15:49:07.138Z" stale="2021-03-12T15:49:07.138Z"><point lat="0.000000" lon="0.000000" hae="0.0" ce="9999999.0" le="9999999.0"/><detail><takv os="Android" version="10" device="Some Device" platform="python unittest"/><status battery="83"/><uid Droid="JENNY"/><contact callsign="JENNY" endpoint="*:-1:stcp" phone="800-867-5309"/><__group role="Team Member" name="Cyan"/><track course="90.1" speed="10.3"/></detail></event>';
|
|
53
|
+
t.deepEquals((new XML(packet)).raw, {
|
|
54
|
+
'event': {
|
|
55
|
+
'_attributes': {
|
|
56
|
+
'version': '2.0',
|
|
57
|
+
'uid': 'TEST-deadbeef',
|
|
58
|
+
'type': 'a',
|
|
59
|
+
'how': 'm-g',
|
|
60
|
+
'time': '2021-03-12T15:49:07.138Z',
|
|
61
|
+
'start': '2021-03-12T15:49:07.138Z',
|
|
62
|
+
'stale': '2021-03-12T15:49:07.138Z'
|
|
63
|
+
},
|
|
64
|
+
'point': {
|
|
65
|
+
'_attributes': {
|
|
66
|
+
'lat': 0.000000,
|
|
67
|
+
'lon': 0.000000,
|
|
68
|
+
'hae': 0.0,
|
|
69
|
+
'ce': 9999999.0,
|
|
70
|
+
'le': 9999999.0
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
'detail': {
|
|
74
|
+
'takv': {
|
|
75
|
+
'_attributes': {
|
|
76
|
+
'os': 'Android',
|
|
77
|
+
'version': '10',
|
|
78
|
+
'device': 'Some Device',
|
|
79
|
+
'platform': 'python unittest'
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
'status': {
|
|
83
|
+
'_attributes': {
|
|
84
|
+
'battery': '83'
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
'uid': {
|
|
88
|
+
'_attributes': {
|
|
89
|
+
'Droid': 'JENNY'
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
'contact': {
|
|
93
|
+
'_attributes': {
|
|
94
|
+
'callsign': 'JENNY',
|
|
95
|
+
'endpoint': '*:-1:stcp',
|
|
96
|
+
'phone': '800-867-5309'
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
'__group': {
|
|
100
|
+
'_attributes': {
|
|
101
|
+
'role': 'Team Member',
|
|
102
|
+
'name': 'Cyan'
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
'track': {
|
|
106
|
+
'_attributes': {
|
|
107
|
+
'course': '90.1',
|
|
108
|
+
'speed': '10.3'
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
t.end();
|
|
115
|
+
});
|
|
116
|
+
test('Encode COT message', (t) => {
|
|
117
|
+
const packet = {
|
|
118
|
+
'event': {
|
|
119
|
+
'_attributes': {
|
|
120
|
+
'version': '2.0',
|
|
121
|
+
'uid': 'ANDROID-deadbeef',
|
|
122
|
+
'type': 'a-f-G-U-C',
|
|
123
|
+
'how': 'm-g',
|
|
124
|
+
'time': '2021-02-27T20:32:24.771Z',
|
|
125
|
+
'start': '2021-02-27T20:32:24.771Z',
|
|
126
|
+
'stale': '2021-02-27T20:38:39.771Z'
|
|
127
|
+
},
|
|
128
|
+
'point': {
|
|
129
|
+
'_attributes': {
|
|
130
|
+
'lat': 1.234567,
|
|
131
|
+
'lon': -3.141592,
|
|
132
|
+
'hae': -25.7,
|
|
133
|
+
'ce': 9.9,
|
|
134
|
+
'le': 9999999
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
'detail': {
|
|
138
|
+
'takv': {
|
|
139
|
+
'_attributes': {
|
|
140
|
+
'os': '29',
|
|
141
|
+
'version': '4.0.0.0 (deadbeef).1234567890-CIV',
|
|
142
|
+
'device': 'Some Android Device',
|
|
143
|
+
'platform': 'ATAK-CIV'
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
'contact': {
|
|
147
|
+
'_attributes': {
|
|
148
|
+
'xmppUsername': 'xmpp@host.com',
|
|
149
|
+
'endpoint': '*:-1:stcp',
|
|
150
|
+
'callsign': 'JENNY'
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
'uid': { '_attributes': { 'Droid': 'JENNY' } },
|
|
154
|
+
'precisionlocation': { '_attributes': { 'altsrc': 'GPS', 'geopointsrc': 'GPS' } },
|
|
155
|
+
'__group': { '_attributes': { 'role': 'Team Member', 'name': 'Cyan' } },
|
|
156
|
+
'status': { '_attributes': { 'battery': '78' } },
|
|
157
|
+
'track': { '_attributes': { 'course': '80.24833892285461', 'speed': '0.0' } }
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
t.deepEquals((new XML(packet)).to_xml(), '<event version="2.0" uid="ANDROID-deadbeef" type="a-f-G-U-C" how="m-g" time="2021-02-27T20:32:24.771Z" start="2021-02-27T20:32:24.771Z" stale="2021-02-27T20:38:39.771Z"><point lat="1.234567" lon="-3.141592" hae="-25.7" ce="9.9" le="9999999"/><detail><takv os="29" version="4.0.0.0 (deadbeef).1234567890-CIV" device="Some Android Device" platform="ATAK-CIV"/><contact xmppUsername="xmpp@host.com" endpoint="*:-1:stcp" callsign="JENNY"/><uid Droid="JENNY"/><precisionlocation altsrc="GPS" geopointsrc="GPS"/><__group role="Team Member" name="Cyan"/><status battery="78"/><track course="80.24833892285461" speed="0.0"/></detail></event>');
|
|
162
|
+
t.end();
|
|
163
|
+
});
|
|
164
|
+
test('Parse GeoChat message', (t) => {
|
|
165
|
+
const geochat = '<event version="2.0" uid="GeoChat.ANDROID-deadbeef.JOKER MAN.563040b9-2ac9-4af3-9e01-4cb2b05d98ea" type="b-t-f" how="h-g-i-g-o" time="2021-02-23T22:28:22.191Z" start="2021-02-23T22:28:22.191Z" stale="2021-02-24T22:28:22.191Z">\n' +
|
|
166
|
+
' <point lat="1.234567" lon="-3.141592" hae="-25.8" ce="9.9" le="9999999.0"/>\n' +
|
|
167
|
+
' <detail>\n' +
|
|
168
|
+
' <__chat parent="RootContactGroup" groupOwner="false" chatroom="JOKER MAN" id="ANDROID-cafebabe" senderCallsign="JENNY">\n' +
|
|
169
|
+
' <chatgrp uid0="ANDROID-deadbeef" uid1="ANDROID-cafebabe" id="ANDROID-cafebabe"/>\n' +
|
|
170
|
+
' </__chat>\n' +
|
|
171
|
+
' <link uid="ANDROID-deadbeef" type="a-f-G-U-C" relation="p-p"/>\n' +
|
|
172
|
+
' <remarks source="BAO.F.ATAK.ANDROID-deadbeef" to="ANDROID-cafebabe" time="2021-02-23T22:28:22.191Z">test</remarks>\n' +
|
|
173
|
+
' <__serverdestination destinations="123.45.67.89:4242:tcp:ANDROID-deadbeef"/>\n' +
|
|
174
|
+
' <marti>\n' +
|
|
175
|
+
' <dest callsign="JOKER MAN"/>\n' +
|
|
176
|
+
' </marti>\n' +
|
|
177
|
+
' </detail>\n' +
|
|
178
|
+
'</event>';
|
|
179
|
+
t.deepEquals((new XML(geochat)).raw, {
|
|
180
|
+
'event': {
|
|
181
|
+
'_attributes': {
|
|
182
|
+
'version': '2.0',
|
|
183
|
+
'uid': 'GeoChat.ANDROID-deadbeef.JOKER MAN.563040b9-2ac9-4af3-9e01-4cb2b05d98ea',
|
|
184
|
+
'type': 'b-t-f',
|
|
185
|
+
'how': 'h-g-i-g-o',
|
|
186
|
+
'time': '2021-02-23T22:28:22.191Z',
|
|
187
|
+
'start': '2021-02-23T22:28:22.191Z',
|
|
188
|
+
'stale': '2021-02-24T22:28:22.191Z'
|
|
189
|
+
},
|
|
190
|
+
'point': {
|
|
191
|
+
'_attributes': {
|
|
192
|
+
'lat': 1.234567,
|
|
193
|
+
'lon': -3.141592,
|
|
194
|
+
'hae': -25.8,
|
|
195
|
+
'ce': 9.9,
|
|
196
|
+
'le': 9999999
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
'detail': {
|
|
200
|
+
'__chat': {
|
|
201
|
+
'_attributes': {
|
|
202
|
+
'parent': 'RootContactGroup',
|
|
203
|
+
'groupOwner': 'false',
|
|
204
|
+
'chatroom': 'JOKER MAN',
|
|
205
|
+
'id': 'ANDROID-cafebabe',
|
|
206
|
+
'senderCallsign': 'JENNY'
|
|
207
|
+
},
|
|
208
|
+
'chatgrp': {
|
|
209
|
+
'_attributes': {
|
|
210
|
+
'uid0': 'ANDROID-deadbeef',
|
|
211
|
+
'uid1': 'ANDROID-cafebabe',
|
|
212
|
+
'id': 'ANDROID-cafebabe'
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
'link': { '_attributes': { 'uid': 'ANDROID-deadbeef', 'type': 'a-f-G-U-C', 'relation': 'p-p' } },
|
|
217
|
+
'remarks': {
|
|
218
|
+
'_attributes': {
|
|
219
|
+
'source': 'BAO.F.ATAK.ANDROID-deadbeef',
|
|
220
|
+
'to': 'ANDROID-cafebabe',
|
|
221
|
+
'time': '2021-02-23T22:28:22.191Z'
|
|
222
|
+
}, '_text': 'test'
|
|
223
|
+
},
|
|
224
|
+
'__serverdestination': { '_attributes': { 'destinations': '123.45.67.89:4242:tcp:ANDROID-deadbeef' } },
|
|
225
|
+
'marti': { 'dest': { '_attributes': { 'callsign': 'JOKER MAN' } } }
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
t.end();
|
|
230
|
+
});
|
|
231
|
+
//# sourceMappingURL=cot.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cot.test.js","sourceRoot":"","sources":["../../test/cot.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import test from 'tape';
|
|
2
|
+
import { XML } from '../index.js';
|
|
3
|
+
test('XML.from_geojson - Point', (t) => {
|
|
4
|
+
const geo = XML.from_geojson({
|
|
5
|
+
type: 'Feature',
|
|
6
|
+
properties: {},
|
|
7
|
+
geometry: {
|
|
8
|
+
type: 'Point',
|
|
9
|
+
coordinates: [1.1, 2.2]
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
t.equals(geo.raw.event._attributes.version, '2.0');
|
|
13
|
+
t.equals(geo.raw.event._attributes.type, 'a-f-G');
|
|
14
|
+
t.equals(geo.raw.event._attributes.how, 'm-g');
|
|
15
|
+
t.equals(geo.raw.event._attributes.uid.length, 36);
|
|
16
|
+
t.equals(geo.raw.event._attributes.time.length, 24);
|
|
17
|
+
t.equals(geo.raw.event._attributes.start.length, 24);
|
|
18
|
+
t.equals(geo.raw.event._attributes.stale.length, 24);
|
|
19
|
+
t.deepEquals(geo.raw.event.point, {
|
|
20
|
+
_attributes: { lat: 2.2, lon: 1.1, hae: 0, ce: 9999999, le: 9999999 }
|
|
21
|
+
});
|
|
22
|
+
t.deepEquals(geo.raw.event.detail, {
|
|
23
|
+
contact: { _attributes: { callsign: 'UNKNOWN' } }
|
|
24
|
+
});
|
|
25
|
+
t.end();
|
|
26
|
+
});
|
|
27
|
+
test('XML.from_geojson - Polygon', (t) => {
|
|
28
|
+
const geo = XML.from_geojson({
|
|
29
|
+
type: 'Feature',
|
|
30
|
+
properties: {},
|
|
31
|
+
geometry: {
|
|
32
|
+
type: 'Polygon',
|
|
33
|
+
coordinates: [[
|
|
34
|
+
[-108.587, 39.098],
|
|
35
|
+
[-108.587, 39.032],
|
|
36
|
+
[-108.505, 39.032],
|
|
37
|
+
[-108.505, 39.098],
|
|
38
|
+
[-108.587, 39.098]
|
|
39
|
+
]]
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
t.equals(geo.raw.event._attributes.version, '2.0');
|
|
43
|
+
t.equals(geo.raw.event._attributes.type, 'u-d-r');
|
|
44
|
+
t.equals(geo.raw.event._attributes.how, 'm-g');
|
|
45
|
+
t.equals(geo.raw.event._attributes.uid.length, 36);
|
|
46
|
+
t.equals(geo.raw.event._attributes.time.length, 24);
|
|
47
|
+
t.equals(geo.raw.event._attributes.start.length, 24);
|
|
48
|
+
t.equals(geo.raw.event._attributes.stale.length, 24);
|
|
49
|
+
t.deepEquals(geo.raw.event.point, {
|
|
50
|
+
_attributes: { lat: 39.065, lon: -108.54599999999999, hae: 0, ce: 9999999, le: 9999999 }
|
|
51
|
+
});
|
|
52
|
+
t.deepEquals(geo.raw.event.detail, {
|
|
53
|
+
contact: { _attributes: { callsign: 'UNKNOWN' } },
|
|
54
|
+
link: [
|
|
55
|
+
{ _attributes: { point: '39.098,-108.587' } },
|
|
56
|
+
{ _attributes: { point: '39.032,-108.587' } },
|
|
57
|
+
{ _attributes: { point: '39.032,-108.505' } },
|
|
58
|
+
{ _attributes: { point: '39.098,-108.505' } }
|
|
59
|
+
],
|
|
60
|
+
labels_on: { _attributes: { value: 'false' } },
|
|
61
|
+
tog: { _attributes: { enabled: '0' } },
|
|
62
|
+
strokeColor: { _attributes: { value: 16776960 } },
|
|
63
|
+
strokeWeight: { _attributes: { value: 3 } },
|
|
64
|
+
strokeStyle: { _attributes: { value: 'solid' } },
|
|
65
|
+
fillColor: { _attributes: { value: 16776960 } }
|
|
66
|
+
});
|
|
67
|
+
t.end();
|
|
68
|
+
});
|
|
69
|
+
test('XML.from_geojson - LineString', (t) => {
|
|
70
|
+
const geo = XML.from_geojson({
|
|
71
|
+
type: 'Feature',
|
|
72
|
+
properties: {},
|
|
73
|
+
geometry: {
|
|
74
|
+
type: 'LineString',
|
|
75
|
+
coordinates: [
|
|
76
|
+
[-108.587, 39.098],
|
|
77
|
+
[-108.587, 39.032],
|
|
78
|
+
[-108.505, 39.032],
|
|
79
|
+
[-108.505, 39.098],
|
|
80
|
+
[-108.587, 39.098]
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
t.equals(geo.raw.event._attributes.version, '2.0');
|
|
85
|
+
t.equals(geo.raw.event._attributes.type, 'u-d-f');
|
|
86
|
+
t.equals(geo.raw.event._attributes.how, 'm-g');
|
|
87
|
+
t.equals(geo.raw.event._attributes.uid.length, 36);
|
|
88
|
+
t.equals(geo.raw.event._attributes.time.length, 24);
|
|
89
|
+
t.equals(geo.raw.event._attributes.start.length, 24);
|
|
90
|
+
t.equals(geo.raw.event._attributes.stale.length, 24);
|
|
91
|
+
t.deepEquals(geo.raw.event.point, {
|
|
92
|
+
_attributes: { lat: 39.098, lon: -108.505, hae: 0, ce: 9999999, le: 9999999 }
|
|
93
|
+
});
|
|
94
|
+
t.deepEquals(geo.raw.event.detail, {
|
|
95
|
+
contact: { _attributes: { callsign: 'UNKNOWN' } },
|
|
96
|
+
link: [
|
|
97
|
+
{ _attributes: { point: '39.098,-108.587' } },
|
|
98
|
+
{ _attributes: { point: '39.032,-108.587' } },
|
|
99
|
+
{ _attributes: { point: '39.032,-108.505' } },
|
|
100
|
+
{ _attributes: { point: '39.098,-108.505' } },
|
|
101
|
+
{ _attributes: { point: '39.098,-108.587' } }
|
|
102
|
+
],
|
|
103
|
+
labels_on: { _attributes: { value: 'false' } },
|
|
104
|
+
tog: { _attributes: { enabled: '0' } },
|
|
105
|
+
strokeColor: { _attributes: { value: 16776960 } },
|
|
106
|
+
strokeWeight: { _attributes: { value: 3 } },
|
|
107
|
+
strokeStyle: { _attributes: { value: 'solid' } }
|
|
108
|
+
});
|
|
109
|
+
t.end();
|
|
110
|
+
});
|
|
111
|
+
test('XML.from_geojson - Start', (t) => {
|
|
112
|
+
const geo = XML.from_geojson({
|
|
113
|
+
type: 'Feature',
|
|
114
|
+
properties: {
|
|
115
|
+
// 1hr in the future
|
|
116
|
+
start: new Date(+new Date() + 60 * 60 * 1000)
|
|
117
|
+
},
|
|
118
|
+
geometry: {
|
|
119
|
+
type: 'Point',
|
|
120
|
+
coordinates: [1.1, 2.2]
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
// Approx +/- 100ms + 1hr ahead of Now
|
|
124
|
+
t.ok(+new Date(geo.raw.event._attributes.start) > +new Date() + 60 * 60 * 1000 - 100);
|
|
125
|
+
t.ok(+new Date(geo.raw.event._attributes.start) < +new Date() + 60 * 60 * 1000 + 100);
|
|
126
|
+
// Approx +/- 100ms ahead of Now
|
|
127
|
+
t.ok(+new Date(geo.raw.event._attributes.time) > +new Date() - 100);
|
|
128
|
+
t.ok(+new Date(geo.raw.event._attributes.time) < +new Date() + 100);
|
|
129
|
+
// Approx +/- 100ms +1hr20s ahead of now
|
|
130
|
+
t.ok(+new Date(geo.raw.event._attributes.stale) > +new Date(geo.raw.event._attributes.start) - 100 + 20 * 1000);
|
|
131
|
+
t.ok(+new Date(geo.raw.event._attributes.stale) < +new Date(geo.raw.event._attributes.start) + 100 + 20 * 1000);
|
|
132
|
+
t.end();
|
|
133
|
+
});
|
|
134
|
+
test('XML.from_geojson - Start/Stale', (t) => {
|
|
135
|
+
const geo = XML.from_geojson({
|
|
136
|
+
type: 'Feature',
|
|
137
|
+
properties: {
|
|
138
|
+
// 1hr in the future
|
|
139
|
+
start: new Date(+new Date() + 60 * 60 * 1000),
|
|
140
|
+
stale: 60 * 1000
|
|
141
|
+
},
|
|
142
|
+
geometry: {
|
|
143
|
+
type: 'Point',
|
|
144
|
+
coordinates: [1.1, 2.2]
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
// Approx +/- 100ms + 1hr ahead of Now
|
|
148
|
+
t.ok(+new Date(geo.raw.event._attributes.start) > +new Date() + 60 * 60 * 1000 - 100);
|
|
149
|
+
t.ok(+new Date(geo.raw.event._attributes.start) < +new Date() + 60 * 60 * 1000 + 100);
|
|
150
|
+
// Approx +/- 100ms ahead of Now
|
|
151
|
+
t.ok(+new Date(geo.raw.event._attributes.time) > +new Date() - 100);
|
|
152
|
+
t.ok(+new Date(geo.raw.event._attributes.time) < +new Date() + 100);
|
|
153
|
+
// Approx +/- 100ms +1hr60s ahead of now
|
|
154
|
+
t.ok(+new Date(geo.raw.event._attributes.stale) > +new Date(geo.raw.event._attributes.start) - 100 + 60 * 1000);
|
|
155
|
+
t.ok(+new Date(geo.raw.event._attributes.stale) < +new Date(geo.raw.event._attributes.start) + 100 + 60 * 1000);
|
|
156
|
+
t.end();
|
|
157
|
+
});
|
|
158
|
+
//# sourceMappingURL=from_geojson.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"from_geojson.test.js","sourceRoot":"","sources":["../../test/from_geojson.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import test from 'tape';
|
|
2
|
+
import Util from '../lib/util.js';
|
|
3
|
+
test('Util.cot_date - default', (t) => {
|
|
4
|
+
const res = Util.cot_date();
|
|
5
|
+
// Within 100ms of current time
|
|
6
|
+
t.ok(+new Date(res.time) > +new Date() - 100, 'res.time within 100ms of current time');
|
|
7
|
+
// res.start is the same as res.time
|
|
8
|
+
t.equals(+new Date(res.start), +new Date(res.time), 'by default res.start === res.time');
|
|
9
|
+
// Approx 20s ahead of start
|
|
10
|
+
t.ok(+new Date(res.stale) > +new Date(res.start) + 20 * 1000 - 100);
|
|
11
|
+
t.ok(+new Date(res.stale) < +new Date(res.start) + 20 * 1000 + 100);
|
|
12
|
+
t.end();
|
|
13
|
+
});
|
|
14
|
+
test('Util.cot_date - stale', (t) => {
|
|
15
|
+
const res = Util.cot_date(null, null, 1000);
|
|
16
|
+
// Within 100ms of current time
|
|
17
|
+
t.ok(+new Date(res.time) > +new Date() - 100, 'res.time within 100ms of current time');
|
|
18
|
+
// res.start is the same as res.time
|
|
19
|
+
t.equals(+new Date(res.start), +new Date(res.time), 'by default res.start === res.time');
|
|
20
|
+
// Approx 1s ahead of start
|
|
21
|
+
t.ok(+new Date(res.stale) > +new Date(res.start) + 1 * 1000 - 100);
|
|
22
|
+
t.ok(+new Date(res.stale) < +new Date(res.start) + 1 * 1000 + 100);
|
|
23
|
+
t.end();
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=util.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.test.js","sourceRoot":"","sources":["../../test/util.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,IAAI,MAAM,gBAAgB,CAAC;AAElC,IAAI,CAAC,yBAAyB,EAAE,CAAC,CAAC,EAAE,EAAE;IAClC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;IAE5B,+BAA+B;IAC/B,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,GAAG,GAAG,EAAE,uCAAuC,CAAC,CAAC;IAEvF,oCAAoC;IACpC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,mCAAmC,CAAC,CAAC;IAEzF,4BAA4B;IAC5B,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;IACpE,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;IAEpE,CAAC,CAAC,GAAG,EAAE,CAAC;AACZ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uBAAuB,EAAE,CAAC,CAAC,EAAE,EAAE;IAChC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAE5C,+BAA+B;IAC/B,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,GAAG,GAAG,EAAE,uCAAuC,CAAC,CAAC;IAEvF,oCAAoC;IACpC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,mCAAmC,CAAC,CAAC;IAEzF,2BAA2B;IAC3B,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;IACnE,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;IAEnE,CAAC,CAAC,GAAG,EAAE,CAAC;AACZ,CAAC,CAAC,CAAC"}
|
package/lib/color.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import _color from 'color';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Helper functions for working with CoT Colours
|
|
5
|
+
*
|
|
6
|
+
* @param {Number|Number[]} color 32bit packged ARGB or [A, R, G, B]
|
|
7
|
+
* @class
|
|
8
|
+
*/
|
|
9
|
+
export default class Color {
|
|
10
|
+
r: number;
|
|
11
|
+
g: number;
|
|
12
|
+
b: number;
|
|
13
|
+
a: number;
|
|
14
|
+
|
|
15
|
+
constructor(color: number | number[]) {
|
|
16
|
+
if (!isNaN(Number(color))) {
|
|
17
|
+
color = Number(color);
|
|
18
|
+
|
|
19
|
+
this.r = (color >> 16) & 255;
|
|
20
|
+
this.g = (color >> 8) & 255;
|
|
21
|
+
this.b = (color >> 0) & 255;
|
|
22
|
+
this.a = ((color >> 24) & 255) / 255;
|
|
23
|
+
} else if (Array.isArray(color)) {
|
|
24
|
+
this.a = color[0];
|
|
25
|
+
this.r = color[1];
|
|
26
|
+
this.g = color[2];
|
|
27
|
+
this.b = color[3];
|
|
28
|
+
} else {
|
|
29
|
+
const c = _color(color);
|
|
30
|
+
|
|
31
|
+
this.a = c.alpha();
|
|
32
|
+
this.r = c.red();
|
|
33
|
+
this.g = c.green();
|
|
34
|
+
this.b = c.blue();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
as_32bit(): number {
|
|
39
|
+
return (this.a << 24) | (this.r << 16) | (this.g << 8) | this.b;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
as_opacity(): number {
|
|
43
|
+
return this.a;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
as_argb(): number[] {
|
|
47
|
+
return [this.a, this.r, this.b, this.g];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
as_rgb(): number[] {
|
|
51
|
+
return [this.r, this.b, this.g];
|
|
52
|
+
}
|
|
53
|
+
}
|
package/lib/util.ts
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { randomUUID } from 'crypto'
|
|
2
|
+
import type {
|
|
3
|
+
Attributes,
|
|
4
|
+
Detail,
|
|
5
|
+
Point
|
|
6
|
+
} from './xml.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Helper functions for generating CoT data
|
|
10
|
+
* @class
|
|
11
|
+
*/
|
|
12
|
+
export default class Util {
|
|
13
|
+
/**
|
|
14
|
+
* Return an event._attributes object with as many defaults as possible
|
|
15
|
+
*
|
|
16
|
+
* @param type CoT Type
|
|
17
|
+
* @param how CoT how
|
|
18
|
+
* @param time Time of CoT Message - if omitted, current time is used
|
|
19
|
+
* @param start Start Time of CoT - if omitted, current time is used
|
|
20
|
+
* @param stale Expiration of CoT - if null now+20s is used. Alternative an integer representing the ms offset
|
|
21
|
+
*/
|
|
22
|
+
static cot_event_attr(
|
|
23
|
+
type: string,
|
|
24
|
+
how: string,
|
|
25
|
+
time?: Date | string | null,
|
|
26
|
+
start?: Date | string | null,
|
|
27
|
+
stale?: Date | string | number | null
|
|
28
|
+
): Attributes {
|
|
29
|
+
if (!type) throw new Error('type param required');
|
|
30
|
+
if (!how) throw new Error('how param required');
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
version: Util.cot_version(),
|
|
34
|
+
uid: Util.cot_uuid(),
|
|
35
|
+
type,
|
|
36
|
+
how,
|
|
37
|
+
...Util.cot_date(time, start, stale)
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Return an event.detail object with as many defaults as possible
|
|
43
|
+
*
|
|
44
|
+
* @param [callsign=UNKNOWN] Display Callsign
|
|
45
|
+
*/
|
|
46
|
+
static cot_event_detail(callsign = 'UNKNOWN'): Detail {
|
|
47
|
+
return {
|
|
48
|
+
contact: {
|
|
49
|
+
_attributes: { callsign }
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Generate a random UUID
|
|
56
|
+
*/
|
|
57
|
+
static cot_uuid(): string {
|
|
58
|
+
return randomUUID()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Return the current version number this library supports
|
|
63
|
+
*/
|
|
64
|
+
static cot_version(): string {
|
|
65
|
+
return '2.0';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Generate Null Island CoT point object
|
|
70
|
+
*/
|
|
71
|
+
static cot_point(): Point {
|
|
72
|
+
return {
|
|
73
|
+
'_attributes': {
|
|
74
|
+
'lat': '0.000000',
|
|
75
|
+
'lon': '0.000000',
|
|
76
|
+
'hae': '0.0',
|
|
77
|
+
'ce': '9999999.0',
|
|
78
|
+
'le': '9999999.0'
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Generate CoT date objects
|
|
85
|
+
*
|
|
86
|
+
* cot_date() - Time: now, Start: now, Stale: now + 20s
|
|
87
|
+
*
|
|
88
|
+
* @param time Time of CoT Message - if omitted, current time is used
|
|
89
|
+
* @param start Start Time of CoT - if omitted, current time is used
|
|
90
|
+
* @param stale Expiration of CoT - if null now+20s is used. Alternative an integer representing the ms offset
|
|
91
|
+
*/
|
|
92
|
+
static cot_date(
|
|
93
|
+
time?: Date | string | null,
|
|
94
|
+
start?: Date | string | null,
|
|
95
|
+
stale?: Date | string | number | null
|
|
96
|
+
): {
|
|
97
|
+
time: string,
|
|
98
|
+
start: string,
|
|
99
|
+
stale: string
|
|
100
|
+
} {
|
|
101
|
+
const now = Date.now();
|
|
102
|
+
|
|
103
|
+
if (!stale) {
|
|
104
|
+
return {
|
|
105
|
+
time: (new Date(time || now)).toISOString(),
|
|
106
|
+
start: (new Date(start || now)).toISOString(),
|
|
107
|
+
stale: (new Date(new Date(start || now).getTime() + 20 * 1000)).toISOString()
|
|
108
|
+
};
|
|
109
|
+
} else if (!isNaN(parseInt(String(stale)))) {
|
|
110
|
+
return {
|
|
111
|
+
time: (new Date(time || now)).toISOString(),
|
|
112
|
+
start: (new Date(start || now)).toISOString(),
|
|
113
|
+
stale: (new Date(new Date(start || now).getTime() + Number(stale))).toISOString()
|
|
114
|
+
};
|
|
115
|
+
} else {
|
|
116
|
+
return {
|
|
117
|
+
time: (new Date(time || now)).toISOString(),
|
|
118
|
+
start: (new Date(start || now)).toISOString(),
|
|
119
|
+
stale: String(stale)
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|