Initial commit

This commit is contained in:
2026-04-15 17:08:39 +02:00
parent ae164c47a8
commit 47fd1c2b7a
1819 changed files with 685388 additions and 0 deletions

12
node_modules/maplibre-gl/build/banner.ts generated vendored Normal file
View File

@@ -0,0 +1,12 @@
import {readFileSync} from 'fs';
import {fileURLToPath} from 'url';
import {dirname, join} from 'path';
const packageJSONPath = join(dirname(fileURLToPath(import.meta.url)), '../package.json');
const packageJSON = JSON.parse(readFileSync(packageJSONPath, 'utf8'));
export default
`/**
* MapLibre GL JS
* @license 3-Clause BSD. Full text of license: https://github.com/maplibre/maplibre-gl-js/blob/v${packageJSON.version}/LICENSE.txt
*/`;

77
node_modules/maplibre-gl/build/check-bundle-size.js generated vendored Normal file
View File

@@ -0,0 +1,77 @@
#!/usr/bin/env node
import fs from "fs";
import zlib from "zlib";
import prettyBytes from "pretty-bytes";
const beforeSourcemap = JSON.parse(fs.readFileSync('./before.json').toString());
const afterSourcemap = JSON.parse(fs.readFileSync('./after.json').toString());
function fileSize(file) {
const {size} = fs.statSync(file);
const gzipped = zlib.gzipSync(fs.readFileSync(file)).length
return {
size,
gzipped
};
}
const beforejs = fileSize('./before/maplibre-gl.js');
const beforecss = fileSize('./before/maplibre-gl.css');
const afterjs = fileSize('./after/maplibre-gl.js');
const aftercss = fileSize('./after/maplibre-gl.css');
console.log('Bundle size report:\n');
console.log(`**Size Change:** ${prettyBytes(afterjs.gzipped + aftercss.gzipped - (beforejs.gzipped + beforecss.gzipped), { signed: true })}`);
console.log(`**Total Size Before:** ${prettyBytes(beforejs.gzipped + beforecss.gzipped)}`);
console.log(`**Total Size After:** ${prettyBytes(afterjs.gzipped + aftercss.gzipped)}`);
console.log(`
| Output file | Before | After | Change |
| :--- | :---: | :---: | :---: |
| maplibre-gl.js | ${prettyBytes(beforejs.gzipped)} | ${prettyBytes(afterjs.gzipped)} | ${prettyBytes(afterjs.gzipped - beforejs.gzipped, { signed: true })} |
| maplibre-gl.css | ${prettyBytes(beforecss.gzipped)} | ${prettyBytes(aftercss.gzipped)} | ${prettyBytes(aftercss.gzipped - beforecss.gzipped, { signed: true })} |`);
const before = {};
beforeSourcemap.results.forEach(result => {
Object.keys(result.files).forEach(filename => {
const {size} = result.files[filename];
before[filename] = size;
});
});
const after = {};
afterSourcemap.results.forEach(result => {
Object.keys(result.files).forEach(filename => {
const {size} = result.files[filename];
after[filename] = size;
});
});
const diffs = [];
Object.keys(Object.assign({}, before, after)).forEach(filename => {
const beforeSize = before[filename] || 0;
const afterSize = after[filename] || 0;
if (Math.abs(afterSize - beforeSize) > 0) {
diffs.push([
afterSize - beforeSize, // for sorting
filename.replace(/^[\./]+/, ''), // omit ../
prettyBytes(beforeSize),
prettyBytes(afterSize),
prettyBytes(afterSize - beforeSize, { signed: true })
]);
}
});
diffs.sort((a, b) => b[0] - a[0]);
console.log(`
<details><summary> <strong>View Details</strong></summary>`);
if (diffs.length) {
console.log(`
| Source file | Before | After | Change |
| :--- | :---: | :---: | :---: |
${diffs.map(diff => '| ' + diff.slice(1).join(' | ') + ' |').join('\n')}
`);
} else {
console.log('No major changes');
}
console.log(`</details>`);

View File

@@ -0,0 +1,26 @@
'use strict';
/// js files in this project are esm.
/// This package.json ensures that node imports from outside see them as such
// https://nodejs.org/api/packages.html#type
import { writeFile, mkdir, copyFile } from "node:fs/promises"
async function ensureDist() {
const dist = new URL("../dist/", import.meta.url);
await mkdir(dist, { recursive: true })
return dist
}
await writeFile(
new URL("package.json", await ensureDist()),
JSON.stringify({
name: "maplibre-gl",
type: "commonjs",
deprecated: "Please install maplibre-gl from parent directory instead",
})
)
await copyFile(
"./LICENSE.txt",
new URL("LICENSE.txt", await ensureDist())
)

80
node_modules/maplibre-gl/build/generate-doc-images.ts generated vendored Normal file
View File

@@ -0,0 +1,80 @@
import path from 'path';
import fs from 'fs';
import puppeteer from 'puppeteer';
import packageJson from '../package.json' with { type: 'json' };
const exampleName = process.argv[2];
const useLocalhost = (process.argv.length > 3) && (process.argv[3] === 'serve');
const examplePath = path.resolve('test', 'examples');
const browser = await puppeteer.launch({headless: exampleName === 'all'});
const page = await browser.newPage();
// set viewport and double deviceScaleFactor to get a closer shot of the map
await page.setViewport({
width: 600,
height: 250,
deviceScaleFactor: 2
});
async function createImage(exampleName) {
// get the example contents
if (useLocalhost) {
console.log('Using localhost to serve examples.');
await page.goto(`http://localhost:9966/test/examples/${exampleName}.html`);
} else {
const html = fs.readFileSync(path.resolve(examplePath, `${exampleName}.html`), 'utf-8');
await page.setContent(html.replaceAll('../../dist', `https://unpkg.com/maplibre-gl@${packageJson.version}/dist`));
}
// Wait for map to load, then wait two more seconds for images, etc. to load.
try {
// @ts-ignore
await page.evaluate(() => document.querySelector('.maplibregl-ctrl-attrib').style.display = 'none');
await page.waitForFunction('map.loaded()', {timeout: 10000});
// Wait for 5 seconds on 3d model examples, since this takes longer to load.
const waitTime = (exampleName.includes('3d-model') || exampleName.includes('globe')) ? 5000 : 1500;
console.log(`waiting for ${waitTime} ms`);
await new Promise(resolve => setTimeout(resolve, waitTime));
} catch {
// map.loaded() does not evaluate to true within 3 seconds, it's probably an animated example.
// In this case we take the screenshot immediately.
console.log(`Timed out waiting for map load on ${exampleName}.`);
}
await page
.screenshot({
path: `./docs/assets/examples/${exampleName}.png`,
type: 'png',
clip: {
x: 0,
y: 0,
width: 600,
height: 250
}
})
.then(() => console.log(`Created ./docs/assets/examples/${exampleName}.png`))
.catch((err) => {
console.log(err);
});
}
if (exampleName === 'all') {
const allFiles = fs.readdirSync(examplePath).filter(f => f.endsWith('html'));
console.log(`Generating ${allFiles.length} images.`);
for (const file of allFiles) {
await createImage(file.replace('.html', ''));
}
} else if (exampleName) {
await createImage(exampleName);
} else {
throw new Error(`
Usage: npm run generate-images <file-name|all> [serve]
file-name: the name of the example file in test/examples without the .html extension.
all: generate images for all examples.
serve: use localhost to serve examples - use 'npm run start' with this option, otherwise it will use the latest published version in npm.
Example: npm run generate-images 3d-buildings serve`
);
}
await browser.close();

