@tomtom-org/maps-sdk-plugin-map-theme 0.1.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/LICENSE.txt +511 -0
- package/README.md +35 -0
- package/THIRD_PARTY.txt +47 -0
- package/dist/THIRD_PARTY.txt +36 -0
- package/dist/index.d.ts +159 -0
- package/dist/index.es.js +2 -0
- package/dist/index.es.js.map +1 -0
- package/dist/third-party.json +12 -0
- package/package.json +45 -0
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
TOMTOM MAPS SDK FOR JAVASCRIPT LICENSE AGREEMENT (“AGREEMENT”)
|
|
2
|
+
|
|
3
|
+
Last update: 29 May 2026
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
By downloading, accessing the “TomTom Maps SDK for JavaScript”, you are entering into a binding agreement with TomTom Global Content B.V. (“TomTom”). The 'TomTom Maps SDK for JavaScript' includes all software, binaries, and source code made available by TomTom, whether through the TomTom developer portal or public code repositories (e.g., GitHub)." Your agreement with TomTom includes the following terms and conditions and the Privacy Policy (Data Processing Schedule | TomTom). You should not use the TomTom Maps SDK for JavaScript if you cannot agree to this Agreement and the Privacy Policy.
|
|
8
|
+
|
|
9
|
+
You may not use the TomTom Maps SDK for JavaScript and may not accept the Agreement if you are a person barred from receiving the TomTom Maps SDK for JavaScript under the laws of the European Union or other countries, including the country in which you are resident or from which you use the TomTom Maps SDK for JavaScript. If you agree to be bound by the Agreement on behalf of your employer or other entity, you represent and warrant that you have full legal authority to bind your employer or such entity to the Agreement. If you do not have the requisite authority, you may not accept the Agreement or use the TomTom Maps SDK for JavaScript on behalf of your employer or other entity.
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
1. GRANT OF LICENSE: Subject to and conditional upon your compliance at all times with this Agreement, TomTom grants to you a limited, non-exclusive, non-transferable and non-sublicensable, revocable, royalty-free license during the Term (as defined in Clause 9) to use the TomTom Maps SDK for JavaScript in connection with the development of web based applications or mobile applications to be used in connection with the TomTom APIs and, in addition, third party online APIs (“Permitted Applications”). For the avoidance of doubt, you must use the TomTom APIs in connection with the TomTom Maps SDK for JavaScript. Any such Permitted Application and use of the TomTom APIs shall be subject to TomTom’s standard terms of use applicable to the TomTom APIs as made available on the TomTom developer portal or any other specific written agreement that you and TomTom have executed regarding the use of the TomTom APIs.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
2. UPDATES AND CHANGES TO THE TOMTOM MAPS SDK FOR JAVASCRIPT AND THIS AGREEMENT: TomTom reserves the right, with or without notice and at its sole discretion, to discontinue, update, modify, upgrade and supplement any of the TomTom Maps SDK for JavaScript or any features within the TomTom Maps SDK for JavaScript and to modify this Agreement. You agree that future versions of the TomTom Maps SDK for JavaScript may be incompatible with applications that were developed on previous versions of the TomTom Maps SDK for JavaScript.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
3. YOUR FURTHER OBLIGATIONS:
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
3.1. You agree to use the TomTom Maps SDK for JavaScript only for purposes that are permitted by (a) this Agreement and (b) any applicable law, regulation or generally accepted practices or guidelines in the relevant jurisdictions (including any laws regarding the export of data or software to and from the United States or other relevant countries).
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
3.2. Other than as permitted by applicable legislation, you are prohibited from copying (except for backup purposes), modifying, adapting, (re)distributing, renting, lending, publicly presenting, decompiling, reverse engineering, disassembling, or creating derivative works of the TomTom Maps SDK for JavaScript or any part of the TomTom Maps SDK for JavaScript. Notwithstanding the foregoing, if the TomTom Maps SDK is hosted on a public repository (e.g. GitHub, which allows forking under its terms of service), you may: (i) fork the repository solely for the purpose of submitting a Pull Request to TomTom, provided that such fork remains hosted within the platform and may not be used as a basis for a separate or competing product or service; and (ii) download a local copy of the source code solely for the purpose of debugging your Permitted Application, provided that such copy is not shared or redistributed. The availability of the source code in a public repository, and any rights granted by that platform's terms of service with respect to viewing or forking within the platform, do not constitute — and shall not be construed as — a grant of rights to modify, fork, or redistribute.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
3.3. You may not use the TomTom Maps SDK for JavaScript in connection with any illegal, fraudulent, dishonest or unethical activity or behaviour, specially to create, develop, or help others create or develop a product, service, or library that competes, directly or indirectly, with the TomTom Maps SDK or the TomTom APIs.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
3.4. You shall be permitted to display TomTom APIs results (“Results”) on third party content or map data provided that nothing shall entitle you to add or incorporate Results into the OSM or any other open source database. You shall also be permitted to display Results from third party content or map data on a TomTom map as a separate layer.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
3.5. The TomTom Maps SDK for JavaScript may include data which TomTom licenses from third parties or open-source software. You shall comply with all requirements and restrictions which such third parties may require TomTom to impose on you (and as may be updated and amended by TomTom from time to time). It shall be your responsibility to check, review and comply with any updated or amended terms that would apply to the TomTom Maps SDK for JavaScript licensed to you under this Agreement. For the avoidance of doubt, any such software is made available to you under the terms and conditions of the applicable licenses. In the event of a conflict between this Agreement and an Open-Source license governing a specific dependency, the Open Source license shall prevail solely with respect to that dependency.
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
4. PRIVACY: In order to improve the TomTom Developer Portal and TomTom Maps SDK for JavaScript, TomTom may collect certain usage related information from the software including but not limited to the general SDK and product identifiers, version numbers, and information on which tools and/or services in the TomTom Maps SDK for JavaScript are being used and how they are being used by you. In addition, TomTom may collect your unique identifier and associated IP address for legitimate business reasons (such as without limitation the processing of invoices). This data will be retained for a maximum period of 120 days. The information collected is maintained in accordance with our Privacy Policy.
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
5. INTELLECTUAL PROPERTY RIGHTS AND COPYRIGHT NOTICES:
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
5.1. All intellectual property rights related to the TomTom Maps SDK for JavaScript and to the TomTom APIs are owned by TomTom and/or its licensors and suppliers. However, TomTom agrees that it obtains no intellectual property rights under this Agreement in or to any Permitted Application that you develop using the TomTom Maps SDK for JavaScript and the TomTom APIs.
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
5.2. Your use of any trade names, logos, trademarks, service marks and other marks of TomTom is subject to TomTom’s prior written approval. Any goodwill arising out of the use thereof shall inure to the benefit of TomTom. In addition, you agree not to remove, obscure, mask or change any logo and/or copyright notice placed on or automatically generated by the TomTom Maps SDK for JavaScript or the TomTom APIs.
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
6. WARRANTIES:
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
6.1. YOU ACKNOWLEDGE THAT THE TOMTOM MAPS SDK FOR JAVASCRIPT HAS NOT BEEN DEVELOPED TO MEET YOUR INDIVIDUAL REQUIREMENTS AND THAT IT IS THEREFORE YOUR RESPONSIBILITY TO ENSURE THAT THE FACILITIES AND FUNCTIONS OF THE TOMTOM MAPS SDK FOR JAVASCRIPT MEET YOUR REQUIREMENTS. TOMTOM DOES NOT AND CANNOT WARRANT THAT THE TOMTOM MAPS SDK FOR JAVASCRIPT OPERATES UNINTERRUPTED OR ERROR-FREE. TOMTOM DOES NOT WARRANT THAT THE TOMTOM MAPS SDK FOR JAVASCRIPT IS CAPABLE OF INTEROPERATING WITH ANY OTHER SYSTEM, DEVICE OR PRODUCT (EITHER SOFTWARE OR HARDWARE).
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
6.2. YOUR USE OF THE TOMTOM MAPS SDK FOR JAVASCRIPT AND ANY MATERIAL DOWNLOADED OR OTHERWISE OBTAINED THROUGH THE USE OF THE TOMTOM MAPS SDK FOR JAVASCRIPT IS AT YOUR OWN DISCRETION AND RISK AND YOU ARE SOLELY RESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR OTHER DEVICES OR ANY LOSS OF DATA THAT RESULTS FROM SUCH USE.
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
6.3. WITHOUT LIMITING CLAUSES 6.1 AND 6.2 ABOVE, THE TOMTOM MAPS SDK FOR JAVASCRIPT IS PROVIDED ON AN “AS IS” AND WITH “ALL FAULTS BASIS” AND TOMTOM EXPRESSLY DISCLAIMS ALL OTHER WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, SATISFACTORY QUALITY, ACCURACY, TITLE AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
6.4. THE PROVISIONS OF THIS CLAUSE DO NOT AFFECT ANY OF YOUR LEGAL RIGHTS UNDER APPLICABLE MANDATORY NATIONAL LEGISLATION, INCLUDING BUT NOT LIMITED TO ANY MANDATORY STATUTORY WARRANTIES. IF ANY PART OF THIS LIMITED WARRANTY IS HELD TO BE INVALID OR UNENFORCEABLE, THE REMAINDER OF THE LIMITED WARRANTY SHALL NONETHELESS REMAIN IN FULL FORCE AND EFFECT.
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
7. LIMITATION OF LIABILITY:
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
7.1. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, NEITHER TOMTOM NOR ITS LICENSORS, SUPPLIERS, OFFICERS, DIRECTORS OR EMPLOYEES SHALL BE LIABLE TO YOU OR TO ANY THIRD PARTY FOR ANY DAMAGES, WHETHER DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL (INCLUDING BUT NOT LIMITED TO DAMAGES FOR THE INABILITY TO USE OR ACCESS THE TOMTOM MAPS SDK FOR JAVASCRIPT OR TOMTOM APIS, LOSS OF DATA, LOSS OF BUSINESS, LOSS OF PROFITS, BUSINESS INTERRUPTION OR THE LIKE) ARISING OUT OF OR RELATED TO THE USE OF, THE INABILITY TO USE OR ACCESS, OR OTHERWISE THE PERFORMANCE OF THE TOMTOM MAPS SDK FOR JAVASCRIPT, EVEN IF TOMTOM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
7.2. TO THE EXTENT TOMTOM IS NOT PERMITTED UNDER APPLICABLE LAW TO EXCLUDE ITS LIABILITY PURSUANT TO CLAUSE 7.1 ABOVE, TOMTOM’S TOTAL AGGREGATE LIABILITY TO YOU SHALL BE LIMITED TO THE AMOUNT OF EUR100.00.
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
7.3. THE ABOVE LIMITATIONS OF LIABILITY UNDER THIS CLAUSE 7 DO NOT: (I) AFFECT YOUR RIGHTS UNDER ANY APPLICABLE MANDATORY NATIONAL LEGISLATION; (II) EXCLUDE OR LIMIT ANY LIABILITY THAT CANNOT BE EXCLUDED OR LIMITED UNDER APPLICABLE LAW.
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
8. IPR INDMENITY: To the maximum extent permitted by law, you agree to defend, indemnify and hold TomTom and its respective directors, officers, employees, affiliates, agents and suppliers harmless from and against any and all claims, actions, suits or proceedings, as well as any and all losses, liabilities, damages, costs and expenses (including reasonable attorney’s fees) arising out of or accruing from (a) your use of the TomTom Maps SDK for JavaScript, (b) any application you develop on the TomTom Maps SDK for JavaScript that infringes any copyright, trademark, trade secret, trade dress, patent or other intellectual property right of any person or defames any person or violates their rights of publicity or privacy, and (c) any non-compliance by you with this Agreement.
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
9. TERM AND TERMINATION AND DIRECT ENFORCEMENT:
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
9.1. This Agreement begins on either (a) the date you demonstrate your acceptance of the terms and conditions of this Agreement or (b) when you first use the TomTom Maps SDK for JavaScript and shall continue until terminated (jointly the “Term”) by either TomTom or you subject to and in accordance with this Agreement. The provisions of this Agreement, which by their nature are intended to survive termination, will remain in effect after termination of this Agreement. Furthermore, you agree that TomTom may directly enforce these provisions against you.
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
9.2. Without prejudice to any other rights, TomTom may immediately terminate this Agreement if (i) you fail to comply with any of its terms and conditions, or (ii) the agreement governing the use of TomTom APIs between you and TomTom you has terminated, or (iii) TomTom decides to no longer provide the TomTom Maps SDK for JavaScript or certain parts of the TomTom Maps SDK for JavaScript either entirely or in certain territories related to your use.
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
9.3. You may terminate this Agreement by ceasing your use of the TomTom Maps SDK for JavaScript at any time.
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
10. GOVERNING LAW AND DISPUTE RESOLUTION:
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
10.1. If you, your employer or the entity on whose behalf you act is incorporated in the European Union then this Agreement and any dispute arising under or in connection with it, including any non-contractual claims and disputes, shall be governed by and construed in accordance with the laws of the Netherlands. The applicability of the United Nations Convention on Contracts for the International Sale of Goods is explicitly excluded. You and TomTom hereby irrevocably submit to the exclusive jurisdiction of the courts of Amsterdam, the Netherlands in respect of any dispute arising under or in connection with this Agreement, including any non-contractual claims or disputes.
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
10.2. If you, your employer or the entity on whose behalf you act is incorporated outside of European Union, then this Agreement and any dispute arising under or in connection with it, including any non-contractual claims and disputes, shall be governed by and construed in accordance with the laws of the Netherlands. All disputes arising in connection with the Agreement, including any non-contractual claims or disputes, shall be settled in accordance with the Arbitration Rules of the Netherlands Arbitration Institute. The arbitral tribunal shall be composed of three (3) arbitrators. The place or arbitration shall be Amsterdam, and the language of the arbitration shall be English. Consolidation of the arbitral proceedings with other arbitral proceedings, as provided for in Article 1046 of the Dutch Code of Civil Procedure and Article 39 of the Arbitration Rules of the Netherlands Arbitration Institute, is excluded.
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
10.3. Notwithstanding this, TomTom shall still be allowed to apply for injunctive remedies (or an equivalent type of urgent legal relief) in any jurisdiction.
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
11. OTHER LEGAL TERMS:
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
11.1. No failure or delay by TomTom to exercise any right or remedy provided under this Agreement or by law shall constitute a waiver of that or any other right or remedy, nor shall it preclude or restrict the further exercise of that or any other right or remedy. No single or partial exercise of such right or remedy shall preclude or restrict the further exercise of that or any other right or remedy.
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
11.2. Should for any reason, or to any extent, any provision of this Agreement be held invalid or unenforceable, such invalidity or enforceability shall not affect or render invalid or unenforceable the remaining provisions of this Agreement and the application of that provision shall be enforced to the extent permitted by law.
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
11.3. The rights granted to you in this Agreement may not be assigned or transferred by you without TomTom’s prior written approval.
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
11.4. The TomTom APIs and TomTom Maps SDK for JavaScript are provided as “Commercial Computer Software” or “restricted computer software”. Use, duplication, or disclosure by the U.S. Government or U.S. Government subcontractor is subject to the restrictions set forth in 48.C.F.R. Section 12.212 or 48 C.F.R.227.2702, as applicable or successor provisions. In respect of the Map API and Search API, the manufacturer is TomTom Global Content B.V.
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
11.5. The availability of the TomTom Maps SDK source code in a public repository does not constitute 'Open-Source' licensing. This Agreement does not grant you any rights under any Open-Source Initiative (OSI) approved license. Your rights are strictly limited to those expressly granted in Clause 1."
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
11.6 By submitting any suggestion, bug fix, or code contribution (“Contribution”) to TomTom (e.g., via a GitHub Pull Request), you hereby grant TomTom a perpetual, irrevocable, worldwide, royalty-free, and non-exclusive license to use, reproduce, modify, and distribute the Contribution as part of the TomTom Maps SDK. You represent that you have the legal right to grant this license and that the Contribution does not infringe any third-party intellectual property rights.
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
Name: zod
|
|
174
|
+
Version: 4.1.12
|
|
175
|
+
License: MIT
|
|
176
|
+
Private: false
|
|
177
|
+
Description: TypeScript-first schema declaration and validation library with static type inference
|
|
178
|
+
Repository: git+https://github.com/colinhacks/zod.git
|
|
179
|
+
Homepage: https://zod.dev
|
|
180
|
+
Author: Colin McDonnell <zod@colinhacks.com>
|
|
181
|
+
License Copyright:
|
|
182
|
+
===
|
|
183
|
+
|
|
184
|
+
MIT License
|
|
185
|
+
|
|
186
|
+
Copyright (c) 2025 Colin McDonnell
|
|
187
|
+
|
|
188
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
189
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
190
|
+
in the Software without restriction, including without limitation the rights
|
|
191
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
192
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
193
|
+
furnished to do so, subject to the following conditions:
|
|
194
|
+
|
|
195
|
+
The above copyright notice and this permission notice shall be included in all
|
|
196
|
+
copies or substantial portions of the Software.
|
|
197
|
+
|
|
198
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
199
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
200
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
201
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
202
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
203
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
204
|
+
SOFTWARE.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
Name: lodash-es
|
|
209
|
+
Version: 4.17.21
|
|
210
|
+
License: MIT
|
|
211
|
+
Private: false
|
|
212
|
+
Description: Lodash exported as ES modules.
|
|
213
|
+
Repository: undefined
|
|
214
|
+
Homepage: https://lodash.com/custom-builds
|
|
215
|
+
Author: John-David Dalton <john.david.dalton@gmail.com>
|
|
216
|
+
Contributors:
|
|
217
|
+
John-David Dalton <john.david.dalton@gmail.com>
|
|
218
|
+
Mathias Bynens <mathias@qiwi.be>
|
|
219
|
+
License Copyright:
|
|
220
|
+
===
|
|
221
|
+
|
|
222
|
+
Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
|
|
223
|
+
|
|
224
|
+
Based on Underscore.js, copyright Jeremy Ashkenas,
|
|
225
|
+
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
|
|
226
|
+
|
|
227
|
+
This software consists of voluntary contributions made by many
|
|
228
|
+
individuals. For exact contribution history, see the revision history
|
|
229
|
+
available at https://github.com/lodash/lodash
|
|
230
|
+
|
|
231
|
+
The following license applies to all parts of this software except as
|
|
232
|
+
documented below:
|
|
233
|
+
|
|
234
|
+
====
|
|
235
|
+
|
|
236
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
237
|
+
a copy of this software and associated documentation files (the
|
|
238
|
+
"Software"), to deal in the Software without restriction, including
|
|
239
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
240
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
241
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
242
|
+
the following conditions:
|
|
243
|
+
|
|
244
|
+
The above copyright notice and this permission notice shall be
|
|
245
|
+
included in all copies or substantial portions of the Software.
|
|
246
|
+
|
|
247
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
248
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
249
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
250
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
251
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
252
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
253
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
254
|
+
|
|
255
|
+
====
|
|
256
|
+
|
|
257
|
+
Copyright and related rights for sample code are waived via CC0. Sample
|
|
258
|
+
code is defined as all source code displayed within the prose of the
|
|
259
|
+
documentation.
|
|
260
|
+
|
|
261
|
+
CC0: http://creativecommons.org/publicdomain/zero/1.0/
|
|
262
|
+
|
|
263
|
+
====
|
|
264
|
+
|
|
265
|
+
Files located in the node_modules and vendor directories are externally
|
|
266
|
+
maintained libraries used by this software which have their own
|
|
267
|
+
licenses; we recommend you read them, as their terms may differ from the
|
|
268
|
+
terms above.
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
Name: @turf/helpers
|
|
277
|
+
Version: 7.3.0
|
|
278
|
+
License: MIT
|
|
279
|
+
Private: false
|
|
280
|
+
Description: Provides helper functions to create GeoJSON features, like points, lines, or areas on a map.
|
|
281
|
+
Repository: git://github.com/Turfjs/turf.git
|
|
282
|
+
Homepage: https://github.com/Turfjs/turf
|
|
283
|
+
Author: Turf Authors
|
|
284
|
+
Contributors:
|
|
285
|
+
Tom MacWright <@tmcw>
|
|
286
|
+
Stefano Borghi <@stebogit>
|
|
287
|
+
Denis Carriere <@DenisCarriere>
|
|
288
|
+
William Nordmann <@wnordmann>
|
|
289
|
+
License Copyright:
|
|
290
|
+
===
|
|
291
|
+
|
|
292
|
+
The MIT License (MIT)
|
|
293
|
+
|
|
294
|
+
Copyright (c) 2017 TurfJS
|
|
295
|
+
|
|
296
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
297
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
298
|
+
the Software without restriction, including without limitation the rights to
|
|
299
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
300
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
301
|
+
subject to the following conditions:
|
|
302
|
+
|
|
303
|
+
The above copyright notice and this permission notice shall be included in all
|
|
304
|
+
copies or substantial portions of the Software.
|
|
305
|
+
|
|
306
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
307
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
308
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
309
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
310
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
311
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
Name: @turf/invariant
|
|
316
|
+
Version: 7.3.0
|
|
317
|
+
License: MIT
|
|
318
|
+
Private: false
|
|
319
|
+
Description: Lightweight utility for input validation and data extraction in Turf.js. Ensures GeoJSON inputs are in the correct format and extracts specific components like coordinates or geometries.
|
|
320
|
+
Repository: git://github.com/Turfjs/turf.git
|
|
321
|
+
Homepage: https://github.com/Turfjs/turf
|
|
322
|
+
Author: Turf Authors
|
|
323
|
+
Contributors:
|
|
324
|
+
Tom MacWright <@tmcw>
|
|
325
|
+
Denis Carriere <@DenisCarriere>
|
|
326
|
+
License Copyright:
|
|
327
|
+
===
|
|
328
|
+
|
|
329
|
+
The MIT License (MIT)
|
|
330
|
+
|
|
331
|
+
Copyright (c) 2017 TurfJS
|
|
332
|
+
|
|
333
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
334
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
335
|
+
the Software without restriction, including without limitation the rights to
|
|
336
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
337
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
338
|
+
subject to the following conditions:
|
|
339
|
+
|
|
340
|
+
The above copyright notice and this permission notice shall be included in all
|
|
341
|
+
copies or substantial portions of the Software.
|
|
342
|
+
|
|
343
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
344
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
345
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
346
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
347
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
348
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
Name: @turf/bearing
|
|
353
|
+
Version: 7.3.0
|
|
354
|
+
License: MIT
|
|
355
|
+
Private: false
|
|
356
|
+
Description: Takes two points and finds the geographic bearing between them.
|
|
357
|
+
Repository: git://github.com/Turfjs/turf.git
|
|
358
|
+
Homepage: https://github.com/Turfjs/turf
|
|
359
|
+
Author: Turf Authors
|
|
360
|
+
License Copyright:
|
|
361
|
+
===
|
|
362
|
+
|
|
363
|
+
The MIT License (MIT)
|
|
364
|
+
|
|
365
|
+
Copyright (c) 2017 TurfJS
|
|
366
|
+
|
|
367
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
368
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
369
|
+
the Software without restriction, including without limitation the rights to
|
|
370
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
371
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
372
|
+
subject to the following conditions:
|
|
373
|
+
|
|
374
|
+
The above copyright notice and this permission notice shall be included in all
|
|
375
|
+
copies or substantial portions of the Software.
|
|
376
|
+
|
|
377
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
378
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
379
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
380
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
381
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
382
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
Name: maplibre-gl
|
|
387
|
+
Version: 5.12.0
|
|
388
|
+
License: BSD-3-Clause
|
|
389
|
+
Private: false
|
|
390
|
+
Description: BSD licensed community fork of mapbox-gl, a WebGL interactive maps library
|
|
391
|
+
Repository: git://github.com/maplibre/maplibre-gl-js.git
|
|
392
|
+
Homepage: https://maplibre.org/
|
|
393
|
+
License Copyright:
|
|
394
|
+
===
|
|
395
|
+
|
|
396
|
+
Copyright (c) 2023, MapLibre contributors
|
|
397
|
+
|
|
398
|
+
All rights reserved.
|
|
399
|
+
|
|
400
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
401
|
+
are permitted provided that the following conditions are met:
|
|
402
|
+
|
|
403
|
+
* Redistributions of source code must retain the above copyright notice,
|
|
404
|
+
this list of conditions and the following disclaimer.
|
|
405
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
406
|
+
this list of conditions and the following disclaimer in the documentation
|
|
407
|
+
and/or other materials provided with the distribution.
|
|
408
|
+
* Neither the name of MapLibre GL JS nor the names of its contributors
|
|
409
|
+
may be used to endorse or promote products derived from this software
|
|
410
|
+
without specific prior written permission.
|
|
411
|
+
|
|
412
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
413
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
414
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
415
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
416
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
417
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
418
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
419
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
420
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
421
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
422
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
-------------------------------------------------------------------------------
|
|
426
|
+
|
|
427
|
+
Contains code from mapbox-gl-js v1.13 and earlier
|
|
428
|
+
|
|
429
|
+
Version v1.13 of mapbox-gl-js and earlier are licensed under a BSD-3-Clause license
|
|
430
|
+
|
|
431
|
+
Copyright (c) 2020, Mapbox
|
|
432
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
433
|
+
are permitted provided that the following conditions are met:
|
|
434
|
+
|
|
435
|
+
* Redistributions of source code must retain the above copyright notice,
|
|
436
|
+
this list of conditions and the following disclaimer.
|
|
437
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
438
|
+
this list of conditions and the following disclaimer in the documentation
|
|
439
|
+
and/or other materials provided with the distribution.
|
|
440
|
+
* Neither the name of Mapbox GL JS nor the names of its contributors
|
|
441
|
+
may be used to endorse or promote products derived from this software
|
|
442
|
+
without specific prior written permission.
|
|
443
|
+
|
|
444
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
445
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
446
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
447
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
448
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
449
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
450
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
451
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
452
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
453
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
454
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
-------------------------------------------------------------------------------
|
|
458
|
+
|
|
459
|
+
Contains code from glfx.js
|
|
460
|
+
|
|
461
|
+
Copyright (C) 2011 by Evan Wallace
|
|
462
|
+
|
|
463
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
464
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
465
|
+
in the Software without restriction, including without limitation the rights
|
|
466
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
467
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
468
|
+
furnished to do so, subject to the following conditions:
|
|
469
|
+
|
|
470
|
+
The above copyright notice and this permission notice shall be included in
|
|
471
|
+
all copies or substantial portions of the Software.
|
|
472
|
+
|
|
473
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
474
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
475
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
476
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
477
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
478
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
479
|
+
THE SOFTWARE.
|
|
480
|
+
|
|
481
|
+
--------------------------------------------------------------------------------
|
|
482
|
+
|
|
483
|
+
Contains a portion of d3-color https://github.com/d3/d3-color
|
|
484
|
+
|
|
485
|
+
Copyright 2010-2016 Mike Bostock
|
|
486
|
+
All rights reserved.
|
|
487
|
+
|
|
488
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
489
|
+
are permitted provided that the following conditions are met:
|
|
490
|
+
|
|
491
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
492
|
+
list of conditions and the following disclaimer.
|
|
493
|
+
|
|
494
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
495
|
+
this list of conditions and the following disclaimer in the documentation
|
|
496
|
+
and/or other materials provided with the distribution.
|
|
497
|
+
|
|
498
|
+
* Neither the name of the author nor the names of contributors may be used to
|
|
499
|
+
endorse or promote products derived from this software without specific prior
|
|
500
|
+
written permission.
|
|
501
|
+
|
|
502
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
503
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
504
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
505
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
506
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
507
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
508
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
509
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
510
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
511
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Map Theme Plugin
|
|
2
|
+
|
|
3
|
+
Plugin for the [TomTom Maps SDK for JavaScript](https://docs.tomtom.com/maps-sdk-js/introduction/overview) that themes a `TomTomMap` from wherever a look comes from: a brand's colours, a website's, a described mood, an artist's palette, or an image. It assigns them to the SDK's ten map colours; `StylingModule.setMapColors` applies them.
|
|
4
|
+
|
|
5
|
+
| Function | From | To |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| `deriveMapColors` | A handful of CSS colours | The ten map colours |
|
|
8
|
+
| `deriveMapColorsFromCss` | A stylesheet's text — a website's CSS, design tokens, an uploaded `.css` file | The ten map colours, through the colours it paints with most |
|
|
9
|
+
| `cssColors` | A stylesheet's text | Hex colours, most used first |
|
|
10
|
+
| `deriveMapColorsFromImage` | An image — `File`, `Blob`, `<img>`, `ImageBitmap`, CORS-readable URL or raw pixels | The ten map colours, through its dominant colours |
|
|
11
|
+
| `dominantColors` | Raw pixels | Hex colours, largest area first |
|
|
12
|
+
| `mapColorsLightDark` | The ten map colours | `'light'` or `'dark'`: switch to a style of the same (`standardDark` for a dark theme) before applying them |
|
|
13
|
+
|
|
14
|
+
## Docs & examples
|
|
15
|
+
|
|
16
|
+
- Developer guide: https://docs.tomtom.com/maps-sdk-js/guides/plugins/map-theme
|
|
17
|
+
- Example: https://docs.tomtom.com/maps-sdk-js/examples/map-theme
|
|
18
|
+
|
|
19
|
+
## Quickstart
|
|
20
|
+
|
|
21
|
+
The plugin declares `@tomtom-org/maps-sdk` and `culori` as peer dependencies; npm 7+ and Yarn install them for you.
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @tomtom-org/maps-sdk maplibre-gl @tomtom-org/maps-sdk-plugin-map-theme
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { StylingModule } from '@tomtom-org/maps-sdk/map';
|
|
29
|
+
import { deriveMapColors, deriveMapColorsFromCss, deriveMapColorsFromImage } from '@tomtom-org/maps-sdk-plugin-map-theme';
|
|
30
|
+
|
|
31
|
+
const styling = await StylingModule.get(map);
|
|
32
|
+
styling.setMapColors(deriveMapColors(['#1d3f8a', '#e63312', '#f5d000', '#111111', '#f4f1ea']));
|
|
33
|
+
styling.setMapColors(deriveMapColorsFromCss(await cssFileInput.files[0].text()));
|
|
34
|
+
styling.setMapColors(await deriveMapColorsFromImage(fileInput.files[0], { mode: 'dark' }));
|
|
35
|
+
```
|
package/THIRD_PARTY.txt
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
THIRD-PARTY SOFTWARE NOTICES FOR @tomtom-org/maps-sdk-plugin-map-theme
|
|
2
|
+
|
|
3
|
+
This file lists the third-party components used by this package, together with
|
|
4
|
+
their licenses. It is generated from the build output — do not edit it by hand.
|
|
5
|
+
|
|
6
|
+
Components marked "Bundled: false (peer dependency)" are not shipped inside it:
|
|
7
|
+
your package manager installs them alongside it and your application bundles them.
|
|
8
|
+
The licenses below apply to those copies, and each such component may in turn install
|
|
9
|
+
its own dependencies under their own licenses.
|
|
10
|
+
|
|
11
|
+
The software itself is licensed under the terms in LICENSE.txt, which is not affected
|
|
12
|
+
by the licenses reproduced here.
|
|
13
|
+
|
|
14
|
+
--------------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
Name: culori
|
|
17
|
+
Version: 4.0.2
|
|
18
|
+
License: MIT
|
|
19
|
+
Bundled: false (peer dependency)
|
|
20
|
+
Description: A general-purpose color library for JavaScript
|
|
21
|
+
Repository: git@github.com:Evercoder/culori.git
|
|
22
|
+
Author: Dan Burzo <dan@danburzo.ro>
|
|
23
|
+
License Text:
|
|
24
|
+
===
|
|
25
|
+
|
|
26
|
+
MIT License
|
|
27
|
+
|
|
28
|
+
Copyright (c) 2018 Dan Burzo
|
|
29
|
+
|
|
30
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
31
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
32
|
+
in the Software without restriction, including without limitation the rights
|
|
33
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
34
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
35
|
+
furnished to do so, subject to the following conditions:
|
|
36
|
+
|
|
37
|
+
The above copyright notice and this permission notice shall be included in all
|
|
38
|
+
copies or substantial portions of the Software.
|
|
39
|
+
|
|
40
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
41
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
42
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
43
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
44
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
45
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
46
|
+
SOFTWARE.
|
|
47
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
The following third-party components are declared as peer dependencies. Their code is
|
|
2
|
+
NOT bundled into this package: your package manager installs them alongside it and
|
|
3
|
+
your application bundles them. The licenses below apply to those copies, and each of
|
|
4
|
+
these components may in turn install its own dependencies under their own licenses.
|
|
5
|
+
|
|
6
|
+
Name: culori
|
|
7
|
+
Version: 4.0.2
|
|
8
|
+
License: MIT
|
|
9
|
+
Bundled: false (peer dependency)
|
|
10
|
+
Description: A general-purpose color library for JavaScript
|
|
11
|
+
Repository: git@github.com:Evercoder/culori.git
|
|
12
|
+
Author: Dan Burzo <dan@danburzo.ro>
|
|
13
|
+
License Text:
|
|
14
|
+
===
|
|
15
|
+
|
|
16
|
+
MIT License
|
|
17
|
+
|
|
18
|
+
Copyright (c) 2018 Dan Burzo
|
|
19
|
+
|
|
20
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
21
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
22
|
+
in the Software without restriction, including without limitation the rights
|
|
23
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
24
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
25
|
+
furnished to do so, subject to the following conditions:
|
|
26
|
+
|
|
27
|
+
The above copyright notice and this permission notice shall be included in all
|
|
28
|
+
copies or substantial portions of the Software.
|
|
29
|
+
|
|
30
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
31
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
32
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
33
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
34
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
35
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
36
|
+
SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { LightDark, MapColors } from "@tomtom-org/maps-sdk/map";
|
|
2
|
+
//#region src/types.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Every {@link MapThemeMode}, for validating one at runtime.
|
|
5
|
+
*
|
|
6
|
+
* @group Map Theme
|
|
7
|
+
*/
|
|
8
|
+
export declare const mapThemeModes: readonly ["light", "dark", "auto"];
|
|
9
|
+
/**
|
|
10
|
+
* Whether a derived theme reads as a light or a dark map. `auto` (the default) picks dark when the
|
|
11
|
+
* source colours are mostly dark.
|
|
12
|
+
*
|
|
13
|
+
* @group Map Theme
|
|
14
|
+
*/
|
|
15
|
+
type MapThemeMode = (typeof mapThemeModes)[number];
|
|
16
|
+
/**
|
|
17
|
+
* Options for {@link deriveMapColors}.
|
|
18
|
+
*
|
|
19
|
+
* @group Map Theme
|
|
20
|
+
*/
|
|
21
|
+
type MapThemeOptions = {
|
|
22
|
+
/** Default `auto`. */
|
|
23
|
+
mode?: MapThemeMode;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Options for {@link deriveMapColorsFromImage} and {@link deriveMapColorsFromCss}, which extract a few
|
|
27
|
+
* colours from their source before assigning them roles.
|
|
28
|
+
*
|
|
29
|
+
* @group Map Theme
|
|
30
|
+
*/
|
|
31
|
+
type MapThemeExtractionOptions = MapThemeOptions & {
|
|
32
|
+
/** The most colours to extract. Default 6. */
|
|
33
|
+
colorCount?: number;
|
|
34
|
+
};
|
|
35
|
+
/** @ignore */
|
|
36
|
+
declare const DEFAULT_COLOR_COUNT = 6;
|
|
37
|
+
/**
|
|
38
|
+
* Raw pixels in the shape of a DOM `ImageData`: RGBA bytes, row-major. Accepted by
|
|
39
|
+
* {@link deriveMapColorsFromImage} so an image decoded elsewhere (a worker, a test) can be themed
|
|
40
|
+
* without a canvas.
|
|
41
|
+
*
|
|
42
|
+
* @group Map Theme
|
|
43
|
+
*/
|
|
44
|
+
type ImagePixels = {
|
|
45
|
+
data: Uint8ClampedArray | Uint8Array | number[];
|
|
46
|
+
width: number;
|
|
47
|
+
height: number;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* What {@link deriveMapColorsFromImage} accepts: an image URL (must be CORS-readable), a `Blob`/`File`,
|
|
51
|
+
* a loaded `HTMLImageElement`, an `ImageBitmap`, or raw {@link ImagePixels}.
|
|
52
|
+
*
|
|
53
|
+
* @group Map Theme
|
|
54
|
+
*/
|
|
55
|
+
type MapThemeImageSource = string | Blob | HTMLImageElement | ImageBitmap | ImagePixels;
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region src/cssColors.d.ts
|
|
58
|
+
/**
|
|
59
|
+
* The colours a stylesheet paints with, most used first, as hex strings: `var()` references
|
|
60
|
+
* resolved, fills weighted over borders and shadows, translucent colours and a colour's shades left
|
|
61
|
+
* out, and at most two greys while colourful ones remain. Feed the result to {@link deriveMapColors};
|
|
62
|
+
* {@link deriveMapColorsFromCss} does both.
|
|
63
|
+
*
|
|
64
|
+
* Rules for one colour scheme (`prefers-color-scheme`, a `.dark` or `.light` class, a `data-*="dark"`
|
|
65
|
+
* attribute) are read only with that `mode`, and then override the defaults; `auto` reads neither.
|
|
66
|
+
* A `var()` resolves against its own rule or the page root, not a custom property set on another selector.
|
|
67
|
+
*
|
|
68
|
+
* @param cssText - The stylesheet's text, e.g. `await file.text()`; `@import`s are not followed.
|
|
69
|
+
*
|
|
70
|
+
* @group Map Theme
|
|
71
|
+
*/
|
|
72
|
+
export declare const cssColors: (cssText: string, options?: MapThemeExtractionOptions) => string[];
|
|
73
|
+
//#endregion
|
|
74
|
+
//#region src/cssTheme.d.ts
|
|
75
|
+
/**
|
|
76
|
+
* Derives the ten semantic map colours from a stylesheet — a site's CSS, a design system's tokens —
|
|
77
|
+
* by reading the colours it paints with ({@link cssColors}) and assigning them roles with
|
|
78
|
+
* {@link deriveMapColors}.
|
|
79
|
+
*
|
|
80
|
+
* With `mode: 'auto'`, the default, the map is light or dark as the page is: its background on
|
|
81
|
+
* `:root`, `html` or `body`, or else the grey most rules fill with, and light when neither resolves.
|
|
82
|
+
* Needs no DOM.
|
|
83
|
+
*
|
|
84
|
+
* @param cssText - The stylesheet's text, e.g. `await file.text()`; `@import`s are not followed.
|
|
85
|
+
* @throws `RangeError` when the stylesheet paints with no opaque colour.
|
|
86
|
+
*
|
|
87
|
+
* @group Map Theme
|
|
88
|
+
*/
|
|
89
|
+
export declare const deriveMapColorsFromCss: (cssText: string, options?: MapThemeExtractionOptions) => Required<MapColors>;
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/dominantColors.d.ts
|
|
92
|
+
/**
|
|
93
|
+
* The dominant colours of an image, largest area first, as hex strings — a small k-means over a
|
|
94
|
+
* sample of opaque pixels, with near-identical clusters merged. Feed the result to
|
|
95
|
+
* {@link deriveMapColors}; {@link deriveMapColorsFromImage} does both.
|
|
96
|
+
*
|
|
97
|
+
* @param count - The most colours to return (default 6); merged clusters can leave fewer.
|
|
98
|
+
*
|
|
99
|
+
* @group Map Theme
|
|
100
|
+
*/
|
|
101
|
+
export declare const dominantColors: (pixels: ImagePixels, count?: number) => string[];
|
|
102
|
+
//#endregion
|
|
103
|
+
//#region src/imageTheme.d.ts
|
|
104
|
+
/**
|
|
105
|
+
* Derives the ten semantic map colours from an image — a photo, a logo, a poster — by extracting its
|
|
106
|
+
* dominant colours and assigning them roles with {@link deriveMapColors}.
|
|
107
|
+
*
|
|
108
|
+
* @throws `RangeError` when the image has no opaque pixels, or an error when it cannot be read (not
|
|
109
|
+
* CORS-readable, no DOM to decode it).
|
|
110
|
+
*
|
|
111
|
+
* @group Map Theme
|
|
112
|
+
*/
|
|
113
|
+
export declare const deriveMapColorsFromImage: (source: MapThemeImageSource, options?: MapThemeExtractionOptions) => Promise<Required<MapColors>>;
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region src/roleAssignment.d.ts
|
|
116
|
+
/**
|
|
117
|
+
* Assigns a handful of colours — a brand's, a website's, an artist's, a mood's — to the ten semantic
|
|
118
|
+
* map colours, ready for {@link StylingModule.setMapColors}.
|
|
119
|
+
*
|
|
120
|
+
* @remarks
|
|
121
|
+
* Deterministic, and no two roles share a colour:
|
|
122
|
+
* - `land`: the lightest low-saturation colour (the darkest, on a dark theme), toned down if saturated.
|
|
123
|
+
* - `roadMajor`: the most colourful by OKLCH chroma, preferring one that is not a blue or a green.
|
|
124
|
+
* - `water`: a blue or cyan; `vegetation`: a green.
|
|
125
|
+
* - `label`: the one contrasting most with `land`, when it reaches WCAG 4.5:1.
|
|
126
|
+
*
|
|
127
|
+
* Picked colours come back as given; roles no colour fits are `hsl()` shades of `land`, so the
|
|
128
|
+
* result is complete. Apply it over a style of the same light or dark: {@link mapColorsLightDark}.
|
|
129
|
+
*
|
|
130
|
+
* @param colors - One to roughly eight CSS colours; order does not matter, near-duplicates count once.
|
|
131
|
+
* @throws `RangeError` when no colour can be parsed.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```typescript
|
|
135
|
+
* const colors = deriveMapColors(['#0b2a3a', '#0fa8c8', '#f6efe3', '#d9822b'], { mode: 'light' });
|
|
136
|
+
* styling.setMapColors(colors); // `colors` also tells a UI what became what
|
|
137
|
+
* ```
|
|
138
|
+
*
|
|
139
|
+
* @group Map Theme
|
|
140
|
+
*/
|
|
141
|
+
export declare const deriveMapColors: (colors: string[], options?: MapThemeOptions) => Required<MapColors>;
|
|
142
|
+
/**
|
|
143
|
+
* Whether map colours make a light or a dark map (dark when labels are lighter than land), to apply
|
|
144
|
+
* them over a style of the same: {@link StylingModule.setMapColors} keeps the loaded style's shade
|
|
145
|
+
* offsets, which a dark land over `standardLight` clamps to black. Tells what `auto` chose.
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```typescript
|
|
149
|
+
* const colors = await deriveMapColorsFromImage(file);
|
|
150
|
+
* const lightDark = mapColorsLightDark(colors);
|
|
151
|
+
* if (lightDark !== map.styleLightDarkTheme) await map.setStyle(lightDark === 'dark' ? 'standardDark' : 'standardLight');
|
|
152
|
+
* styling.setMapColors(colors);
|
|
153
|
+
* ```
|
|
154
|
+
*
|
|
155
|
+
* @group Map Theme
|
|
156
|
+
*/
|
|
157
|
+
export declare const mapColorsLightDark: ({ land, label }: Pick<Required<MapColors>, "land" | "label">) => LightDark;
|
|
158
|
+
//#endregion
|
|
159
|
+
export type { DEFAULT_COLOR_COUNT, ImagePixels, MapThemeExtractionOptions, MapThemeImageSource, MapThemeMode, MapThemeOptions };
|
package/dist/index.es.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{clampRgb as e,differenceEuclidean as t,differenceHueNaive as o,formatHex as r,modeHsl as s,modeLrgb as a,modeOklab as n,modeOklch as l,modeRgb as i,parse as c,useMode as h,wcagContrast as d,wcagLuminance as p}from"culori/fn";import{formatStyleHsl as u,toHsl as m}from"@tomtom-org/maps-sdk/map";h(i),h(a),h(s),h(n);var f=h(l),g=t("oklab"),w=(e,t)=>g(e,t)<.035,k=([e,t,o])=>({mode:"rgb",r:e/255,g:t/255,b:o/255}),b=["light","dark","auto"],v=(e,t)=>new RegExp(String.raw`prefers-color-scheme\s*:\s*${e}|\.(?:theme-)?${e}(?:-(?:mode|theme))?(?![\w-])|\[data-[\w-]+=["']?${e}["']?\]`,t),M=["light","dark"],x={light:v("light","i"),dark:v("dark","i")},S=v("(?:light|dark)","gi"),y=/^(?:(?::root|html|body)\s*)+$/,C=/^background(-color)?$/,I=/url\((?:"[^"]*"|'[^']*'|[^)]*)\)|"[^"]*"|'[^']*'/gi,E=new RegExp([/#[\da-f]{3,8}\b/,/\b(?:rgba?|hsla?|oklab|oklch)\([^()]*\)/,/\b[a-z]+\b/].map(({source:e})=>e).join("|"),"i"),$=new RegExp(E,"gi"),O=/var\(\s*(--[\w-]+)\s*(?:,([^()]*(?:\([^()]*\)[^()]*)*))?\)/g,R=[[/^(background|fill|accent-color|caret-color)|^color$/,1],[/^(border|outline|stroke|column-rule|text-decoration)/,.3],[/shadow$/,.1]],z=/brand|primary|accent/i,F=e=>e.startsWith("--"),q=e=>""===e||e.split(",").some(e=>y.test(e.trim())),A=(e,t)=>`${q(e)?"":e}\0${t}`,H=e=>M.find(t=>e.some(e=>x[t].test(e))),L=(e,t,o)=>{const r=e[t];if(o.escaped)o.escaped=!1;else if("\\"===r)o.escaped=!0;else if(o.quote)r===o.quote&&(o.quote=void 0);else if('"'===r||"'"===r)o.quote=r;else if("("===r)o.parentheses++;else if(")"===r)o.parentheses=Math.max(0,o.parentheses-1);else if(o.parentheses||"{"!==r){if(!o.parentheses&&(";"===r||"}"===r)){const s=e.slice(o.start,t);return o.start=t+1,{text:s,closesRule:"}"===r}}}else o.preludes.push(e.slice(o.start,t).trim()),o.start=t+1},j=(e,t)=>{const o=e.indexOf(":"),r=t.at(-1);if(o<=0||void 0===r)return;const s=e.slice(0,o).trim();return{property:F(s)?s:s.toLowerCase(),value:e.slice(o+1).trim(),selector:r.replace(S,"").replace(/\s+/g," ").trim(),scheme:H(t)}},B=(e,t,o,r=0)=>r>8?e:e.replace(O,(e,s,a="")=>{const n=o.get(A(t,s))??o.get(A("",s));return B(n??a,t,o,r+1)}),D=(t,o,s)=>{for(const[a]of o.replace(I," ").matchAll($)){const o=c(a);if(!o||(o.alpha??1)<1)continue;const n=e(o),l=r(n),i=t.get(l)??{hex:l,weight:0,color:f(n)};i.weight+=s,t.set(l,i)}},N=(e,t)=>F(e)?E.exec(t)?.[0]!==t.trim()?0:z.test(e)?1:.5:R.find(([t])=>t.test(e))?.[1]??0,P=(e,t)=>{const o=(e=>{const t=e.replace(/\/\*[\s\S]*?\*\//g,""),o={preludes:[],start:0,parentheses:0,escaped:!1},r=[];for(let s=0;s<t.length;s++){const e=L(t,s,o);if(!e)continue;const a=j(e.text,o.preludes);a&&r.push(a),e.closesRule&&o.preludes.pop()}return r})(e),r=({selector:e,property:t})=>A(e,t),s=new Set(o.filter(({scheme:e})=>e===t).map(r));return o.filter(e=>e.scheme?e.scheme===t:!s.has(r(e)))},T=e=>e.c<.03,V=(e,t)=>t.weight-e.weight,W=e=>{const t=[];for(const r of[...e].toSorted(V)){const e=t.find(e=>{return t=e.color,s=r.color,T(t)||T(s)?T(t)&&T(s)&&Math.abs(t.l-s.l)<.06:Math.abs(o({h:t.h??0},{h:s.h??0}))<20&&Math.abs(t.l-s.l)<.2;var t,s});e?e.weight+=r.weight:t.push({...r})}return t.toSorted(V)},Y=(e,t)=>{const o=(e=>{const[t,...o]=e,r=o.find(e=>Math.abs(e.color.l-t.color.l)>=.4);return r?[t,r,...o.filter(e=>e!==r)]:e})(e.filter(e=>T(e.color))),r=e.filter(e=>!T(e.color)),s=Math.min(t,Math.max(Math.min(o.length,2),t-r.length));return[...o.slice(0,s),...r.slice(0,t-s)].toSorted(V).map(e=>e.hex)},_=(e,t)=>{const o=e.filter(({property:e})=>C.test(e)),r=o.findLast(({selector:e})=>q(e)),s=/* @__PURE__ */new Map;r&&D(s,B(r.value,r.selector,t),1);const a=/* @__PURE__ */new Map;for(const{value:l,selector:i}of o)D(a,B(l,i,t),1);const[n]=s.size?s.values():[...a.values()].filter(e=>T(e.color)).toSorted(V);return n&&n.color.l<.5?"dark":"light"},G=(e,{mode:t="auto",colorCount:o=6}={})=>{const r=P(e,t),s=(e=>new Map(e.filter(({property:e})=>F(e)).map(({selector:e,property:t,value:o})=>[A(e,t),o])))(r),a=/* @__PURE__ */new Map;for(const{property:n,value:l,selector:i}of r){const e=B(l,i,s),t=N(n,e);t&&D(a,e,t)}return{colors:Y(W(a.values()),o),mode:"auto"===t?_(r,s):t}},J=(e,t={})=>G(e,t).colors,K=[170,260],Q=[150,280],U=[70,170],X=(e,[t,o])=>void 0!==e.h&&e.h>=t&&e.h<=o,Z=(e,t,o)=>u({h:e,s:t,l:o}),ee=e=>{const t=m(e);return t&&{...t,css:e,chroma:f(t).c}},te=class{pool;dark;land;constructor(e,t){this.pool=[...e];const o=e.reduce((e,t)=>e+t.l,0)/e.length;var r;this.dark="dark"===t||"auto"===t&&o<.45,this.land=(r=this.take(this.pickLand())??e[0]).s<=.14?r:ee(Z(r.h,.14,r.l))??r}pickLand(){const e=this.pool.filter(e=>e.s<=.4);return(e.length?e:this.pool).toSorted((e,t)=>this.dark?e.l-t.l:t.l-e.l)[0]}take(e){if(e)return this.pool.splice(this.pool.indexOf(e),1),e}takeAccent(){const e=this.pool.filter(e=>e.s>=.2).toSorted((e,t)=>t.chroma-e.chroma),t=e.find(e=>!X(e,Q)&&!X(e,U));return this.take(t??e[0])}takeHue(e){const t=this.pool.filter(t=>t.s>=.12&&X(t,e));return this.take(t.toSorted((e,t)=>t.s-e.s)[0])}takeMostContrasting(){const e=e=>d(e,this.land),t=this.pool.toSorted((t,o)=>e(o)-e(t))[0];return t&&e(t)>=4.5?this.take(t):void 0}shade(e,t={}){return Z(t.h??this.land.h,t.s??this.land.s,this.land.l+(this.dark?1:-1)*e)}labelShade(e,t){const o=this.shade(e,{s:t});return d(o,this.land)>=4.5?o:this.shade(-e,{s:t})}},oe=(e,t={})=>{const o=e.map(ee).filter(e=>void 0!==e),r=o.filter((e,t)=>!o.slice(0,t).some(t=>w(t,e)));if(!r.length)throw new RangeError("deriveMapColors needs at least one parseable CSS colour.");const s=new te(r,t.mode??"auto"),{dark:a,land:n}=s,l=s.takeAccent()?.css??s.shade(a?.55:.45,{s:.7}),i=(s.takeHue(K)??s.takeHue(Q))?.css??s.shade(a?.12:.14,{h:205,s:Math.max(.35,n.s)}),c=s.takeHue(U)?.css??s.shade(a?.08:.09,{h:110,s:Math.max(.18,.6*n.s)}),h=s.takeMostContrasting()?.css??s.labelShade(a?.8:.78,Math.min(n.s,.2)),d=ee(c)??n;return{land:n.css,water:i,vegetation:c,park:Z(d.h,d.s,d.l+(a?.04:.05)),artificial:s.shade(a?.04:.03),roadMajor:l,road:s.shade(a?.1:-.08,{s:.5*n.s}),roadOutline:s.shade(a?.24:.22,{s:.6*n.s}),label:h,labelOutline:s.shade(-.03)}},re=({land:e,label:t})=>p(t)>p(e)?"dark":"light",se=(e,t={})=>{const{colors:o,mode:r}=G(e,t);if(!o.length)throw new RangeError("deriveMapColorsFromCss: the stylesheet paints with no opaque colour to take a theme from.");return oe(o,{mode:r})},ae=(e,t)=>(e[0]-t[0])**2+(e[1]-t[1])**2+(e[2]-t[2])**2,ne=(e,t)=>{let o=0,r=Number.POSITIVE_INFINITY;for(let s=0;s<t.length;s++){const a=ae(e,t[s]);a<r&&(r=a,o=s)}return o},le=(e,t=6)=>{const o=(({data:e})=>{const t=Math.floor(e.length/4),o=Math.max(1,Math.floor(t/4096)),r=[];for(let s=0;s<t;s+=o){const t=4*s;e[t+3]<128||r.push([e[t],e[t+1],e[t+2]])}return r})(e);if(!o.length)return[];const{centroids:s,sizes:a}=((e,t)=>{let o=t,r=[];for(let s=0;s<8;s++){const t=o.map(()=>[0,0,0]);r=o.map(()=>0);for(const s of e){const e=ne(s,o);r[e]++,t[e][0]+=s[0],t[e][1]+=s[1],t[e][2]+=s[2]}o=o.map((e,o)=>r[o]?t[o].map(e=>e/r[o]):e)}return{centroids:o,sizes:r}})(o,((e,t)=>{const o=e=>p(k(e)),r=[[...e.toSorted((e,t)=>o(e)-o(t))[Math.floor(e.length/2)]]];for(;r.length<t;){let t=e[0],o=-1;for(const s of e){const e=ae(s,r[ne(s,r)]);e>o&&(o=e,t=s)}if(0===o)break;r.push([...t])}return r})(o,Math.min(t,o.length)));return((e,t)=>{const o=[];for(const[r,s]of e.entries()){if(!t[r])continue;const e=o.find(e=>w(k(e.rgb),k(s)));e?e.size+=t[r]:o.push({rgb:s,size:t[r]})}return o})(s,a).toSorted((e,t)=>t.size-e.size).map(e=>r(k(e.rgb)))},ie=64,ce=async e=>{return"string"==typeof e?(t=e,new Promise((e,o)=>{const r=new Image;r.crossOrigin="anonymous",r.onload=()=>e(r),r.onerror=()=>o(/* @__PURE__ */new Error(`deriveMapColorsFromImage: could not load '${t}'.`)),r.src=t})):e instanceof Blob?createImageBitmap(e):e;var t},he=async(e,t={})=>{const o=(e=>"object"==typeof e&&"data"in e)(e)?e:await(async e=>{if("undefined"==typeof document)throw new TypeError("deriveMapColorsFromImage needs a DOM to decode images; pass ImagePixels instead.");const t=await ce(e),o=document.createElement("canvas");o.width=ie,o.height=ie;const r=o.getContext("2d");if(!r)throw new Error("deriveMapColorsFromImage: no 2D canvas context available.");r.drawImage(t,0,0,ie,ie);try{return r.getImageData(0,0,ie,ie)}catch{throw new Error("deriveMapColorsFromImage: the image is not CORS-readable (canvas tainted). Serve it with Access-Control-Allow-Origin or pass a Blob/File.")}})(e),r=le(o,t.colorCount);if(!r.length)throw new RangeError("deriveMapColorsFromImage: the image has no opaque pixels to take colours from.");return oe(r,t)};export{J as cssColors,oe as deriveMapColors,se as deriveMapColorsFromCss,he as deriveMapColorsFromImage,le as dominantColors,re as mapColorsLightDark,b as mapThemeModes};
|
|
2
|
+
//# sourceMappingURL=index.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.es.js","names":["registerColorSpace","clampRgb","differenceEuclidean","differenceHueNaive","formatHex","modeHsl","modeLrgb","modeOklab","modeOklch","modeRgb","parse","useMode","wcagContrast","wcagLuminance","formatStyleHsl","toHsl","toOklch","oklabDistance","isSameColor","a","b","rgbFromBytes","red","green","blue","mode","r","g","mapThemeModes","schemeMarker","scheme","flags","RegExp","String","raw","COLOR_SCHEMES","SCHEME_MARKERS","light","dark","ANY_SCHEME_MARKER","PAGE_ROOT","PAGE_BACKGROUND","NON_PAINTING_TEXT","COLOR_TOKEN","map","source","join","COLOR_TOKENS","VARIABLE_REFERENCE","USAGE_WEIGHTS","BRAND_NAME","isCustomProperty","property","startsWith","isPageRoot","selector","split","some","part","test","trim","scopeKey","schemeOf","preludes","find","prelude","scanCharacter","css","index","state","character","escaped","quote","parentheses","Math","max","text","slice","start","closesRule","push","declarationOf","colon","indexOf","at","toLowerCase","value","replace","resolveVariables","variables","depth","_reference","name","fallback","definition","get","tally","swatches","weight","token","matchAll","parsed","alpha","rgb","hex","swatch","color","set","weightOf","resolvedValue","exec","pattern","declarationsFor","cssText","declarations","length","scanned","declaration","pop","declarationsOf","key","overridden","Set","filter","has","isNeutral","c","byWeight","mergeShades","tallied","merged","toSorted","main","existing","isShadeOf","abs","l","h","pickSwatches","count","neutrals","first","rest","opposite","neutralsByRole","colorful","neutralCount","min","pageMode","backgrounds","rootBackground","findLast","rootColors","Map","fills","page","size","values","readStylesheet","colorCount","variablesOf","colors","cssColors","options","WATER_HUES","WIDER_WATER_HUES","VEGETATION_HUES","isInHues","from","to","hsl","s","parseColor","chroma","RoleAssigner","pool","land","constructor","this","meanLightness","reduce","sum","take","pickLand","splice","takeAccent","accents","unclaimed","takeHue","hues","inRange","takeMostContrasting","againstLand","best","shade","lightnessOffset","labelShade","towards","deriveMapColors","distinct","seen","RangeError","roles","roadMajor","water","vegetation","label","park","artificial","road","roadOutline","labelOutline","mapColorsLightDark","deriveMapColorsFromCss","squaredDistance","nearestIndex","sample","centroids","nearest","nearestDistance","Number","POSITIVE_INFINITY","distance","dominantColors","pixels","samples","data","pixelCount","floor","stride","offset","sampleOpaquePixels","sizes","seeds","iteration","sums","centroid","cluster","kMeans","luminanceOf","farthest","farthestDistance","seedCentroids","entries","twin","entry","mergeClusters","DECODE_SIDE","toDrawable","async","url","Promise","resolve","reject","image","Image","crossOrigin","onload","onerror","Error","src","Blob","createImageBitmap","deriveMapColorsFromImage","isImagePixels","document","TypeError","drawable","canvas","createElement","width","height","context","getContext","drawImage","getImageData","readPixels"],"sources":["../src/colorSpaces.ts","../src/types.ts","../src/cssColors.ts","../src/roleAssignment.ts","../src/cssTheme.ts","../src/dominantColors.ts","../src/imageTheme.ts"],"sourcesContent":["import type { Color, Rgb } from 'culori/fn';\nimport {\n differenceEuclidean,\n modeHsl,\n modeLrgb,\n modeOklab,\n modeOklch,\n modeRgb,\n useMode as registerColorSpace,\n} from 'culori/fn';\n\n// The colour spaces this plugin's own culori calls need: sRGB for hex, linear sRGB for luminance and\n// contrast, HSL and OKLab for the colours a stylesheet writes in them, OKLCH for chroma. The SDK\n// registers some of them too, but an app can resolve a second culori copy for the plugin.\nregisterColorSpace(modeRgb);\nregisterColorSpace(modeLrgb);\nregisterColorSpace(modeHsl);\nregisterColorSpace(modeOklab);\n\n/**\n * A colour in OKLCH: perceptual lightness, chroma (how colourful it looks) and hue.\n * @ignore\n */\nexport const toOklch = registerColorSpace(modeOklch);\n\n// Below this OKLab distance two colours read as one.\nconst SAME_COLOR_DISTANCE = 0.035;\nconst oklabDistance = differenceEuclidean('oklab');\n\n/**\n * Whether two colours read as one: an image's near-identical clusters, a palette's near-duplicates.\n * @ignore\n */\nexport const isSameColor = (a: Color, b: Color): boolean => oklabDistance(a, b) < SAME_COLOR_DISTANCE;\n\n/**\n * Red, green and blue bytes (0–255), as image pixels carry them, as a culori colour.\n * @ignore\n */\nexport const rgbFromBytes = ([red, green, blue]: readonly number[]): Rgb => ({\n mode: 'rgb',\n r: red / 255,\n g: green / 255,\n b: blue / 255,\n});\n","import type { LightDark } from '@tomtom-org/maps-sdk/map';\n\n/**\n * Every {@link MapThemeMode}, for validating one at runtime.\n *\n * @group Map Theme\n */\nexport const mapThemeModes = ['light', 'dark', 'auto'] as const satisfies readonly (LightDark | 'auto')[];\n\n/**\n * Whether a derived theme reads as a light or a dark map. `auto` (the default) picks dark when the\n * source colours are mostly dark.\n *\n * @group Map Theme\n */\nexport type MapThemeMode = (typeof mapThemeModes)[number];\n\n/**\n * Options for {@link deriveMapColors}.\n *\n * @group Map Theme\n */\nexport type MapThemeOptions = {\n /** Default `auto`. */\n mode?: MapThemeMode;\n};\n\n/**\n * Options for {@link deriveMapColorsFromImage} and {@link deriveMapColorsFromCss}, which extract a few\n * colours from their source before assigning them roles.\n *\n * @group Map Theme\n */\nexport type MapThemeExtractionOptions = MapThemeOptions & {\n /** The most colours to extract. Default 6. */\n colorCount?: number;\n};\n\n/** @ignore */\nexport const DEFAULT_COLOR_COUNT = 6;\n\n/**\n * Raw pixels in the shape of a DOM `ImageData`: RGBA bytes, row-major. Accepted by\n * {@link deriveMapColorsFromImage} so an image decoded elsewhere (a worker, a test) can be themed\n * without a canvas.\n *\n * @group Map Theme\n */\nexport type ImagePixels = { data: Uint8ClampedArray | Uint8Array | number[]; width: number; height: number };\n\n/**\n * What {@link deriveMapColorsFromImage} accepts: an image URL (must be CORS-readable), a `Blob`/`File`,\n * a loaded `HTMLImageElement`, an `ImageBitmap`, or raw {@link ImagePixels}.\n *\n * @group Map Theme\n */\nexport type MapThemeImageSource = string | Blob | HTMLImageElement | ImageBitmap | ImagePixels;\n","import type { LightDark } from '@tomtom-org/maps-sdk/map';\nimport { clampRgb, differenceHueNaive, formatHex, type Oklch, parse } from 'culori/fn';\nimport { toOklch } from './colorSpaces';\nimport { DEFAULT_COLOR_COUNT, type MapThemeExtractionOptions, type MapThemeMode } from './types';\n\n// `scheme` is set on a rule for one colour scheme only. `selector` has the class or attribute that\n// marks the scheme removed, so `.dark` and `html[data-theme=dark]` select the page root as `:root` does.\ntype Declaration = { property: string; value: string; selector: string; scheme?: LightDark };\n\ntype Swatch = { hex: string; weight: number; color: Oklch };\n\n// What marks a rule as one colour scheme's: the media query, or the class or `data-*` attribute a\n// site toggles (`.dark`, `.dark-mode`, `.theme-dark`, `[data-theme=\"dark\"]`) — not a utility class\n// such as `.bg-dark`.\nconst schemeMarker = (scheme: string, flags: string): RegExp =>\n new RegExp(\n String.raw`prefers-color-scheme\\s*:\\s*${scheme}|\\.(?:theme-)?${scheme}(?:-(?:mode|theme))?(?![\\w-])|\\[data-[\\w-]+=[\"']?${scheme}[\"']?\\]`,\n flags,\n );\nconst COLOR_SCHEMES = ['light', 'dark'] as const satisfies readonly LightDark[];\nconst SCHEME_MARKERS: Record<LightDark, RegExp> = {\n light: schemeMarker('light', 'i'),\n dark: schemeMarker('dark', 'i'),\n};\nconst ANY_SCHEME_MARKER = schemeMarker('(?:light|dark)', 'gi');\nconst PAGE_ROOT = /^(?:(?::root|html|body)\\s*)+$/;\nconst PAGE_BACKGROUND = /^background(-color)?$/;\n// Text in a value that paints nothing, though words in it read as colour names: `url(/img/tan.png)`.\nconst NON_PAINTING_TEXT = /url\\((?:\"[^\"]*\"|'[^']*'|[^)]*)\\)|\"[^\"]*\"|'[^']*'/gi;\nconst HEX_COLOR = /#[\\da-f]{3,8}\\b/;\nconst COLOR_FUNCTION = /\\b(?:rgba?|hsla?|oklab|oklch)\\([^()]*\\)/;\nconst COLOR_NAME = /\\b[a-z]+\\b/;\nconst COLOR_TOKEN = new RegExp([HEX_COLOR, COLOR_FUNCTION, COLOR_NAME].map(({ source }) => source).join('|'), 'i');\nconst COLOR_TOKENS = new RegExp(COLOR_TOKEN, 'gi');\nconst VARIABLE_REFERENCE = /var\\(\\s*(--[\\w-]+)\\s*(?:,([^()]*(?:\\([^()]*\\)[^()]*)*))?\\)/g;\nconst MAX_VARIABLE_DEPTH = 8;\n\n// What a colour counts for where it is used: what a page fills with dominates its look, lines and\n// shadows barely register, and a property that paints nothing (a font, a grid area) counts for 0.\nconst USAGE_WEIGHTS: [RegExp, number][] = [\n [/^(background|fill|accent-color|caret-color)|^color$/, 1],\n [/^(border|outline|stroke|column-rule|text-decoration)/, 0.3],\n [/shadow$/, 0.1],\n];\n// A custom property holding one colour counts once where it is defined, so a file of design tokens\n// alone still ranks them; one named as the brand's counts double.\nconst DEFINITION_WEIGHT = 0.5;\nconst BRAND_NAME = /brand|primary|accent/i;\n\n// Below this OKLCH chroma a colour reads as a grey. A stylesheet has many; a theme needs two of them\n// at most (a background and a text colour) while colourful ones remain.\nconst NEUTRAL_CHROMA = 0.03;\nconst MAX_NEUTRALS = 2;\n// OKLCH lightness apart that a background and a text colour are at least.\nconst OPPOSITE_LIGHTNESS = 0.4;\n\nconst isCustomProperty = (property: string): boolean => property.startsWith('--');\n\n// Whether a rule styles the whole page, so that its custom properties reach every other rule.\nconst isPageRoot = (selector: string): boolean =>\n selector === '' || selector.split(',').some((part) => PAGE_ROOT.test(part.trim()));\n\n// Declarations with one key are one setting: the same property, on the same selector or anywhere on\n// the page root.\nconst scopeKey = (selector: string, property: string): string =>\n `${isPageRoot(selector) ? '' : selector}\\u0000${property}`;\n\nconst schemeOf = (preludes: string[]): LightDark | undefined =>\n COLOR_SCHEMES.find((scheme) => preludes.some((prelude) => SCHEME_MARKERS[scheme].test(prelude)));\n\ntype ScanState = { preludes: string[]; start: number; parentheses: number; quote?: string; escaped: boolean };\n\ntype ScannedDeclaration = { text: string; closesRule: boolean };\n\n// Advances the scan over one character; returns a declaration's text when the character ends one.\n// Escaped characters, quoted strings and parentheses are stepped over, so neither the `;` in\n// `url(\"data:…;base64,…\")` nor the quotes in `content: \"\\\\\"` or `.content-\\[\\'x\\'\\]` end anything.\nconst scanCharacter = (css: string, index: number, state: ScanState): ScannedDeclaration | undefined => {\n const character = css[index];\n if (state.escaped) {\n state.escaped = false;\n } else if (character === '\\\\') {\n state.escaped = true;\n } else if (state.quote) {\n if (character === state.quote) state.quote = undefined;\n } else if (character === '\"' || character === \"'\") {\n state.quote = character;\n } else if (character === '(') {\n state.parentheses++;\n } else if (character === ')') {\n state.parentheses = Math.max(0, state.parentheses - 1);\n } else if (!state.parentheses && character === '{') {\n state.preludes.push(css.slice(state.start, index).trim());\n state.start = index + 1;\n } else if (!state.parentheses && (character === ';' || character === '}')) {\n const text = css.slice(state.start, index);\n state.start = index + 1;\n return { text, closesRule: character === '}' };\n }\n return undefined;\n};\n\n// Undefined for text that declares nothing: an empty rule, a stray `;`, text outside any rule.\nconst declarationOf = (text: string, preludes: string[]): Declaration | undefined => {\n const colon = text.indexOf(':');\n const selector = preludes.at(-1);\n if (colon <= 0 || selector === undefined) return undefined;\n\n const property = text.slice(0, colon).trim();\n return {\n property: isCustomProperty(property) ? property : property.toLowerCase(),\n value: text.slice(colon + 1).trim(),\n selector: selector.replace(ANY_SCHEME_MARKER, '').replace(/\\s+/g, ' ').trim(),\n scheme: schemeOf(preludes),\n };\n};\n\n// A stylesheet's declarations, each with the selector of the rule holding it.\nconst declarationsOf = (cssText: string): Declaration[] => {\n const css = cssText.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n const state: ScanState = { preludes: [], start: 0, parentheses: 0, escaped: false };\n const declarations: Declaration[] = [];\n for (let index = 0; index < css.length; index++) {\n const scanned = scanCharacter(css, index, state);\n if (!scanned) continue;\n\n const declaration = declarationOf(scanned.text, state.preludes);\n if (declaration) declarations.push(declaration);\n if (scanned.closesRule) state.preludes.pop();\n }\n return declarations;\n};\n\n// Custom properties by `scopeKey`. A `var()` reads the definition on its own rule, else the page\n// root's: which elements a definition on another selector (`.inverse { --bg: … }`) reaches is more\n// than a flat read of the rules can tell, so it resolves nothing outside its own rule.\ntype Variables = Map<string, string>;\n\nconst variablesOf = (declarations: Declaration[]): Variables =>\n new Map(\n declarations\n .filter(({ property }) => isCustomProperty(property))\n .map(({ selector, property, value }) => [scopeKey(selector, property), value]),\n );\n\nconst resolveVariables = (value: string, selector: string, variables: Variables, depth = 0): string =>\n depth > MAX_VARIABLE_DEPTH\n ? value\n : value.replace(VARIABLE_REFERENCE, (_reference, name: string, fallback = '') => {\n const definition = variables.get(scopeKey(selector, name)) ?? variables.get(scopeKey('', name));\n return resolveVariables(definition ?? fallback, selector, variables, depth + 1);\n });\n\n// Adds `weight` to every opaque colour in a value, keyed by hex, in the order the value writes them.\n// Translucent colours are overlays and shadows, not the palette.\nconst tally = (swatches: Map<string, Swatch>, value: string, weight: number): void => {\n for (const [token] of value.replace(NON_PAINTING_TEXT, ' ').matchAll(COLOR_TOKENS)) {\n const parsed = parse(token);\n if (!parsed || (parsed.alpha ?? 1) < 1) continue;\n\n const rgb = clampRgb(parsed);\n const hex = formatHex(rgb);\n const swatch = swatches.get(hex) ?? { hex, weight: 0, color: toOklch(rgb) };\n swatch.weight += weight;\n swatches.set(hex, swatch);\n }\n};\n\nconst weightOf = (property: string, resolvedValue: string): number => {\n if (!isCustomProperty(property)) return USAGE_WEIGHTS.find(([pattern]) => pattern.test(property))?.[1] ?? 0;\n\n if (COLOR_TOKEN.exec(resolvedValue)?.[0] !== resolvedValue.trim()) return 0;\n\n return BRAND_NAME.test(property) ? 2 * DEFINITION_WEIGHT : DEFINITION_WEIGHT;\n};\n\n// The declarations in effect for a mode: the defaults, and for `light` or `dark` that scheme's rules\n// too, each replacing the defaults with its `scopeKey`. `auto` reads the page as it is by default.\nconst declarationsFor = (cssText: string, mode: MapThemeMode): Declaration[] => {\n const declarations = declarationsOf(cssText);\n const key = ({ selector, property }: Declaration) => scopeKey(selector, property);\n const overridden = new Set(declarations.filter(({ scheme }) => scheme === mode).map(key));\n return declarations.filter((declaration) =>\n declaration.scheme ? declaration.scheme === mode : !overridden.has(key(declaration)),\n );\n};\n\nconst isNeutral = (color: Oklch): boolean => color.c < NEUTRAL_CHROMA;\n\n// Shades of one colour (a button and its hover, two greys a step apart) are one swatch.\nconst isShadeOf = (a: Oklch, b: Oklch): boolean => {\n if (isNeutral(a) || isNeutral(b)) return isNeutral(a) && isNeutral(b) && Math.abs(a.l - b.l) < 0.06;\n\n return Math.abs(differenceHueNaive({ h: a.h ?? 0 }, { h: b.h ?? 0 })) < 20 && Math.abs(a.l - b.l) < 0.2;\n};\n\nconst byWeight = (a: Swatch, b: Swatch): number => b.weight - a.weight;\n\n// Swatches heaviest first, each named by its most-used shade.\nconst mergeShades = (tallied: Iterable<Swatch>): Swatch[] => {\n const merged: Swatch[] = [];\n for (const swatch of [...tallied].toSorted(byWeight)) {\n const main = merged.find((existing) => isShadeOf(existing.color, swatch.color));\n if (main) {\n main.weight += swatch.weight;\n } else {\n merged.push({ ...swatch });\n }\n }\n return merged.toSorted(byWeight);\n};\n\n// The most-used grey, then the most-used one across the lightness scale from it (a background and a\n// text colour), then the rest by use.\nconst neutralsByRole = (neutrals: Swatch[]): Swatch[] => {\n const [first, ...rest] = neutrals;\n const opposite = rest.find((swatch) => Math.abs(swatch.color.l - first.color.l) >= OPPOSITE_LIGHTNESS);\n return opposite ? [first, opposite, ...rest.filter((swatch) => swatch !== opposite)] : neutrals;\n};\n\nconst pickSwatches = (swatches: Swatch[], count: number): string[] => {\n const neutrals = neutralsByRole(swatches.filter((swatch) => isNeutral(swatch.color)));\n const colorful = swatches.filter((swatch) => !isNeutral(swatch.color));\n const neutralCount = Math.min(count, Math.max(Math.min(neutrals.length, MAX_NEUTRALS), count - colorful.length));\n return [...neutrals.slice(0, neutralCount), ...colorful.slice(0, count - neutralCount)]\n .toSorted(byWeight)\n .map((swatch) => swatch.hex);\n};\n\n// Light or dark as the page itself is: the last background set on the root or the body, or else the\n// grey the stylesheet fills the most rules with; light when neither resolves to a colour.\nconst pageMode = (declarations: Declaration[], variables: Variables): LightDark => {\n const backgrounds = declarations.filter(({ property }) => PAGE_BACKGROUND.test(property));\n const rootBackground = backgrounds.findLast(({ selector }) => isPageRoot(selector));\n const rootColors = new Map<string, Swatch>();\n if (rootBackground) {\n tally(rootColors, resolveVariables(rootBackground.value, rootBackground.selector, variables), 1);\n }\n\n const fills = new Map<string, Swatch>();\n for (const { value, selector } of backgrounds) tally(fills, resolveVariables(value, selector, variables), 1);\n\n const [page] = rootColors.size\n ? rootColors.values()\n : [...fills.values()].filter((swatch) => isNeutral(swatch.color)).toSorted(byWeight);\n return page && page.color.l < 0.5 ? 'dark' : 'light';\n};\n\n/**\n * The colours a stylesheet paints with, and the mode given or, for `auto`, the one its page sets.\n * @ignore\n */\nexport const readStylesheet = (\n cssText: string,\n { mode = 'auto', colorCount = DEFAULT_COLOR_COUNT }: MapThemeExtractionOptions = {},\n): { colors: string[]; mode: LightDark } => {\n const declarations = declarationsFor(cssText, mode);\n const variables = variablesOf(declarations);\n const tallied = new Map<string, Swatch>();\n for (const { property, value, selector } of declarations) {\n const resolvedValue = resolveVariables(value, selector, variables);\n const weight = weightOf(property, resolvedValue);\n if (weight) tally(tallied, resolvedValue, weight);\n }\n return {\n colors: pickSwatches(mergeShades(tallied.values()), colorCount),\n mode: mode === 'auto' ? pageMode(declarations, variables) : mode,\n };\n};\n\n/**\n * The colours a stylesheet paints with, most used first, as hex strings: `var()` references\n * resolved, fills weighted over borders and shadows, translucent colours and a colour's shades left\n * out, and at most two greys while colourful ones remain. Feed the result to {@link deriveMapColors};\n * {@link deriveMapColorsFromCss} does both.\n *\n * Rules for one colour scheme (`prefers-color-scheme`, a `.dark` or `.light` class, a `data-*=\"dark\"`\n * attribute) are read only with that `mode`, and then override the defaults; `auto` reads neither.\n * A `var()` resolves against its own rule or the page root, not a custom property set on another selector.\n *\n * @param cssText - The stylesheet's text, e.g. `await file.text()`; `@import`s are not followed.\n *\n * @group Map Theme\n */\nexport const cssColors = (cssText: string, options: MapThemeExtractionOptions = {}): string[] =>\n readStylesheet(cssText, options).colors;\n","import { formatStyleHsl, type HslColor, type LightDark, type MapColors, toHsl } from '@tomtom-org/maps-sdk/map';\nimport { wcagContrast, wcagLuminance } from 'culori/fn';\nimport { isSameColor, toOklch } from './colorSpaces';\nimport type { MapThemeMode, MapThemeOptions } from './types';\n\n// A source colour in HSL (saturation and lightness 0–1), with the CSS it was given as and its OKLCH\n// chroma.\ntype ParsedColor = HslColor & { css: string; chroma: number };\n\nconst NEUTRAL_SATURATION = 0.4;\n// Land-use tints in the built-up colour's hue family are re-derived as its shades, saturation\n// included, and `artificial` is a shade of land; a saturated land makes them garish, so it is toned\n// down to a true neutral.\nconst MAX_LAND_SATURATION = 0.14;\nconst MIN_LABEL_CONTRAST = 4.5;\nconst MIN_ACCENT_SATURATION = 0.2;\n\n// Hue ranges, in degrees, water and vegetation take their colour from: water tries the first and\n// widens to the second.\ntype HueRange = readonly [from: number, to: number];\nconst WATER_HUES: HueRange = [170, 260];\nconst WIDER_WATER_HUES: HueRange = [150, 280];\nconst VEGETATION_HUES: HueRange = [70, 170];\n\nconst isInHues = (color: ParsedColor, [from, to]: HueRange): boolean =>\n color.h !== undefined && color.h >= from && color.h <= to;\n\nconst hsl = (h: number | undefined, s: number, l: number): string => formatStyleHsl({ h, s, l });\n\nconst parseColor = (css: string): ParsedColor | undefined => {\n const parsed = toHsl(css);\n return parsed && { ...parsed, css, chroma: toOklch(parsed).c };\n};\n\nconst asNeutral = (color: ParsedColor): ParsedColor => {\n if (color.s <= MAX_LAND_SATURATION) return color;\n\n return parseColor(hsl(color.h, MAX_LAND_SATURATION, color.l)) ?? color;\n};\n\n// Assigns the ten semantic roles from an unordered list of colours. Each pick removes the colour\n// from the pool so no two roles share one; a role with no fitting colour is derived from `land`\n// so the result is always a coherent, complete palette.\nclass RoleAssigner {\n private readonly pool: ParsedColor[];\n readonly dark: boolean;\n readonly land: ParsedColor;\n\n constructor(colors: ParsedColor[], mode: MapThemeMode) {\n this.pool = [...colors];\n const meanLightness = colors.reduce((sum, color) => sum + color.l, 0) / colors.length;\n this.dark = mode === 'dark' || (mode === 'auto' && meanLightness < 0.45);\n this.land = asNeutral(this.take(this.pickLand()) ?? colors[0]);\n }\n\n private pickLand(): ParsedColor | undefined {\n const neutrals = this.pool.filter((color) => color.s <= NEUTRAL_SATURATION);\n const candidates = neutrals.length ? neutrals : this.pool;\n // Darkest first on a dark theme, lightest first otherwise; the sort is stable, so equally\n // light candidates keep the caller's order.\n return candidates.toSorted((a, b) => (this.dark ? a.l - b.l : b.l - a.l))[0];\n }\n\n private take(color: ParsedColor | undefined): ParsedColor | undefined {\n if (!color) return undefined;\n\n this.pool.splice(this.pool.indexOf(color), 1);\n return color;\n }\n\n // The most colourful colour left that is saturated enough to read as an accent, ranked by chroma\n // rather than HSL saturation, in which a dark navy is as saturated as a vivid red. A colour\n // outside the water and vegetation hues goes first, so roads do not spend the only blue or green.\n takeAccent(): ParsedColor | undefined {\n const accents = this.pool\n .filter((color) => color.s >= MIN_ACCENT_SATURATION)\n .toSorted((a, b) => b.chroma - a.chroma);\n const unclaimed = accents.find(\n (color) => !isInHues(color, WIDER_WATER_HUES) && !isInHues(color, VEGETATION_HUES),\n );\n return this.take(unclaimed ?? accents[0]);\n }\n\n takeHue(hues: HueRange): ParsedColor | undefined {\n const inRange = this.pool.filter((color) => color.s >= 0.12 && isInHues(color, hues));\n return this.take(inRange.toSorted((a, b) => b.s - a.s)[0]);\n }\n\n // The colour that contrasts most with land; undefined when none reaches the readable minimum.\n takeMostContrasting(): ParsedColor | undefined {\n const againstLand = (color: ParsedColor) => wcagContrast(color, this.land);\n const best = this.pool.toSorted((a, b) => againstLand(b) - againstLand(a))[0];\n return best && againstLand(best) >= MIN_LABEL_CONTRAST ? this.take(best) : undefined;\n }\n\n // A shade of land, `lightnessOffset` towards the label side (lighter on a dark theme, darker on a\n // light one; negative goes the other way), optionally re-hued or re-saturated.\n shade(lightnessOffset: number, options: { h?: number; s?: number } = {}): string {\n return hsl(\n options.h ?? this.land.h,\n options.s ?? this.land.s,\n this.land.l + (this.dark ? 1 : -1) * lightnessOffset,\n );\n }\n\n // A label shade towards the label side, or away from it when land sits so near that end that the\n // shade clamps to a colour too close to land to read.\n labelShade(lightnessOffset: number, s: number): string {\n const towards = this.shade(lightnessOffset, { s });\n return wcagContrast(towards, this.land) >= MIN_LABEL_CONTRAST ? towards : this.shade(-lightnessOffset, { s });\n }\n}\n\n/**\n * Assigns a handful of colours — a brand's, a website's, an artist's, a mood's — to the ten semantic\n * map colours, ready for {@link StylingModule.setMapColors}.\n *\n * @remarks\n * Deterministic, and no two roles share a colour:\n * - `land`: the lightest low-saturation colour (the darkest, on a dark theme), toned down if saturated.\n * - `roadMajor`: the most colourful by OKLCH chroma, preferring one that is not a blue or a green.\n * - `water`: a blue or cyan; `vegetation`: a green.\n * - `label`: the one contrasting most with `land`, when it reaches WCAG 4.5:1.\n *\n * Picked colours come back as given; roles no colour fits are `hsl()` shades of `land`, so the\n * result is complete. Apply it over a style of the same light or dark: {@link mapColorsLightDark}.\n *\n * @param colors - One to roughly eight CSS colours; order does not matter, near-duplicates count once.\n * @throws `RangeError` when no colour can be parsed.\n *\n * @example\n * ```typescript\n * const colors = deriveMapColors(['#0b2a3a', '#0fa8c8', '#f6efe3', '#d9822b'], { mode: 'light' });\n * styling.setMapColors(colors); // `colors` also tells a UI what became what\n * ```\n *\n * @group Map Theme\n */\nexport const deriveMapColors = (colors: string[], options: MapThemeOptions = {}): Required<MapColors> => {\n const parsed = colors.map(parseColor).filter((color): color is ParsedColor => color !== undefined);\n const distinct = parsed.filter((color, index) => !parsed.slice(0, index).some((seen) => isSameColor(seen, color)));\n if (!distinct.length) {\n throw new RangeError('deriveMapColors needs at least one parseable CSS colour.');\n }\n\n const roles = new RoleAssigner(distinct, options.mode ?? 'auto');\n const { dark, land } = roles;\n\n const roadMajor = roles.takeAccent()?.css ?? roles.shade(dark ? 0.55 : 0.45, { s: 0.7 });\n const water =\n (roles.takeHue(WATER_HUES) ?? roles.takeHue(WIDER_WATER_HUES))?.css ??\n roles.shade(dark ? 0.12 : 0.14, { h: 205, s: Math.max(0.35, land.s) });\n const vegetation =\n roles.takeHue(VEGETATION_HUES)?.css ??\n roles.shade(dark ? 0.08 : 0.09, { h: 110, s: Math.max(0.18, land.s * 0.6) });\n const label = roles.takeMostContrasting()?.css ?? roles.labelShade(dark ? 0.8 : 0.78, Math.min(land.s, 0.2));\n const park = parseColor(vegetation) ?? land;\n\n return {\n land: land.css,\n water,\n vegetation,\n park: hsl(park.h, park.s, park.l + (dark ? 0.04 : 0.05)),\n artificial: roles.shade(dark ? 0.04 : 0.03),\n roadMajor,\n road: roles.shade(dark ? 0.1 : -0.08, { s: land.s * 0.5 }),\n roadOutline: roles.shade(dark ? 0.24 : 0.22, { s: land.s * 0.6 }),\n label,\n labelOutline: roles.shade(-0.03),\n };\n};\n\n/**\n * Whether map colours make a light or a dark map (dark when labels are lighter than land), to apply\n * them over a style of the same: {@link StylingModule.setMapColors} keeps the loaded style's shade\n * offsets, which a dark land over `standardLight` clamps to black. Tells what `auto` chose.\n *\n * @example\n * ```typescript\n * const colors = await deriveMapColorsFromImage(file);\n * const lightDark = mapColorsLightDark(colors);\n * if (lightDark !== map.styleLightDarkTheme) await map.setStyle(lightDark === 'dark' ? 'standardDark' : 'standardLight');\n * styling.setMapColors(colors);\n * ```\n *\n * @group Map Theme\n */\nexport const mapColorsLightDark = ({ land, label }: Pick<Required<MapColors>, 'land' | 'label'>): LightDark =>\n wcagLuminance(label) > wcagLuminance(land) ? 'dark' : 'light';\n","import type { MapColors } from '@tomtom-org/maps-sdk/map';\nimport { readStylesheet } from './cssColors';\nimport { deriveMapColors } from './roleAssignment';\nimport type { MapThemeExtractionOptions } from './types';\n\n/**\n * Derives the ten semantic map colours from a stylesheet — a site's CSS, a design system's tokens —\n * by reading the colours it paints with ({@link cssColors}) and assigning them roles with\n * {@link deriveMapColors}.\n *\n * With `mode: 'auto'`, the default, the map is light or dark as the page is: its background on\n * `:root`, `html` or `body`, or else the grey most rules fill with, and light when neither resolves.\n * Needs no DOM.\n *\n * @param cssText - The stylesheet's text, e.g. `await file.text()`; `@import`s are not followed.\n * @throws `RangeError` when the stylesheet paints with no opaque colour.\n *\n * @group Map Theme\n */\nexport const deriveMapColorsFromCss = (\n cssText: string,\n options: MapThemeExtractionOptions = {},\n): Required<MapColors> => {\n const { colors, mode } = readStylesheet(cssText, options);\n if (!colors.length) {\n throw new RangeError(\n 'deriveMapColorsFromCss: the stylesheet paints with no opaque colour to take a theme from.',\n );\n }\n\n return deriveMapColors(colors, { mode });\n};\n","import { formatHex, wcagLuminance } from 'culori/fn';\nimport { isSameColor, rgbFromBytes } from './colorSpaces';\nimport { DEFAULT_COLOR_COUNT, type ImagePixels } from './types';\n\nconst SAMPLE_BUDGET = 4096;\nconst KMEANS_ITERATIONS = 8;\n\n// In RGB bytes: cheap enough for the k-means loop, which only needs a nearest centroid.\nconst squaredDistance = (a: number[], b: number[]): number =>\n (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2 + (a[2] - b[2]) ** 2;\n\n// Up to SAMPLE_BUDGET opaque pixels, evenly strided through the image.\nconst sampleOpaquePixels = ({ data }: ImagePixels): number[][] => {\n const pixelCount = Math.floor(data.length / 4);\n const stride = Math.max(1, Math.floor(pixelCount / SAMPLE_BUDGET));\n const samples: number[][] = [];\n for (let index = 0; index < pixelCount; index += stride) {\n const offset = index * 4;\n if (data[offset + 3] < 128) continue;\n\n samples.push([data[offset], data[offset + 1], data[offset + 2]]);\n }\n return samples;\n};\n\nconst nearestIndex = (sample: number[], centroids: number[][]): number => {\n let nearest = 0;\n let nearestDistance = Number.POSITIVE_INFINITY;\n for (let c = 0; c < centroids.length; c++) {\n const distance = squaredDistance(sample, centroids[c]);\n if (distance < nearestDistance) {\n nearestDistance = distance;\n nearest = c;\n }\n }\n return nearest;\n};\n\n// Farthest-point seeding: start from the median-luminance pixel, then keep adding the pixel farthest\n// from every seed so far, so distinct colours each get a cluster even when they are all dark.\nconst seedCentroids = (samples: number[][], count: number): number[][] => {\n const luminanceOf = (rgb: number[]) => wcagLuminance(rgbFromBytes(rgb));\n const byLuminance = samples.toSorted((a, b) => luminanceOf(a) - luminanceOf(b));\n const centroids = [[...byLuminance[Math.floor(samples.length / 2)]]];\n while (centroids.length < count) {\n let farthest = samples[0];\n let farthestDistance = -1;\n for (const sample of samples) {\n const distance = squaredDistance(sample, centroids[nearestIndex(sample, centroids)]);\n if (distance > farthestDistance) {\n farthestDistance = distance;\n farthest = sample;\n }\n }\n if (farthestDistance === 0) break;\n\n centroids.push([...farthest]);\n }\n return centroids;\n};\n\nconst kMeans = (samples: number[][], seeds: number[][]): { centroids: number[][]; sizes: number[] } => {\n let centroids = seeds;\n let sizes: number[] = [];\n for (let iteration = 0; iteration < KMEANS_ITERATIONS; iteration++) {\n const sums = centroids.map(() => [0, 0, 0]);\n sizes = centroids.map(() => 0);\n for (const sample of samples) {\n const nearest = nearestIndex(sample, centroids);\n sizes[nearest]++;\n sums[nearest][0] += sample[0];\n sums[nearest][1] += sample[1];\n sums[nearest][2] += sample[2];\n }\n centroids = centroids.map((centroid, cluster) =>\n sizes[cluster] ? sums[cluster].map((sum) => sum / sizes[cluster]) : centroid,\n );\n }\n return { centroids, sizes };\n};\n\ntype Cluster = { rgb: number[]; size: number };\n\nconst mergeClusters = (centroids: number[][], sizes: number[]): Cluster[] => {\n const merged: Cluster[] = [];\n for (const [cluster, rgb] of centroids.entries()) {\n if (!sizes[cluster]) continue;\n\n const twin = merged.find((entry) => isSameColor(rgbFromBytes(entry.rgb), rgbFromBytes(rgb)));\n if (twin) {\n twin.size += sizes[cluster];\n } else {\n merged.push({ rgb, size: sizes[cluster] });\n }\n }\n return merged;\n};\n\n/**\n * The dominant colours of an image, largest area first, as hex strings — a small k-means over a\n * sample of opaque pixels, with near-identical clusters merged. Feed the result to\n * {@link deriveMapColors}; {@link deriveMapColorsFromImage} does both.\n *\n * @param count - The most colours to return (default 6); merged clusters can leave fewer.\n *\n * @group Map Theme\n */\nexport const dominantColors = (pixels: ImagePixels, count = DEFAULT_COLOR_COUNT): string[] => {\n const samples = sampleOpaquePixels(pixels);\n if (!samples.length) return [];\n\n const { centroids, sizes } = kMeans(samples, seedCentroids(samples, Math.min(count, samples.length)));\n return mergeClusters(centroids, sizes)\n .toSorted((a, b) => b.size - a.size)\n .map((entry) => formatHex(rgbFromBytes(entry.rgb)));\n};\n","import type { MapColors } from '@tomtom-org/maps-sdk/map';\nimport { dominantColors } from './dominantColors';\nimport { deriveMapColors } from './roleAssignment';\nimport type { ImagePixels, MapThemeExtractionOptions, MapThemeImageSource } from './types';\n\n// The dominant colours do not need every pixel, so the image is drawn into a square this small.\nconst DECODE_SIDE = 64;\n\nconst isImagePixels = (source: MapThemeImageSource): source is ImagePixels =>\n typeof source === 'object' && 'data' in source;\n\nconst loadImageElement = (url: string): Promise<HTMLImageElement> =>\n new Promise((resolve, reject) => {\n const image = new Image();\n image.crossOrigin = 'anonymous';\n image.onload = () => resolve(image);\n image.onerror = () => reject(new Error(`deriveMapColorsFromImage: could not load '${url}'.`));\n image.src = url;\n });\n\nconst toDrawable = async (source: Exclude<MapThemeImageSource, ImagePixels>): Promise<CanvasImageSource> => {\n if (typeof source === 'string') return loadImageElement(source);\n\n if (source instanceof Blob) return createImageBitmap(source);\n\n return source;\n};\n\nconst readPixels = async (source: Exclude<MapThemeImageSource, ImagePixels>): Promise<ImagePixels> => {\n if (typeof document === 'undefined') {\n throw new TypeError('deriveMapColorsFromImage needs a DOM to decode images; pass ImagePixels instead.');\n }\n\n const drawable = await toDrawable(source);\n const canvas = document.createElement('canvas');\n canvas.width = DECODE_SIDE;\n canvas.height = DECODE_SIDE;\n const context = canvas.getContext('2d');\n if (!context) {\n throw new Error('deriveMapColorsFromImage: no 2D canvas context available.');\n }\n\n context.drawImage(drawable, 0, 0, DECODE_SIDE, DECODE_SIDE);\n try {\n return context.getImageData(0, 0, DECODE_SIDE, DECODE_SIDE);\n } catch {\n throw new Error(\n 'deriveMapColorsFromImage: the image is not CORS-readable (canvas tainted). Serve it with ' +\n 'Access-Control-Allow-Origin or pass a Blob/File.',\n );\n }\n};\n\n/**\n * Derives the ten semantic map colours from an image — a photo, a logo, a poster — by extracting its\n * dominant colours and assigning them roles with {@link deriveMapColors}.\n *\n * @throws `RangeError` when the image has no opaque pixels, or an error when it cannot be read (not\n * CORS-readable, no DOM to decode it).\n *\n * @group Map Theme\n */\nexport const deriveMapColorsFromImage = async (\n source: MapThemeImageSource,\n options: MapThemeExtractionOptions = {},\n): Promise<Required<MapColors>> => {\n const pixels = isImagePixels(source) ? source : await readPixels(source);\n const colors = dominantColors(pixels, options.colorCount);\n if (!colors.length) {\n throw new RangeError('deriveMapColorsFromImage: the image has no opaque pixels to take colours from.');\n }\n\n return deriveMapColors(colors, options);\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"name": "culori",
|
|
4
|
+
"version": "4.0.2",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"bundled": false,
|
|
7
|
+
"description": "A general-purpose color library for JavaScript",
|
|
8
|
+
"repository": "git@github.com:Evercoder/culori.git",
|
|
9
|
+
"author": "Dan Burzo <dan@danburzo.ro>",
|
|
10
|
+
"licenseText": "MIT License\n\nCopyright (c) 2018 Dan Burzo\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
|
|
11
|
+
}
|
|
12
|
+
]
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tomtom-org/maps-sdk-plugin-map-theme",
|
|
3
|
+
"author": "TomTom International B.V.",
|
|
4
|
+
"license": "See in LICENSE.txt",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"description": "Theme a TomTomMap from wherever a look comes from — a brand's colours, a website's, a described mood, an artist's palette, or an image — by assigning them to the SDK's ten map colours",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"peerDependencies": {
|
|
10
|
+
"@tomtom-org/maps-sdk": ">=0.58.0 <1.0.0",
|
|
11
|
+
"culori": "^4.0.2"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@tsconfig/recommended": "^1.0.13",
|
|
15
|
+
"@types/culori": "^4.0.1",
|
|
16
|
+
"@types/node": "^26.6.2",
|
|
17
|
+
"@vitest/coverage-v8": "^4.1.11",
|
|
18
|
+
"rolldown": "^1.2.11",
|
|
19
|
+
"ts-node": "^10.9.2",
|
|
20
|
+
"typescript": "^6.0.3",
|
|
21
|
+
"vite": "^8.3.1",
|
|
22
|
+
"vitest": "^4.1.11",
|
|
23
|
+
"@tomtom-org/maps-sdk": "0.58.0"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"package.json",
|
|
28
|
+
"README.md",
|
|
29
|
+
"LICENSE.txt",
|
|
30
|
+
"THIRD_PARTY.txt"
|
|
31
|
+
],
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"default": "./dist/index.es.js"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "vite build --config ../plugin-vite-config.ts",
|
|
40
|
+
"build:watch": "vite build --watch --config ../plugin-vite-config.ts",
|
|
41
|
+
"test": "vitest run",
|
|
42
|
+
"test:coverage": "vitest run --coverage",
|
|
43
|
+
"type-check": "tsc --noEmit"
|
|
44
|
+
}
|
|
45
|
+
}
|