196
node_modules/maplibre-gl/build/generate-docs.ts generated vendored Normal file
View File

@@ -0,0 +1,196 @@
import fs from 'fs';
import path from 'path';
import typedocConfig from '../typedoc.json' with {type: 'json'};
import packageJson from '../package.json' with {type: 'json'};
import {get} from 'https';
import sharp from 'sharp';
type HtmlDoc = {
title: string;
description: string;
mdFileName: string;
};
function generateAPIIntroMarkdown(lines: string[]): string {
let intro = `# Intro
This file is intended as a reference for the important and public classes of this API.
We recommend looking at the [examples](../examples/index.md) as they will help you the most to start with MapLibre.
Most of the classes written here have an "Options" object for initialization, it is recommended to check which options exist.
It is recommended to import what you need and then use it. Some examples for classes assume you did that.
For example, import the \`Map\` class like this:
\`\`\`ts
import {Map} from 'maplibre-gl';
const map = new Map(...)
\`\`\`
Import declarations are omitted from the examples for brevity.
`;
intro += lines.map(l => l.replace('../', './')).join('\n');
return intro;
}
function generateMarkdownForExample(title: string, description: string, file: string, htmlContent: string): string {
return `
# ${title}
${description}
<iframe src="../${file}" width="100%" style="border:none; height:400px"></iframe>
\`\`\`html
${htmlContent}
\`\`\`
`;
}
async function generateMarkdownIndexFileOfAllExamplesAndPackImages(indexArray: HtmlDoc[]): Promise<string> {
let indexMarkdown = '# Overview \n\n';
const promises: Promise<any>[] = [];
for (const indexArrayItem of indexArray) {
const imagePath = `docs/assets/examples/${indexArrayItem.mdFileName!.replace('.md', '.png')}`;
const outputPath = imagePath.replace('.png', '.webp');
promises.push(sharp(imagePath).webp({quality: 90, lossless: false}).toFile(outputPath));
indexMarkdown += `
## [${indexArrayItem.title}](./${indexArrayItem.mdFileName})
![${indexArrayItem.description}](${outputPath.replace('docs/', '../')}){ loading=lazy }
${indexArrayItem.description}
`;
}
await Promise.all(promises);
return indexMarkdown;
}
/**
* Builds the README.md file by parsing the modules.md file generated by typedoc.
*/
function generateReadme() {
const globalsFile = path.join(typedocConfig.out, 'globals.md');
const content = fs.readFileSync(globalsFile, 'utf-8');
let lines = content.split('\n');
const classesLineIndex = lines.indexOf(lines.find(l => l.endsWith('Classes')) as string);
lines = lines.splice(2, classesLineIndex - 2);
const contentString = generateAPIIntroMarkdown(lines);
fs.writeFileSync(path.join(typedocConfig.out, 'README.md'), contentString);
fs.rmSync(globalsFile);
}
/**
* This takes the examples folder with all the html files and generates a markdown file for each of them.
* It also create an index file with all the examples and their images.
*/
async function generateExamplesFolder() {
const examplesDocsFolder = path.join('docs', 'examples');
if (fs.existsSync(examplesDocsFolder)) {
fs.rmSync(examplesDocsFolder, {recursive: true, force: true});
}
fs.mkdirSync(examplesDocsFolder);
const examplesFolder = path.join('test', 'examples');
const files = fs.readdirSync(examplesFolder).filter(f => f.endsWith('html'));
const maplibreUnpkg = `https://unpkg.com/maplibre-gl@${packageJson.version}/`;
const indexArray = [] as HtmlDoc[];
for (const file of files) {
const htmlFile = path.join(examplesFolder, file);
let htmlContent = fs.readFileSync(htmlFile, 'utf-8');
htmlContent = htmlContent.replace(/\.\.\/\.\.\//g, maplibreUnpkg);
htmlContent = htmlContent.replace(/-dev.js/g, '.js');
const htmlContentLines = htmlContent.split('\n');
const title = htmlContentLines.find(l => l.includes('<title'))?.replace('<title>', '').replace('</title>', '').trim()!;
const description = htmlContentLines.find(l => l.includes('og:description'))?.replace(/.*content=\"(.*)\".*/, '$1')!;
fs.writeFileSync(path.join(examplesDocsFolder, file), htmlContent);
const mdFileName = file.replace('.html', '.md');
indexArray.push({
title,
description,
mdFileName
});
const exampleMarkdown = generateMarkdownForExample(title, description, file, htmlContent);
fs.writeFileSync(path.join(examplesDocsFolder, mdFileName), exampleMarkdown);
}
const indexMarkdown = await generateMarkdownIndexFileOfAllExamplesAndPackImages(indexArray);
fs.writeFileSync(path.join(examplesDocsFolder, 'index.md'), indexMarkdown);
}
async function fetchUrlContent(url: string) {
return new Promise<string>((resolve, reject) => {
get(url, (res) => {
let data = '';
if (res.statusCode && (res.statusCode < 200 || res.statusCode >= 300)) {
reject(new Error(res.statusMessage));
return;
}
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve(data);
});
}).on('error', reject);
});
}
async function generatePluginsPage() {
/**
* It extract some sections from Awesome MapLibre README.md so we can integrate it into our plugins page
*
* ```
* header
* <!-- [SOME-ID]:BEGIN -->
* CONTENT-TO-EXTRACT
* <!-- [SOME-ID]:END -->
* footer
* ```
*/
const awesomeReadmeUrl = 'https://raw.githubusercontent.com/maplibre/awesome-maplibre/main/README.md';
const awesomeReadme = await fetchUrlContent(awesomeReadmeUrl);
const contentGroupsRE = /<!--\s*\[([-a-zA-Z]+)\]:BEGIN\s*-->([\s\S]*?)<!--\s*\[\1\]:END\s*-->/g;
const matches = awesomeReadme.matchAll(contentGroupsRE);
const groups = Object.fromEntries(
Array.from(matches).map(([, key, content]) => [key, content])
);
const pluginsContent = `# Plugins
${groups['JAVASCRIPT-PLUGINS']}
## Framework Integrations
${groups['JAVASCRIPT-BINDINGS']}
`;
fs.writeFileSync('docs/plugins.md', pluginsContent, {encoding: 'utf-8'});
}
function updateMapLibreVersionForUNPKG() {
// Read index.md
const indexPath = 'docs/index.md';
let indexContent = fs.readFileSync(indexPath, 'utf-8');
// Replace the version number
indexContent = indexContent.replace(/unpkg\.com\/maplibre-gl@\^(\d+\.\d+\.\d+)/g, `unpkg.com/maplibre-gl@^${packageJson.version}`);
// Save index.md
fs.writeFileSync(indexPath, indexContent);
}
// !!Main flow start here!!
if (!fs.existsSync(typedocConfig.out)) {
throw new Error('Please run typedoc generation first!');
}
fs.rmSync(path.join(typedocConfig.out, 'README.md'));
generateReadme();
await generateExamplesFolder();
await generatePluginsPage();
updateMapLibreVersionForUNPKG();
console.log('Docs generation completed, to see it in action run\n npm run start-docs');

36
node_modules/maplibre-gl/build/generate-shaders.ts generated vendored Normal file
View File

@@ -0,0 +1,36 @@
import fs from 'fs';
import {globSync} from 'glob';
import path from 'path';
console.log('Generating shaders');
/**
* This script is intended to copy the glsl file to the compilation output folder,
* change their extension to .js and export the shaders as strings in javascript.
* It will also minify them a bit if needed and change the extension to .js
* After that it will create a combined typescript definition file and manipulate it a bit
* It will also create a simple package.json file to allow importing this package in webpack
*/
function glslToTs(code: string): string {
code = code
.trim() // strip whitespace at the start/end
.replace(/\s*\/\/[^\n]*\n/g, '\n') // strip double-slash comments
.replace(/\n+/g, '\n') // collapse multi line breaks
.replace(/\n\s+/g, '\n') // strip indentation
.replace(/\s?([+-\/*=,])\s?/g, '$1') // strip whitespace around operators
.replace(/([;\(\),\{\}])\n(?=[^#])/g, '$1'); // strip more line breaks
return `// This file is generated. Edit build/generate-shaders.ts, then run \`npm run codegen\`.
export default ${JSON.stringify(code).replaceAll('"', '\'')};\n`;
}
const shaderFiles = globSync('./src/shaders/*.glsl');
for (const file of shaderFiles) {
const glslFile = fs.readFileSync(file, 'utf8');
const tsSource = glslToTs(glslFile);
const fileName = path.join('.', 'src', 'shaders', `${file.split(path.sep).splice(-1)}.g.ts`);
fs.writeFileSync(fileName, tsSource);
}
console.log(`Finished converting ${shaderFiles.length} shaders`);

View File

@@ -0,0 +1,440 @@
/*
* Generates the following:
* - data/array_types.js, which consists of:
* - StructArrayLayout_* subclasses, one for each underlying memory layout we need
* - Named exports mapping each conceptual array type (e.g., CircleLayoutArray) to its corresponding StructArrayLayout class
* - Particular, named StructArray subclasses, when fancy struct accessors are needed (e.g. CollisionBoxArray)
*/
'use strict';
import * as fs from 'fs';
import * as util from '../src/util/util';
import {createLayout, viewTypes} from '../src/util/struct_array';
import type {ViewType, StructArrayLayout} from '../src/util/struct_array';
import posAttributes from '../src/data/pos_attributes';
import pos3dAttributes from '../src/data/pos3d_attributes';
import rasterBoundsAttributes from '../src/data/raster_bounds_attributes';
import circleAttributes from '../src/data/bucket/circle_attributes';
import fillAttributes from '../src/data/bucket/fill_attributes';
import fillExtrusionAttributes from '../src/data/bucket/fill_extrusion_attributes';
import {lineLayoutAttributes} from '../src/data/bucket/line_attributes';
import {lineLayoutAttributesExt} from '../src/data/bucket/line_attributes_ext';
import {patternAttributes} from '../src/data/bucket/pattern_attributes';
import {dashAttributes} from '../src/data/bucket/dash_attributes';
// symbol layer specific arrays
import {
symbolLayoutAttributes,
dynamicLayoutAttributes,
placementOpacityAttributes,
collisionBox,
collisionBoxLayout,
collisionCircleLayout,
collisionVertexAttributes,
quadTriangle,
placement,
symbolInstance,
glyphOffset,
lineVertex,
textAnchorOffset
} from '../src/data/bucket/symbol_attributes';
const typeAbbreviations = {
'Int8': 'b',
'Uint8': 'ub',
'Int16': 'i',
'Uint16': 'ui',
'Int32': 'l',
'Uint32': 'ul',
'Float32': 'f'
};
const arraysWithStructAccessors = [];
const arrayTypeEntries = new Set();
const layoutCache = {};
function normalizeMembers(members, usedTypes) {
return members.map((member) => {
if (usedTypes && !usedTypes.has(member.type)) {
usedTypes.add(member.type);
}
return util.extend(member, {
size: sizeOf(member.type),
view: member.type.toLowerCase()
});
});
}
// - If necessary, write the StructArrayLayout_* class for the given layout
// - If `includeStructAccessors`, write the fancy subclass
// - Add an entry for `name` in the array type registry
function createStructArrayType(name: string, layout: StructArrayLayout, includeStructAccessors: boolean = false) {
const hasAnchorPoint = layout.members.some(m => m.name === 'anchorPointX');
// create the underlying StructArrayLayout class exists
const layoutClass = createStructArrayLayoutType(layout);
const arrayClass = `${camelize(name)}Array`;
if (includeStructAccessors) {
const usedTypes = new Set(['Uint8']);
const members = normalizeMembers(layout.members, usedTypes);
arraysWithStructAccessors.push({
arrayClass,
members,
size: layout.size,
usedTypes,
hasAnchorPoint,
layoutClass,
includeStructAccessors
});
} else {
arrayTypeEntries.add(`export class ${arrayClass} extends ${layoutClass} {}`);
}
}
function createStructArrayLayoutType({members, size, alignment}) {
const usedTypes = new Set(['Uint8']);
members = normalizeMembers(members, usedTypes);
// combine consecutive 'members' with same underlying type, summing their
// component counts
if (!alignment || alignment === 1) members = members.reduce((memo, member) => {
if (memo.length > 0 && memo[memo.length - 1].type === member.type) {
const last = memo[memo.length - 1];
return memo.slice(0, -1).concat(util.extend({}, last, {
components: last.components + member.components,
}));
}
return memo.concat(member);
}, []);
const key = `${members.map(m => `${m.components}${typeAbbreviations[m.type]}`).join('')}${size}`;
const className = `StructArrayLayout${key}`;
if (!layoutCache[key]) {
layoutCache[key] = {
className,
members,
size,
usedTypes
};
}
return className;
}
function sizeOf(type: ViewType): number {
return viewTypes[type].BYTES_PER_ELEMENT;
}
function camelize (str) {
return str.replace(/(?:^|[-_])(.)/g, (_, x) => {
return /^[0-9]$/.test(x) ? _ : x.toUpperCase();
});
}
createStructArrayType('pos', posAttributes);
createStructArrayType('pos3d', pos3dAttributes);
createStructArrayType('raster_bounds', rasterBoundsAttributes);
// layout vertex arrays
const layoutAttributes = {
circle: circleAttributes,
fill: fillAttributes,
'fill-extrusion': fillExtrusionAttributes,
heatmap: circleAttributes,
line: lineLayoutAttributes,
lineExt: lineLayoutAttributesExt,
pattern: patternAttributes,
dash: dashAttributes
};
for (const name in layoutAttributes) {
createStructArrayType(`${name.replace(/-/g, '_')}_layout`, layoutAttributes[name]);
}
createStructArrayType('symbol_layout', symbolLayoutAttributes);
createStructArrayType('symbol_dynamic_layout', dynamicLayoutAttributes);
createStructArrayType('symbol_opacity', placementOpacityAttributes);
createStructArrayType('collision_box', collisionBox, true);
createStructArrayType('collision_box_layout', collisionBoxLayout);
createStructArrayType('collision_circle_layout', collisionCircleLayout);
createStructArrayType('collision_vertex', collisionVertexAttributes);
createStructArrayType('quad_triangle', quadTriangle);
createStructArrayType('placed_symbol', placement, true);
createStructArrayType('symbol_instance', symbolInstance, true);
createStructArrayType('glyph_offset', glyphOffset, true);
createStructArrayType('symbol_line_vertex', lineVertex, true);
createStructArrayType('text_anchor_offset', textAnchorOffset, true);
// feature index array
createStructArrayType('feature_index', createLayout([
// the index of the feature in the original vectortile
{type: 'Uint32', name: 'featureIndex'},
// the source layer the feature appears in
{type: 'Uint16', name: 'sourceLayerIndex'},
// the bucket the feature appears in
{type: 'Uint16', name: 'bucketIndex'}
]), true);
// triangle index array
createStructArrayType('triangle_index', createLayout([
{type: 'Uint16', name: 'vertices', components: 3}
]));
// line index array
createStructArrayType('line_index', createLayout([
{type: 'Uint16', name: 'vertices', components: 2}
]));
// line strip index array
createStructArrayType('line_strip_index', createLayout([
{type: 'Uint16', name: 'vertices', components: 1}
]));
// paint vertex arrays
// used by SourceBinder for float properties
createStructArrayLayoutType(createLayout([{
name: 'dummy name (unused for StructArrayLayout)',
type: 'Float32',
components: 1
}], 4));
// used by SourceBinder for color properties and CompositeBinder for float properties
createStructArrayLayoutType(createLayout([{
name: 'dummy name (unused for StructArrayLayout)',
type: 'Float32',
components: 2
}], 4));
// used by CompositeBinder for color properties
createStructArrayLayoutType(createLayout([{
name: 'dummy name (unused for StructArrayLayout)',
type: 'Float32',
components: 4
}], 4));
const layouts = Object.keys(layoutCache).map(k => layoutCache[k]);
function emitStructArrayLayout(locals) {
const output = [];
const {
className,
members,
size,
usedTypes
} = locals;
const structArrayLayoutClass = className;
output.push(
`/**
* @internal
* Implementation of the StructArray layout:`);
for (const member of members) {
output.push(
` * [${member.offset}] - ${member.type}[${member.components}]`);
}
output.push(
` *
*/
class ${structArrayLayoutClass} extends StructArray {`);
for (const type of usedTypes) {
output.push(
` ${type.toLowerCase()}: ${type}Array;`);
}
output.push(`
_refreshViews() {`);
for (const type of usedTypes) {
output.push(
` this.${type.toLowerCase()} = new ${type}Array(this.arrayBuffer);`);
}
output.push(
' }');
// prep for emplaceBack: collect type sizes and count the number of arguments
// we'll need
const bytesPerElement = size;
const usedTypeSizes = [];
const argNames = [];
const argNamesTyped = [];
for (const member of members) {
if (usedTypeSizes.indexOf(member.size) < 0) {
usedTypeSizes.push(member.size);
}
for (let c = 0; c < member.components; c++) {
// arguments v0, v1, v2, ... are, in order, the components of
// member 0, then the components of member 1, etc.
const name = `v${argNames.length}`;
argNames.push(name);
argNamesTyped.push(`${name}: number`);
}
}
output.push(
`
public emplaceBack(${argNamesTyped.join(', ')}) {
const i = this.length;
this.resize(i + 1);
return this.emplace(i, ${argNames.join(', ')});
}
public emplace(i: number, ${argNamesTyped.join(', ')}) {`);
for (const size of usedTypeSizes) {
output.push(
` const o${size.toFixed(0)} = i * ${(bytesPerElement / size).toFixed(0)};`);
}
let argIndex = 0;
for (const member of members) {
for (let c = 0; c < member.components; c++) {
// The index for `member` component `c` into the appropriate type array is:
// this.{TYPE}[o{SIZE} + MEMBER_OFFSET + {c}] = v{X}
// where MEMBER_OFFSET = ROUND(member.offset / size) is the per-element
// offset of this member into the array
const index = `o${member.size.toFixed(0)} + ${(member.offset / member.size + c).toFixed(0)}`;
output.push(
` this.${member.view}[${index}] = v${argIndex++};`);
}
}
output.push(
` return i;
}
}
${structArrayLayoutClass}.prototype.bytesPerElement = ${size};
register('${structArrayLayoutClass}', ${structArrayLayoutClass});
`);
return output.join('\n');
}
function emitStructArray(locals) {
const output = [];
const {
arrayClass,
members,
size,
hasAnchorPoint,
layoutClass,
includeStructAccessors
} = locals;
const structTypeClass = arrayClass.replace('Array', 'Struct');
const structArrayClass = arrayClass;
const structArrayLayoutClass = layoutClass;
// collect components
const components = [];
for (const member of members) {
for (let c = 0; c < member.components; c++) {
let name = member.name;
if (member.components > 1) {
name += c;
}
components.push({name, member, component: c});
}
}
// exceptions for which we generate accessors on the array rather than a separate struct for performance
const useComponentGetters = structArrayClass === 'GlyphOffsetArray' || structArrayClass === 'SymbolLineVertexArray';
if (includeStructAccessors && !useComponentGetters) {
output.push(
`/** @internal */
class ${structTypeClass} extends Struct {
_structArray: ${structArrayClass};`);
for (const {name, member, component} of components) {
const elementOffset = `this._pos${member.size.toFixed(0)}`;
const componentOffset = (member.offset / member.size + component).toFixed(0);
const index = `${elementOffset} + ${componentOffset}`;
const componentAccess = `this._structArray.${member.view}[${index}]`;
output.push(
` get ${name}() { return ${componentAccess}; }`);
// generate setters for properties that are updated during runtime symbol placement; others are read-only
if (name === 'crossTileID' || name === 'placedOrientation' || name === 'hidden') {
output.push(
` set ${name}(x: number) { ${componentAccess} = x; }`);
}
}
// Special case used for the CollisionBoxArray type
if (hasAnchorPoint) {
output.push(
' get anchorPoint() { return new Point(this.anchorPointX, this.anchorPointY); }');
}
output.push(
`}
${structTypeClass}.prototype.size = ${size};
export type ${structTypeClass.replace('Struct', '')} = ${structTypeClass};
`);
} // end 'if (includeStructAccessors)'
output.push(
`/** @internal */
export class ${structArrayClass} extends ${structArrayLayoutClass} {`);
if (useComponentGetters) {
for (const member of members) {
for (let c = 0; c < member.components; c++) {
if (!includeStructAccessors) continue;
let name = `get${member.name}`;
if (member.components > 1) {
name += c;
}
const componentOffset = (member.offset / member.size + c).toFixed(0);
const componentStride = size / member.size;
output.push(
` ${name}(index: number) { return this.${member.view}[index * ${componentStride} + ${componentOffset}]; }`);
}
}
} else if (includeStructAccessors) { // get(i)
output.push(
` /**
* Return the ${structTypeClass} at the given location in the array.
* @param index - The index of the element.
*/
get(index: number): ${structTypeClass} {
return new ${structTypeClass}(this, index);
}`);
}
output.push(
`}
register('${structArrayClass}', ${structArrayClass});
`);
return output.join('\n');
}
fs.writeFileSync('src/data/array_types.g.ts',
`// This file is generated. Edit build/generate-struct-arrays.ts, then run \`npm run codegen\`.
import {Struct, StructArray} from '../util/struct_array';
import {register} from '../util/web_worker_transfer';
import Point from '@mapbox/point-geometry';
${layouts.map(emitStructArrayLayout).join('\n')}
${arraysWithStructAccessors.map(emitStructArray).join('\n')}
${[...arrayTypeEntries].join('\n')}
export {
${layouts.map(layout => layout.className).join(',\n ')}
};
`);

287
node_modules/maplibre-gl/build/generate-style-code.ts generated vendored Normal file
View File

@@ -0,0 +1,287 @@
'use strict';
import * as fs from 'fs';
import {v8} from '@maplibre/maplibre-gl-style-spec';
function camelCase(str: string): string {
return str.replace(/-(.)/g, (_, x) => {
return x.toUpperCase();
});
}
function pascalCase(str: string): string {
const almostCamelized = camelCase(str);
return almostCamelized[0].toUpperCase() + almostCamelized.slice(1);
}
function nativeType(property) {
switch (property.type) {
case 'boolean':
return 'boolean';
case 'number':
return 'number';
case 'string':
return 'string';
case 'enum':
return Object.keys(property.values).map(v => JSON.stringify(v)).join(' | ');
case 'color':
return 'Color';
case 'padding':
return 'Padding';
case 'numberArray':
return 'NumberArray';
case 'colorArray':
return 'ColorArray';
case 'variableAnchorOffsetCollection':
return 'VariableAnchorOffsetCollection';
case 'sprite':
return 'Sprite';
case 'formatted':
return 'Formatted';
case 'resolvedImage':
return 'ResolvedImage';
case 'array':
if (property.length) {
return `[${new Array(property.length).fill(nativeType({type: property.value})).join(', ')}]`;
} else {
return `Array<${nativeType({type: property.value, values: property.values})}>`;
}
default: throw new Error(`unknown type "${property.type}" for "${property.name}"`);
}
}
function possiblyEvaluatedType(property) {
const propType = nativeType(property);
switch (property['property-type']) {
case 'color-ramp':
return 'ColorRampProperty';
case 'cross-faded':
return `CrossFaded<${propType}>`;
case 'cross-faded-data-driven':
return `PossiblyEvaluatedPropertyValue<CrossFaded<${propType}>>`;
case 'data-driven':
return `PossiblyEvaluatedPropertyValue<${propType}>`;
}
return propType;
}
function propertyType(property) {
switch (property['property-type']) {
case 'data-driven':
return `DataDrivenProperty<${nativeType(property)}>`;
case 'cross-faded':
return `CrossFadedProperty<${nativeType(property)}>`;
case 'cross-faded-data-driven':
return `CrossFadedDataDrivenProperty<${nativeType(property)}>`;
case 'color-ramp':
return 'ColorRampProperty';
case 'data-constant':
case 'constant':
return `DataConstantProperty<${nativeType(property)}>`;
default:
throw new Error(`unknown property-type "${property['property-type']}" for ${property.name}`);
}
}
function runtimeType(property) {
switch (property.type) {
case 'boolean':
return 'BooleanType';
case 'number':
return 'NumberType';
case 'string':
case 'enum':
return 'StringType';
case 'color':
return 'ColorType';
case 'padding':
return 'PaddingType';
case 'variableAnchorOffsetCollection':
return 'VariableAnchorOffsetCollectionType';
case 'sprite':
return 'SpriteType';
case 'formatted':
return 'FormattedType';
case 'Image':
return 'ImageType';
case 'array':
if (property.length) {
return `array(${runtimeType({type: property.value})}, ${property.length})`;
} else {
return `array(${runtimeType({type: property.value})})`;
}
default: throw new Error(`unknown type "${property.type}" for "${property.name}"`);
}
}
function overrides(property) {
return `{ runtimeType: ${runtimeType(property)}, getOverride: (o) => o.${camelCase(property.name)}, hasOverride: (o) => !!o.${camelCase(property.name)} }`;
}
function propertyValue(property, type) {
const propertyAsSpec = `styleSpec["${type}_${property.layerType}"]["${property.name}"] as any as StylePropertySpecification`;
switch (property['property-type']) {
case 'data-driven':
if (property.overridable) {
return `new DataDrivenProperty(${propertyAsSpec}, ${overrides(property)})`;
} else {
return `new DataDrivenProperty(${propertyAsSpec})`;
}
case 'cross-faded':
return `new CrossFadedProperty(${propertyAsSpec})`;
case 'cross-faded-data-driven':
return `new CrossFadedDataDrivenProperty(${propertyAsSpec})`;
case 'color-ramp':
return `new ColorRampProperty(${propertyAsSpec})`;
case 'data-constant':
case 'constant':
return `new DataConstantProperty(${propertyAsSpec})`;
default:
throw new Error(`unknown property-type "${property['property-type']}" for ${property.name}`);
}
}
const layers = Object.keys(v8.layer.type.values).map((type) => {
const layoutProperties = Object.keys(v8[`layout_${type}`]).reduce((memo, name) => {
if (name !== 'visibility') {
v8[`layout_${type}`][name].name = name;
v8[`layout_${type}`][name].layerType = type;
memo.push(v8[`layout_${type}`][name]);
}
return memo;
}, []);
const paintProperties = Object.keys(v8[`paint_${type}`]).reduce((memo, name) => {
v8[`paint_${type}`][name].name = name;
v8[`paint_${type}`][name].layerType = type;
memo.push(v8[`paint_${type}`][name]);
return memo;
}, []);
return {type, layoutProperties, paintProperties};
});
function emitlayerProperties(locals) {
const output = [];
const layerType = pascalCase(locals.type);
const {
layoutProperties,
paintProperties
} = locals;
output.push(
`// This file is generated. Edit build/generate-style-code.ts, then run 'npm run codegen'.
/* eslint-disable */
import {latest as styleSpec} from '@maplibre/maplibre-gl-style-spec';
import {
Properties,
DataConstantProperty,
DataDrivenProperty,
CrossFadedDataDrivenProperty,
CrossFadedProperty,
ColorRampProperty,
PossiblyEvaluatedPropertyValue,
CrossFaded
} from '../properties';
import type {Color, Formatted, Padding, NumberArray, ColorArray, ResolvedImage, VariableAnchorOffsetCollection} from '@maplibre/maplibre-gl-style-spec';
import {StylePropertySpecification} from '@maplibre/maplibre-gl-style-spec';
`);
const overridables = paintProperties.filter(p => p.overridable);
if (overridables.length) {
const overridesArray = `import {
${overridables.reduce((imports, prop) => { imports.push(runtimeType(prop)); return imports; }, []).join(',\n ')}
} from '@maplibre/maplibre-gl-style-spec';
`;
output.push(overridesArray);
}
if (layoutProperties.length) {
output.push(
`export type ${layerType}LayoutProps = {`);
for (const property of layoutProperties) {
output.push(
` "${property.name}": ${propertyType(property)},`);
}
output.push(
`};
export type ${layerType}LayoutPropsPossiblyEvaluated = {`);
for (const property of layoutProperties) {
output.push(
` "${property.name}": ${possiblyEvaluatedType(property)},`);
}
output.push(
`};
let layout: Properties<${layerType}LayoutProps>;
const getLayout = () => layout = layout || new Properties({`);
for (const property of layoutProperties) {
output.push(
` "${property.name}": ${propertyValue(property, 'layout')},`);
}
output.push(
'});');
}
if (paintProperties.length) {
output.push(
`
export type ${layerType}PaintProps = {`);
for (const property of paintProperties) {
output.push(
` "${property.name}": ${propertyType(property)},`);
}
output.push(
`};
export type ${layerType}PaintPropsPossiblyEvaluated = {`);
for (const property of paintProperties) {
output.push(
` "${property.name}": ${possiblyEvaluatedType(property)},`);
}
output.push(
'};');
} else {
output.push(
`export type ${layerType}PaintProps = {};`);
}
output.push(
`
let paint: Properties<${layerType}PaintProps>;
const getPaint = () => paint = paint || new Properties({`);
for (const property of paintProperties) {
output.push(
` "${property.name}": ${propertyValue(property, 'paint')},`);
}
output.push(
`});
export default ({ get paint() { return getPaint() }${layoutProperties.length ? ', get layout() { return getLayout() }' : ''} });`);
return output.join('\n');
}
for (const layer of layers) {
fs.writeFileSync(`src/style/style_layer/${layer.type.replace('-', '_')}_style_layer_properties.g.ts`, emitlayerProperties(layer));
}

370
node_modules/maplibre-gl/build/generate-unicode-data.ts generated vendored Normal file
View File

@@ -0,0 +1,370 @@
import * as fs from 'fs';
import * as regenerate from 'regenerate';
/**
* The heuristics in the functions below are based on this version of the
* Unicode Standard. This constant should match the `@unicode/unicode-*` package
* in package.json.
*
* When upgrading to a new version of the standard, consider any new scripts,
* blocks, and characters that may require different script detection.
*/
const unicodeVersion = '17.0.0';
async function createSet(blocks: Array<string>, scripts: Array<string>): Promise<regenerate.regenerate> {
const set = regenerate.default();
for (const block of blocks) {
const slug = block.replace(/[- ]/g, '_');
set.add((await import(`@unicode/unicode-${unicodeVersion}/Block/${slug}/code-points.js`)).default);
}
for (const script of scripts) {
const slug = script.replace(/[- ]/g, '_');
set.add((await import(`@unicode/unicode-${unicodeVersion}/Script/${slug}/code-points.js`)).default);
}
return set;
}
async function usesLocalIdeographFontFamily(): Promise<string> {
// Local rendering is preferred for Unicode code blocks that represent
// writing systems for which TinySDF produces optimal results and greatly
// reduces bandwidth consumption. In general, TinySDF is best for any
// writing system typically set in a monospaced font. With more than 99,000
// codepoints accessed essentially at random, Hanzi/Kanji/Hanja (from the
// CJK Unified Ideographs blocks) is the canonical example of wasteful
// bandwidth consumption when rendered remotely. For visual consistency
// within CJKV text, even relatively small CJKV and other siniform code
// blocks prefer local rendering.
const set = await createSet([
'CJK Compatibility Forms',
'CJK Compatibility',
'CJK Radicals Supplement',
'CJK Strokes',
'CJK Unified Ideographs',
'Enclosed CJK Letters And Months',
'Enclosed Ideographic Supplement',
'Halfwidth And Fullwidth Forms',
'Hangul Syllables',
'Hiragana',
'Ideographic Symbols And Punctuation',
'Kana Extended-A',
'Kana Extended-B',
'Kana Supplement',
'Kangxi Radicals',
'Katakana', // includes "ー"
'Katakana Phonetic Extensions',
// memo: these symbols are not all. others could be added if needed.
'CJK Symbols And Punctuation', // 、。〃〄々〆〇〈〉《》「...
'Halfwidth And Fullwidth Forms',
'Small Kana Extension',
'Vertical Forms',
], [
'Bopomofo',
'Han',
'Hangul',
'Hiragana',
'Katakana',
'Khitan Small Script',
'Nushu',
'Tangut',
'Yi',
]);
set.add((await import(`@unicode/unicode-${unicodeVersion}/Binary_Property/Ideographic/code-points.js`)).default);
return set.toString();
}
async function allowsIdeographicBreaking(): Promise<string> {
// Unicode only considers CJKV to be ideographic, but some other scripts mix
// with CJKV so can also have ideographic line breaking.
const set = await createSet([
'CJK Compatibility Forms',
'CJK Compatibility',
'CJK Radicals Supplement',
'CJK Strokes',
'CJK Symbols And Punctuation',
'Enclosed CJK Letters And Months',
'Enclosed Ideographic Supplement',
'Halfwidth And Fullwidth Forms',
'Ideographic Description Characters',
'Ideographic Symbols And Punctuation',
'Kana Extended-A',
'Kana Extended-B',
'Kana Supplement',
'Kangxi Radicals',
'Katakana Phonetic Extensions',
'Small Kana Extension',
'Vertical Forms',
], [
'Bopomofo',
'Han',
'Hiragana',
'Katakana',
'Khitan Small Script',
'Nushu',
'Tangut',
'Yi',
]);
return set.toString();
}
// The following logic comes from
// <https://www.unicode.org/Public/17.0.0/ucd/VerticalOrientation.txt>.
// Keep it synchronized with
// <https://www.unicode.org/Public/UCD/latest/ucd/VerticalOrientation.txt>.
// The data file denotes with “U” or “Tu” any codepoint that may be drawn
// upright in vertical text but does not distinguish between upright and
// “neutral” characters.
async function hasUprightVerticalOrientation(): Promise<string> {
const set = await createSet([
'Alchemical Symbols',
'Anatolian Hieroglyphs',
'Byzantine Musical Symbols',
'Chess Symbols',
'CJK Compatibility Forms',
'CJK Compatibility',
'CJK Strokes',
'CJK Symbols And Punctuation',
'Counting Rod Numerals',
'Domino Tiles',
'Emoticons',
'Enclosed Alphanumeric Supplement',
'Enclosed CJK Letters And Months',
'Geometric Shapes Extended',
'Halfwidth And Fullwidth Forms',
'Ideographic Description Characters',
'Kanbun',
'Katakana',
'Mahjong Tiles',
'Mayan Numerals',
'Meroitic Hieroglyphs',
'Miscellaneous Symbols And Pictographs',
'Miscellaneous Symbols Supplement',
'Musical Symbols',
'Ornamental Dingbats',
'Playing Cards',
'Siddham',
'Small Form Variants',
'Small Kana Extension',
'Soyombo',
'Supplemental Symbols And Pictographs',
'Sutton SignWriting',
'Symbols And Pictographs Extended-A',
'Tai Xuan Jing Symbols',
'Transport And Map Symbols',
'Vertical Forms',
'Yijing Hexagram Symbols',
'Zanabazar Square',
'Znamenny Musical Notation',
], [
'Bopomofo',
'Canadian Aboriginal',
'Han',
'Hangul',
'Hiragana',
'Katakana',
'Khitan Small Script',
'Nushu',
'Tangut',
'Yi',
]);
set.add(0x02EA /* modifier letter yin departing tone mark */);
set.add(0x02EB /* modifier letter yang departing tone mark */);
// Exceptions to CJK Compatibility Forms
set.removeRange(0xFE49 /* dashed overline */, 0xFE4F /* wavy low line */);
// Exceptions to CJK Symbols and Punctuation
set.removeRange(0x3008 /* left angle bracket */, 0x3011 /* right black lenticular bracket */);
set.removeRange(0x3014 /* left tortoise shell bracket */, 0x301F /* low double prime quotation mark */);
set.remove(0x3030 /* wavy dash */);
// Exceptions to Katakana
set.remove(0x30FC /* katakana-hiragana prolonged sound mark */);
// Exceptions to Halfwidth and Fullwidth Forms
set.remove(0xFF08 /* fullwidth left parenthesis */);
set.remove(0xFF09 /* fullwidth right parenthesis */);
set.remove(0xFF0D /* fullwidth hyphen-minus */);
set.removeRange(0xFF1A /* fullwidth colon */, 0xFF1E /* fullwidth greater-than sign */);
set.remove(0xFF3B /* fullwidth left square bracket */);
set.remove(0xFF3D /* fullwidth right square bracket */);
set.remove(0xFF3F /* fullwidth low line */);
set.removeRange(0xFF5B /* fullwidth left curly bracket */, 0xFFDF);
set.remove(0xFFE3 /* fullwidth macron */);
set.removeRange(0xFFE8 /* halfwidth forms light vertical */, 0xFFEF);
// Exceptions to Small Form Variants
set.removeRange(0xFE58 /* small em dash */, 0xFE5E /* small right tortoise shell bracket */);
set.removeRange(0xFE63 /* small hyphen-minus */, 0xFE66 /* small equals sign */);
return set.toString();
}
async function hasNeutralVerticalOrientation(): Promise<string> {
const set = await createSet([
'CJK Compatibility Forms',
'CJK Symbols And Punctuation',
'Control Pictures',
'Enclosed Alphanumerics',
'Geometric Shapes',
'Halfwidth And Fullwidth Forms',
'Katakana',
'Letterlike Symbols',
'Miscellaneous Symbols',
'Number Forms',
'Optical Character Recognition',
'Private Use Area',
'Small Form Variants',
'Supplementary Private Use Area-A',
'Supplementary Private Use Area-B',
], []);
// Latin-1 Supplement
set.add(0x00A7 /* section sign */);
set.add(0x00A9 /* copyright sign */);
set.add(0x00AE /* registered sign */);
set.add(0x00B1 /* plus-minus sign */);
set.add(0x00BC /* vulgar fraction one quarter */);
set.add(0x00BD /* vulgar fraction one half */);
set.add(0x00BE /* vulgar fraction three quarters */);
set.add(0x00D7 /* multiplication sign */);
set.add(0x00F7 /* division sign */);
// General Punctuation
set.add(0x2016 /* double vertical line */);
set.add(0x2020 /* dagger */);
set.add(0x2021 /* double dagger */);
set.add(0x2030 /* per mille sign */);
set.add(0x2031 /* per ten thousand sign */);
set.add(0x203B /* reference mark */);
set.add(0x203C /* double exclamation mark */);
set.add(0x2042 /* asterism */);
set.add(0x2047 /* double question mark */);
set.add(0x2048 /* question exclamation mark */);
set.add(0x2049 /* exclamation question mark */);
set.add(0x2051 /* two asterisks aligned vertically */);
// Miscellaneous Technical
set.addRange(0x2300 /* diameter sign */, 0x2307 /* wavy line */);
set.addRange(0x230C /* bottom right crop */, 0x231F /* bottom right corner */);
set.addRange(0x2324 /* up arrowhead between two horizontal bars */, 0x2328 /* keyboard */);
set.add(0x232B /* erase to the left */);
set.addRange(0x237D /* shouldered open box */, 0x239A /* clear screen symbol */);
set.addRange(0x23BE /* dentistry symbol light vertical and top right */, 0x23CD /* square foot */);
set.add(0x23CF /* eject symbol */);
set.addRange(0x23D1 /* metrical breve */, 0x23DB /* fuse */);
set.addRange(0x23E2 /* white trapezium */, 0x23FF);
// Exceptions to Control Pictures
set.remove(0x2423 /* open box */);
// Exceptions to Miscellaneous Symbols
set.removeRange(0x261A /* black left pointing index */, 0x261F /* white down pointing index */);
// Miscellaneous Symbols and Arrows
set.addRange(0x2B12 /* square with top half black */, 0x2B2F /* white vertical ellipse */);
set.addRange(0x2B50 /* white medium star */, 0x2B59 /* heavy circled saltire */);
set.addRange(0x2BB8 /* upwards white arrow from bar with horizontal bar */, 0x2BEB);
set.add(0x221E /* infinity */);
set.add(0x2234 /* therefore */);
set.add(0x2235 /* because */);
set.addRange(0x2700 /* black safety scissors */, 0x2767 /* rotated floral heart bullet */);
set.addRange(0x2776 /* dingbat negative circled digit one */, 0x2793 /* dingbat negative circled sans-serif number ten */);
set.add(0xFFFC /* object replacement character */);
set.add(0xFFFD /* replacement character */);
return set.toString();
}
async function requiresComplexTextShaping(): Promise<string> {
// This is a rough heuristic: whether we "can render" a script
// actually depends on the properties of the font being used
// and whether differences from the ideal rendering are considered
// semantically significant.
// These blocks cover common scripts that require
// complex text shaping, based on unicode script metadata:
// https://www.unicode.org/repos/cldr/trunk/common/properties/scriptMetadata.txt
// where "Web Rank <= 32" "Shaping Required = YES"
const set = await createSet([
'Bengali',
'Devanagari',
'Gujarati',
'Gurmukhi',
'Kannada',
'Khmer',
'Malayalam',
'Myanmar',
'Oriya',
'Tamil',
'Telugu',
'Tibetan',
'Sinhala',
], []);
return set.toString();
}
fs.writeFileSync('src/util/unicode_properties.g.ts',
`// This file is generated. Edit build/generate-unicode-data.ts, then run \`npm run generate-unicode-data\`.
/**
* Returns whether the fallback fonts specified by the
* \`localIdeographFontFamily\` map option apply to the given codepoint.
*/
export function codePointUsesLocalIdeographFontFamily(codePoint: number): boolean {
return /${await usesLocalIdeographFontFamily()}/gim.test(String.fromCodePoint(codePoint));
}
/**
* Returns whether the given codepoint participates in ideographic line
* breaking.
*/
export function codePointAllowsIdeographicBreaking(codePoint: number): boolean {
return /${await allowsIdeographicBreaking()}/gim.test(String.fromCodePoint(codePoint));
}
/**
* Returns true if the given Unicode codepoint identifies a character with
* upright orientation.
*
* A character has upright orientation if it is drawn upright (unrotated)
* whether the line is oriented horizontally or vertically, even if both
* adjacent characters can be rotated. For example, a Chinese character is
* always drawn upright. An uprightly oriented character causes an adjacent
* “neutral” character to be drawn upright as well.
*/
export function codePointHasUprightVerticalOrientation(codePoint: number): boolean {
return /${await hasUprightVerticalOrientation()}/gim.test(String.fromCodePoint(codePoint));
}
/**
* Returns true if the given Unicode codepoint identifies a character with
* neutral orientation.
*
* A character has neutral orientation if it may be drawn rotated or unrotated
* when the line is oriented vertically, depending on the orientation of the
* adjacent characters. For example, along a vertically oriented line, the
* vulgar fraction ½ is drawn upright among Chinese characters but rotated among
* Latin letters. A neutrally oriented character does not influence whether an
* adjacent character is drawn upright or rotated.
*/
export function codePointHasNeutralVerticalOrientation(codePoint: number): boolean {
return /${await hasNeutralVerticalOrientation()}/gim.test(String.fromCodePoint(codePoint));
}
/**
* Returns whether the give codepoint is likely to require complex text shaping.
*/
export function codePointRequiresComplexTextShaping(codePoint: number): boolean {
return /${await requiresComplexTextShaping()}/gim.test(String.fromCodePoint(codePoint));
}
`);

52
node_modules/maplibre-gl/build/readme.md generated vendored Normal file
View File

@@ -0,0 +1,52 @@
# Build Scripts
This folder holds common build scripts accessed via the various `npm run` commands.
Codegen is executed when calling `npm install` in order to generate all artifacts needed for the build to pass
## Bundling all the code
The bundling process can be split into several steps:
`npm run build-css`
This command will compile the css code and create the css file.
`npm run build-prod` and `npm run build-dev`
These commands will use rollup to bundle the code. This is where the magic happens and uses some files in this folder.
`banner.ts` is used to create a banner at the beginning of the output file
`rollup_plugins.ts` is used to define common plugins for rollup configurations
`rollup_plugin_minify_style_spec.ts` is used to specify the plugin used in style spec bundling
In the `rollup` folder there are some files that are used as linking files as they link to other files for rollup to pick when bundling.
Rollup is generating 3 files throughout the process of bundling:
`index.ts` a file containing all the code that will run in the main thread.
`shared.ts` a file containing all the code shared between the main and worker code.
`worker.ts` a file containing all the code the will run in the worker threads.
These 3 files are then referenced and used by the `bundle_prelude.js` file. It allows loading the web worker code automatically in web workers without any extra effort from someone who would like to use the library, i.e. it simply works.
<hr>
### `npm run codegen`
The `codegen` command runs the following three scripts, to update the corresponding code files based on the `v8.json` style source, and other data files. Contributors should run this command manually when the underlying style data is modified. The generated code files are then committed to the repo.
#### generate-struct-arrays.ts
Generates `data/array_types.ts`, which consists of:
- `StructArrayLayout_*` subclasses, one for each underlying memory layout
- Named exports mapping each conceptual array type (e.g., `CircleLayoutArray`) to its corresponding `StructArrayLayout` class
- Specific named `StructArray` subclasses, when type-specific struct accessors are needed (e.g., `CollisionBoxArray`)
#### generate-style-code.ts
Generates the various `style/style_layer/[layer type]_style_layer_properties.ts` code files based on the content of `v8.json`. These files provide the type signatures for the paint and layout properties for each type of style layer.
<hr>

View File

@@ -0,0 +1,29 @@
/* eslint-disable */
var maplibregl = {};
var modules = {};
function define(moduleName, _dependencies, moduleFactory) {
modules[moduleName] = moduleFactory;
// to get the list of modules see generated dist/maplibre-gl-dev.js file (look for `define(` calls)
if (moduleName !== 'index') {
return;
}
// we assume that when an index module is initializing then other modules are loaded already
var workerBundleString = 'var sharedModule = {}; (' + modules.shared + ')(sharedModule); (' + modules.worker + ')(sharedModule);'
var sharedModule = {};
// the order of arguments of a module factory depends on rollup (it decides who is whose dependency)
// to check the correct order, see dist/maplibre-gl-dev.js file (look for `define(` calls)
// we assume that for our 3 chunks it will generate 3 modules and their order is predefined like the following
modules.shared(sharedModule);
modules.index(maplibregl, sharedModule);
if (typeof window !== 'undefined') {
maplibregl.setWorkerUrl(window.URL.createObjectURL(new Blob([workerBundleString], { type: 'text/javascript' })));
}
return maplibregl;
};

22
node_modules/maplibre-gl/build/rollup/maplibregl.js generated vendored Normal file
View File

@@ -0,0 +1,22 @@
//
// Our custom intro provides a specialized "define()" function, called by the
// AMD modules below, that sets up the worker blob URL and then executes the
// main module, storing its exported value as 'maplibregl'
// The three "chunks" imported here are produced by a first Rollup pass,
// which outputs them as AMD modules.
// Shared dependencies
import '../../staging/maplibregl/shared';
// Worker and its unique dependencies
// When this wrapper function is passed to our custom define() in build/rollup/bundle_prelude.js,
// it gets stringified, together with the shared wrapper (using
// Function.toString()), and the resulting string of code is made into a
// Blob URL that gets used by the main module to create the web workers.
import '../../staging/maplibregl/worker';
// Main module and its dependencies
import '../../staging/maplibregl/index';
export default maplibregl;

68
node_modules/maplibre-gl/build/rollup_plugins.ts generated vendored Normal file
View File

@@ -0,0 +1,68 @@
import typescript from '@rollup/plugin-typescript';
import resolve from '@rollup/plugin-node-resolve';
import replace from '@rollup/plugin-replace';
import commonjs from '@rollup/plugin-commonjs';
import terser from '@rollup/plugin-terser';
import {type Plugin} from 'rollup';
import json from '@rollup/plugin-json';
import {visualizer} from 'rollup-plugin-visualizer';
const {BUNDLE} = process.env;
const stats = BUNDLE === 'stats';
// Common set of plugins/transformations shared across different rollup
// builds (main maplibre bundle, style-spec package, benchmarks bundle)
export const nodeResolve = resolve({
browser: true,
preferBuiltins: false
});
export const plugins = (production: boolean): Plugin[] => [
json(),
// https://github.com/zaach/jison/issues/351
replace({
preventAssignment: true,
include: /\/jsonlint-lines-primitives\/lib\/jsonlint.js/,
delimiters: ['', ''],
values: {
'_token_stack:': ''
}
}),
production && terser({
compress: {
pure_getters: true,
passes: 3
},
sourceMap: true
}),
nodeResolve,
typescript(),
commonjs({
// global keyword handling causes Webpack compatibility issues, so we disabled it:
// https://github.com/mapbox/mapbox-gl-js/pull/6956
ignoreGlobal: true
}),
// generate bundle stats in multiple formats (treemap, sunburst, etc...)
...(stats ? (['treemap', 'sunburst', 'flamegraph', 'network'] as const).map(template =>
visualizer({
template: template,
title: `gl-js-${template}`,
filename: `staging/${template}.html`,
gzipSize: true,
brotliSize: true,
sourcemap: true,
open: true
})
) : [])
].filter(Boolean) as Plugin[];
export const watchStagingPlugin: Plugin = {
name: 'watch-external',
buildStart() {
this.addWatchFile('staging/maplibregl/index.js');
this.addWatchFile('staging/maplibregl/shared.js');
this.addWatchFile('staging/maplibregl/worker.js');
}
};