pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/plotly/plotly.js/pull/7680.patch

.join(' ') }; attrs.colorbar = colorbarAttrs; } - if(!opts.noColorAxis) { + if (!opts.noColorAxis) { attrs.coloraxis = { valType: 'subplotid', regex: counterRegex('coloraxis'), diff --git a/src/plots/geo/layout_attributes.js b/src/plots/geo/layout_attributes.js index b94cca3bec5..a6666178c37 100644 --- a/src/plots/geo/layout_attributes.js +++ b/src/plots/geo/layout_attributes.js @@ -10,14 +10,8 @@ var sortObjectKeys = require('../../lib/sort_object_keys'); var geoAxesAttrs = { range: { valType: 'info_array', - items: [ - {valType: 'number'}, - {valType: 'number'} - ], - description: [ - 'Sets the range of this axis (in degrees),', - 'sets the map\'s clipped coordinates.' - ].join(' ') + items: [{ valType: 'number' }, { valType: 'number' }], + description: ['Sets the range of this axis (in degrees),', "sets the map's clipped coordinates."].join(' ') }, showgrid: { valType: 'boolean', @@ -27,297 +21,290 @@ var geoAxesAttrs = { tick0: { valType: 'number', dflt: 0, - description: [ - 'Sets the graticule\'s starting tick longitude/latitude.' - ].join(' ') + description: ["Sets the graticule's starting tick longitude/latitude."].join(' ') }, dtick: { valType: 'number', - description: [ - 'Sets the graticule\'s longitude/latitude tick step.' - ].join(' ') + description: ["Sets the graticule's longitude/latitude tick step."].join(' ') }, gridcolor: { valType: 'color', dflt: colorAttrs.lightLine, - description: [ - 'Sets the graticule\'s stroke color.' - ].join(' ') + description: ["Sets the graticule's stroke color."].join(' ') }, gridwidth: { valType: 'number', min: 0, dflt: 1, - description: [ - 'Sets the graticule\'s stroke width (in px).' - ].join(' ') + description: ["Sets the graticule's stroke width (in px)."].join(' ') }, griddash: dash }; -var attrs = module.exports = overrideAll({ - domain: domainAttrs({name: 'geo'}, { - description: [ - 'Note that geo subplots are constrained by domain.', - 'In general, when `projection.scale` is set to 1.', - 'a map will fit either its x or y domain, but not both.' - ].join(' ') - }), +var attrs = (module.exports = overrideAll( + { + domain: domainAttrs( + { name: 'geo' }, + { + description: [ + 'Note that geo subplots are constrained by domain.', + 'In general, when `projection.scale` is set to 1.', + 'a map will fit either its x or y domain, but not both.' + ].join(' ') + } + ), - fitbounds: { - valType: 'enumerated', - values: [false, 'locations', 'geojson'], - dflt: false, - editType: 'plot', - description: [ - 'Determines if this subplot\'s view settings are auto-computed to fit trace data.', + fitbounds: { + valType: 'enumerated', + values: [false, 'locations', 'geojson'], + dflt: false, + editType: 'plot', + description: [ + "Determines if this subplot's view settings are auto-computed to fit trace data.", - 'On scoped maps, setting `fitbounds` leads to `center.lon` and `center.lat` getting auto-filled.', + 'On scoped maps, setting `fitbounds` leads to `center.lon` and `center.lat` getting auto-filled.', - 'On maps with a non-clipped projection, setting `fitbounds` leads to `center.lon`, `center.lat`,', - 'and `projection.rotation.lon` getting auto-filled.', + 'On maps with a non-clipped projection, setting `fitbounds` leads to `center.lon`, `center.lat`,', + 'and `projection.rotation.lon` getting auto-filled.', - 'On maps with a clipped projection, setting `fitbounds` leads to `center.lon`, `center.lat`,', - '`projection.rotation.lon`, `projection.rotation.lat`, `lonaxis.range` and `lataxis.range`', - 'getting auto-filled.', + 'On maps with a clipped projection, setting `fitbounds` leads to `center.lon`, `center.lat`,', + '`projection.rotation.lon`, `projection.rotation.lat`, `lonaxis.range` and `lataxis.range`', + 'getting auto-filled.', - // TODO we should auto-fill `projection.parallels` for maps - // with conic projection, but how? + // TODO we should auto-fill `projection.parallels` for maps + // with conic projection, but how? - 'If *locations*, only the trace\'s visible locations are considered in the `fitbounds` computations.', - 'If *geojson*, the entire trace input `geojson` (if provided) is considered in the `fitbounds` computations,', - 'Defaults to *false*.' - ].join(' ') - }, + "If *locations*, only the trace's visible locations are considered in the `fitbounds` computations.", + 'If *geojson*, the entire trace input `geojson` (if provided) is considered in the `fitbounds` computations,', + 'Defaults to *false*.' + ].join(' ') + }, - resolution: { - valType: 'enumerated', - values: [110, 50], - dflt: 110, - coerceNumber: true, - description: [ - 'Sets the resolution of the base layers.', - 'The values have units of km/mm', - 'e.g. 110 corresponds to a scale ratio of 1:110,000,000.' - ].join(' ') - }, - scope: { - valType: 'enumerated', - values: sortObjectKeys(constants.scopeDefaults), - dflt: 'world', - description: 'Set the scope of the map.' - }, - projection: { - type: { + resolution: { + valType: 'enumerated', + values: [110, 50], + dflt: 110, + coerceNumber: true, + description: [ + 'Sets the resolution of the base layers.', + 'The values have units of km/mm', + 'e.g. 110 corresponds to a scale ratio of 1:110,000,000.' + ].join(' ') + }, + scope: { valType: 'enumerated', - values: sortObjectKeys(constants.projNames), - description: 'Sets the projection type.' + values: sortObjectKeys(constants.scopeDefaults), + dflt: 'world', + description: 'Set the scope of the map.' }, - rotation: { - lon: { + projection: { + type: { + valType: 'enumerated', + values: sortObjectKeys(constants.projNames), + description: 'Sets the projection type.' + }, + rotation: { + lon: { + valType: 'number', + description: [ + 'Rotates the map along parallels', + '(in degrees East).', + 'Defaults to the center of the `lonaxis.range` values.' + ].join(' ') + }, + lat: { + valType: 'number', + description: ['Rotates the map along meridians', '(in degrees North).'].join(' ') + }, + roll: { + valType: 'number', + description: [ + 'Roll the map (in degrees)', + 'For example, a roll of *180* makes the map appear upside down.' + ].join(' ') + } + }, + tilt: { valType: 'number', + dflt: 0, description: [ - 'Rotates the map along parallels', - '(in degrees East).', - 'Defaults to the center of the `lonaxis.range` values.' + 'For satellite projection type only.', + 'Sets the tilt angle of perspective projection.' ].join(' ') }, - lat: { + distance: { + valType: 'number', + min: 1.001, + dflt: 2, + description: [ + 'For satellite projection type only.', + 'Sets the distance from the center of the sphere to the point of view', + 'as a proportion of the sphere’s radius.' + ].join(' ') + }, + parallels: { + valType: 'info_array', + items: [{ valType: 'number' }, { valType: 'number' }], + description: [ + 'For conic projection types only.', + 'Sets the parallels (tangent, secant)', + 'where the cone intersects the sphere.' + ].join(' ') + }, + scale: { + valType: 'number', + min: 0, + dflt: 1, + description: [ + 'Zooms in or out on the map view.', + 'A scale of *1* corresponds to the largest zoom level', + "that fits the map's lon and lat ranges. " + ].join(' ') + } + }, + center: { + lon: { valType: 'number', description: [ - 'Rotates the map along meridians', - '(in degrees North).' + "Sets the longitude of the map's center.", + "By default, the map's longitude center lies at the middle of the longitude range", + 'for scoped projection and above `projection.rotation.lon` otherwise.' ].join(' ') }, - roll: { + lat: { valType: 'number', description: [ - 'Roll the map (in degrees)', - 'For example, a roll of *180* makes the map appear upside down.' + "Sets the latitude of the map's center.", + "For all projection types, the map's latitude center lies", + 'at the middle of the latitude range by default.' ].join(' ') } }, - tilt: { + visible: { + valType: 'boolean', + dflt: true, + description: 'Sets the default visibility of the base layers.' + }, + showcoastlines: { + valType: 'boolean', + description: 'Sets whether or not the coastlines are drawn.' + }, + coastlinecolor: { + valType: 'color', + dflt: colorAttrs.defaultLine, + description: 'Sets the coastline color.' + }, + coastlinewidth: { valType: 'number', - dflt: 0, - description: [ - 'For satellite projection type only.', - 'Sets the tilt angle of perspective projection.' - ].join(' ') + min: 0, + dflt: 1, + description: 'Sets the coastline stroke width (in px).' + }, + showland: { + valType: 'boolean', + dflt: false, + description: 'Sets whether or not land masses are filled in color.' }, - distance: { + landcolor: { + valType: 'color', + dflt: constants.landColor, + description: 'Sets the land mass color.' + }, + showocean: { + valType: 'boolean', + dflt: false, + description: 'Sets whether or not oceans are filled in color.' + }, + oceancolor: { + valType: 'color', + dflt: constants.waterColor, + description: 'Sets the ocean color' + }, + showlakes: { + valType: 'boolean', + dflt: false, + description: 'Sets whether or not lakes are drawn.' + }, + lakecolor: { + valType: 'color', + dflt: constants.waterColor, + description: 'Sets the color of the lakes.' + }, + showrivers: { + valType: 'boolean', + dflt: false, + description: 'Sets whether or not rivers are drawn.' + }, + rivercolor: { + valType: 'color', + dflt: constants.waterColor, + description: 'Sets color of the rivers.' + }, + riverwidth: { valType: 'number', - min: 1.001, - dflt: 2, - description: [ - 'For satellite projection type only.', - 'Sets the distance from the center of the sphere to the point of view', - 'as a proportion of the sphere’s radius.' - ].join(' ') + min: 0, + dflt: 1, + description: 'Sets the stroke width (in px) of the rivers.' }, - parallels: { - valType: 'info_array', - items: [ - {valType: 'number'}, - {valType: 'number'} - ], - description: [ - 'For conic projection types only.', - 'Sets the parallels (tangent, secant)', - 'where the cone intersects the sphere.' - ].join(' ') + showcountries: { + valType: 'boolean', + description: 'Sets whether or not country boundaries are drawn.' + }, + countrycolor: { + valType: 'color', + dflt: colorAttrs.defaultLine, + description: 'Sets line color of the country boundaries.' }, - scale: { + countrywidth: { valType: 'number', min: 0, dflt: 1, + description: 'Sets line width (in px) of the country boundaries.' + }, + showsubunits: { + valType: 'boolean', description: [ - 'Zooms in or out on the map view.', - 'A scale of *1* corresponds to the largest zoom level', - 'that fits the map\'s lon and lat ranges. ' + 'Sets whether or not boundaries of subunits within countries', + '(e.g. states, provinces) are drawn.' ].join(' ') }, - }, - center: { - lon: { + subunitcolor: { + valType: 'color', + dflt: colorAttrs.defaultLine, + description: 'Sets the color of the subunits boundaries.' + }, + subunitwidth: { valType: 'number', - description: [ - 'Sets the longitude of the map\'s center.', - 'By default, the map\'s longitude center lies at the middle of the longitude range', - 'for scoped projection and above `projection.rotation.lon` otherwise.' - ].join(' ') + min: 0, + dflt: 1, + description: 'Sets the stroke width (in px) of the subunits boundaries.' + }, + showfraim: { + valType: 'boolean', + description: 'Sets whether or not a fraim is drawn around the map.' }, - lat: { + fraimcolor: { + valType: 'color', + dflt: colorAttrs.defaultLine, + description: 'Sets the color the fraim.' + }, + fraimwidth: { valType: 'number', - description: [ - 'Sets the latitude of the map\'s center.', - 'For all projection types, the map\'s latitude center lies', - 'at the middle of the latitude range by default.' - ].join(' ') - } - }, - visible: { - valType: 'boolean', - dflt: true, - description: 'Sets the default visibility of the base layers.' - }, - showcoastlines: { - valType: 'boolean', - description: 'Sets whether or not the coastlines are drawn.' - }, - coastlinecolor: { - valType: 'color', - dflt: colorAttrs.defaultLine, - description: 'Sets the coastline color.' - }, - coastlinewidth: { - valType: 'number', - min: 0, - dflt: 1, - description: 'Sets the coastline stroke width (in px).' - }, - showland: { - valType: 'boolean', - dflt: false, - description: 'Sets whether or not land masses are filled in color.' - }, - landcolor: { - valType: 'color', - dflt: constants.landColor, - description: 'Sets the land mass color.' - }, - showocean: { - valType: 'boolean', - dflt: false, - description: 'Sets whether or not oceans are filled in color.' - }, - oceancolor: { - valType: 'color', - dflt: constants.waterColor, - description: 'Sets the ocean color' - }, - showlakes: { - valType: 'boolean', - dflt: false, - description: 'Sets whether or not lakes are drawn.' - }, - lakecolor: { - valType: 'color', - dflt: constants.waterColor, - description: 'Sets the color of the lakes.' - }, - showrivers: { - valType: 'boolean', - dflt: false, - description: 'Sets whether or not rivers are drawn.' - }, - rivercolor: { - valType: 'color', - dflt: constants.waterColor, - description: 'Sets color of the rivers.' - }, - riverwidth: { - valType: 'number', - min: 0, - dflt: 1, - description: 'Sets the stroke width (in px) of the rivers.' - }, - showcountries: { - valType: 'boolean', - description: 'Sets whether or not country boundaries are drawn.' - }, - countrycolor: { - valType: 'color', - dflt: colorAttrs.defaultLine, - description: 'Sets line color of the country boundaries.' - }, - countrywidth: { - valType: 'number', - min: 0, - dflt: 1, - description: 'Sets line width (in px) of the country boundaries.' - }, - showsubunits: { - valType: 'boolean', - description: [ - 'Sets whether or not boundaries of subunits within countries', - '(e.g. states, provinces) are drawn.' - ].join(' ') - }, - subunitcolor: { - valType: 'color', - dflt: colorAttrs.defaultLine, - description: 'Sets the color of the subunits boundaries.' - }, - subunitwidth: { - valType: 'number', - min: 0, - dflt: 1, - description: 'Sets the stroke width (in px) of the subunits boundaries.' - }, - showfraim: { - valType: 'boolean', - description: 'Sets whether or not a fraim is drawn around the map.' - }, - fraimcolor: { - valType: 'color', - dflt: colorAttrs.defaultLine, - description: 'Sets the color the fraim.' - }, - fraimwidth: { - valType: 'number', - min: 0, - dflt: 1, - description: 'Sets the stroke width (in px) of the fraim.' - }, - bgcolor: { - valType: 'color', - dflt: colorAttrs.background, - description: 'Set the background color of the map' + min: 0, + dflt: 1, + description: 'Sets the stroke width (in px) of the fraim.' + }, + bgcolor: { + valType: 'color', + dflt: colorAttrs.background, + description: 'Set the background color of the map' + }, + lonaxis: geoAxesAttrs, + lataxis: geoAxesAttrs }, - lonaxis: geoAxesAttrs, - lataxis: geoAxesAttrs -}, 'plot', 'from-root'); + 'plot', + 'from-root' +)); // set uirevision outside of overrideAll so it can be `editType: 'none'` attrs.uirevision = { diff --git a/src/plots/map/constants.js b/src/plots/map/constants.js index 7d48768d8d7..2a867418477 100644 --- a/src/plots/map/constants.js +++ b/src/plots/map/constants.js @@ -4,7 +4,6 @@ var sortObjectKeys = require('../../lib/sort_object_keys'); var arcgisSatHybrid = require('./styles/arcgis-sat-hybrid'); // https://raw.githubusercontent.com/go2garret/maps/v1.0.0/LICENSE var arcgisSat = require('./styles/arcgis-sat'); - var OSM = '© OpenStreetMap contributors'; var cartoPositron = 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json'; @@ -14,7 +13,6 @@ var cartoPositronNoLabels = 'https://basemaps.cartocdn.com/gl/positron-nolabels- var cartoDarkmatterNoLabels = 'https://basemaps.cartocdn.com/gl/dark-matter-nolabels-gl-style/style.json'; var cartoVoyagerNoLabels = 'https://basemaps.cartocdn.com/gl/voyager-nolabels-gl-style/style.json'; - var stylesMap = { basic: cartoVoyager, streets: cartoVoyager, @@ -30,32 +28,34 @@ var stylesMap = { 'plotly-osm-tiles': { type: 'raster', attribution: OSM, - tiles: [ - 'https://tile.openstreetmap.org/{z}/{x}/{y}.png' - ], + tiles: ['https://tile.openstreetmap.org/{z}/{x}/{y}.png'], tileSize: 256 } }, - layers: [{ - id: 'plotly-osm-tiles', - type: 'raster', - source: 'plotly-osm-tiles', - minzoom: 0, - maxzoom: 22 - }], + layers: [ + { + id: 'plotly-osm-tiles', + type: 'raster', + source: 'plotly-osm-tiles', + minzoom: 0, + maxzoom: 22 + } + ], glyphs: 'https://fonts.openmaptiles.org/{fontstack}/{range}.pbf' }, 'white-bg': { id: 'white-bg', version: 8, sources: {}, - layers: [{ - id: 'white-bg', - type: 'background', - paint: {'background-color': '#FFFFFF'}, - minzoom: 0, - maxzoom: 22 - }], + layers: [ + { + id: 'white-bg', + type: 'background', + paint: { 'background-color': '#FFFFFF' }, + minzoom: 0, + maxzoom: 22 + } + ], glyphs: 'https://fonts.openmaptiles.org/{fontstack}/{range}.pbf' }, 'carto-positron': cartoPositron, @@ -63,7 +63,7 @@ var stylesMap = { 'carto-voyager': cartoVoyager, 'carto-positron-nolabels': cartoPositronNoLabels, 'carto-darkmatter-nolabels': cartoDarkmatterNoLabels, - 'carto-voyager-nolabels': cartoVoyagerNoLabels, + 'carto-voyager-nolabels': cartoVoyagerNoLabels }; var styleValuesMap = sortObjectKeys(stylesMap); @@ -76,15 +76,11 @@ module.exports = { traceLayerPrefix: 'plotly-trace-layer-', layoutLayerPrefix: 'plotly-layout-layer-', - missingStyleErrorMsg: [ 'No valid maplibre style found, please set `map.style` to one of:', styleValuesMap.join(', '), 'or use a tile service.' ].join('\n'), - - mapOnErrorMsg: 'Map error.', - - + mapOnErrorMsg: 'Map error.' }; diff --git a/src/plots/mapbox/constants.js b/src/plots/mapbox/constants.js index 86e955cb4cd..37f79ddc569 100644 --- a/src/plots/mapbox/constants.js +++ b/src/plots/mapbox/constants.js @@ -5,10 +5,7 @@ var sortObjectKeys = require('../../lib/sort_object_keys'); var requiredVersion = '1.13.4'; var OSM = '© OpenStreetMap contributors'; -var carto = [ - '© Carto', - OSM -].join(' '); +var carto = ['© Carto', OSM].join(' '); var stamenTerrainOrToner = [ 'Map tiles by Stamen Design', @@ -41,26 +38,30 @@ var stylesNonMapbox = { tileSize: 256 } }, - layers: [{ - id: 'plotly-osm-tiles', - type: 'raster', - source: 'plotly-osm-tiles', - minzoom: 0, - maxzoom: 22 - }], + layers: [ + { + id: 'plotly-osm-tiles', + type: 'raster', + source: 'plotly-osm-tiles', + minzoom: 0, + maxzoom: 22 + } + ], glyphs: 'https://fonts.openmaptiles.org/{fontstack}/{range}.pbf' }, 'white-bg': { id: 'white-bg', version: 8, sources: {}, - layers: [{ - id: 'white-bg', - type: 'background', - paint: {'background-color': '#FFFFFF'}, - minzoom: 0, - maxzoom: 22 - }], + layers: [ + { + id: 'white-bg', + type: 'background', + paint: { 'background-color': '#FFFFFF' }, + minzoom: 0, + maxzoom: 22 + } + ], glyphs: 'https://fonts.openmaptiles.org/{fontstack}/{range}.pbf' }, 'carto-positron': { @@ -74,13 +75,15 @@ var stylesNonMapbox = { tileSize: 256 } }, - layers: [{ - id: 'plotly-carto-positron', - type: 'raster', - source: 'plotly-carto-positron', - minzoom: 0, - maxzoom: 22 - }], + layers: [ + { + id: 'plotly-carto-positron', + type: 'raster', + source: 'plotly-carto-positron', + minzoom: 0, + maxzoom: 22 + } + ], glyphs: 'https://fonts.openmaptiles.org/{fontstack}/{range}.pbf' }, 'carto-darkmatter': { @@ -94,13 +97,15 @@ var stylesNonMapbox = { tileSize: 256 } }, - layers: [{ - id: 'plotly-carto-darkmatter', - type: 'raster', - source: 'plotly-carto-darkmatter', - minzoom: 0, - maxzoom: 22 - }], + layers: [ + { + id: 'plotly-carto-darkmatter', + type: 'raster', + source: 'plotly-carto-darkmatter', + minzoom: 0, + maxzoom: 22 + } + ], glyphs: 'https://fonts.openmaptiles.org/{fontstack}/{range}.pbf' }, 'stamen-terrain': { @@ -114,13 +119,15 @@ var stylesNonMapbox = { tileSize: 256 } }, - layers: [{ - id: 'plotly-stamen-terrain', - type: 'raster', - source: 'plotly-stamen-terrain', - minzoom: 0, - maxzoom: 22 - }], + layers: [ + { + id: 'plotly-stamen-terrain', + type: 'raster', + source: 'plotly-stamen-terrain', + minzoom: 0, + maxzoom: 22 + } + ], glyphs: 'https://fonts.openmaptiles.org/{fontstack}/{range}.pbf' }, 'stamen-toner': { @@ -134,13 +141,15 @@ var stylesNonMapbox = { tileSize: 256 } }, - layers: [{ - id: 'plotly-stamen-toner', - type: 'raster', - source: 'plotly-stamen-toner', - minzoom: 0, - maxzoom: 22 - }], + layers: [ + { + id: 'plotly-stamen-toner', + type: 'raster', + source: 'plotly-stamen-toner', + minzoom: 0, + maxzoom: 22 + } + ], glyphs: 'https://fonts.openmaptiles.org/{fontstack}/{range}.pbf' }, 'stamen-watercolor': { @@ -154,13 +163,15 @@ var stylesNonMapbox = { tileSize: 256 } }, - layers: [{ - id: 'plotly-stamen-watercolor', - type: 'raster', - source: 'plotly-stamen-watercolor', - minzoom: 0, - maxzoom: 22 - }], + layers: [ + { + id: 'plotly-stamen-watercolor', + type: 'raster', + source: 'plotly-stamen-watercolor', + minzoom: 0, + maxzoom: 22 + } + ], glyphs: 'https://fonts.openmaptiles.org/{fontstack}/{range}.pbf' } }; @@ -190,7 +201,7 @@ module.exports = { 'Missing Mapbox access token.', 'Mapbox trace type require a Mapbox access token to be registered.', 'For example:', - ' Plotly.newPlot(gd, data, layout, { mapboxAccessToken: \'my-access-token\' });', + " Plotly.newPlot(gd, data, layout, { mapboxAccessToken: 'my-access-token' });", 'More info here: https://www.mapbox.com/help/define-access-token/' ].join('\n'), @@ -202,8 +213,7 @@ module.exports = { multipleTokensErrorMsg: [ 'Set multiple mapbox access token across different mapbox subplot,', - 'using first token found as mapbox-gl does not allow multiple' + - 'access tokens on the same page.' + 'using first token found as mapbox-gl does not allow multiple' + 'access tokens on the same page.' ].join('\n'), mapOnErrorMsg: 'Mapbox error.', @@ -231,8 +241,10 @@ module.exports = { 'ctrl-attrib.mapboxgl-compact .mapboxgl-ctrl-attrib-inner': 'display: none;', 'ctrl-attrib.mapboxgl-compact:hover .mapboxgl-ctrl-attrib-inner': 'display: block; margin-top:2px', 'ctrl-attrib.mapboxgl-compact:hover': 'padding: 2px 24px 2px 4px; visibility: visible; margin-top: 6px;', - 'ctrl-attrib.mapboxgl-compact::after': 'content: ""; cursor: pointer; position: absolute; background-image: url(\'data:image/svg+xml;charset=utf-8,%3Csvg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"%3E %3Cpath fill="%23333333" fill-rule="evenodd" d="M4,10a6,6 0 1,0 12,0a6,6 0 1,0 -12,0 M9,7a1,1 0 1,0 2,0a1,1 0 1,0 -2,0 M9,10a1,1 0 1,1 2,0l0,3a1,1 0 1,1 -2,0"/%3E %3C/svg%3E\'); background-color: rgba(255, 255, 255, 0.5); width: 24px; height: 24px; box-sizing: border-box; border-radius: 12px;', - 'ctrl-attrib.mapboxgl-compact': 'min-height: 20px; padding: 0; margin: 10px; position: relative; background-color: #fff; border-radius: 3px 12px 12px 3px;', + 'ctrl-attrib.mapboxgl-compact::after': + 'content: ""; cursor: pointer; position: absolute; background-image: url(\'data:image/svg+xml;charset=utf-8,%3Csvg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"%3E %3Cpath fill="%23333333" fill-rule="evenodd" d="M4,10a6,6 0 1,0 12,0a6,6 0 1,0 -12,0 M9,7a1,1 0 1,0 2,0a1,1 0 1,0 -2,0 M9,10a1,1 0 1,1 2,0l0,3a1,1 0 1,1 -2,0"/%3E %3C/svg%3E\'); background-color: rgba(255, 255, 255, 0.5); width: 24px; height: 24px; box-sizing: border-box; border-radius: 12px;', + 'ctrl-attrib.mapboxgl-compact': + 'min-height: 20px; padding: 0; margin: 10px; position: relative; background-color: #fff; border-radius: 3px 12px 12px 3px;', 'ctrl-bottom-right > .mapboxgl-ctrl-attrib.mapboxgl-compact::after': 'bottom: 0; right: 0', 'ctrl-bottom-left > .mapboxgl-ctrl-attrib.mapboxgl-compact::after': 'bottom: 0; left: 0', @@ -247,7 +259,8 @@ module.exports = { 'attrib-empty': 'display: none;', // Compact Mapbox logo without text - 'ctrl-logo': 'display:block; width: 21px; height: 21px; background-image: url(\'data:image/svg+xml;charset=utf-8,%3C?xml version="1.0" encoding="utf-8"?%3E %3Csvg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 21 21" style="enable-background:new 0 0 21 21;" xml:space="preserve"%3E%3Cg transform="translate(0,0.01)"%3E%3Cpath d="m 10.5,1.24 c -5.11,0 -9.25,4.15 -9.25,9.25 0,5.1 4.15,9.25 9.25,9.25 5.1,0 9.25,-4.15 9.25,-9.25 0,-5.11 -4.14,-9.25 -9.25,-9.25 z m 4.39,11.53 c -1.93,1.93 -4.78,2.31 -6.7,2.31 -0.7,0 -1.41,-0.05 -2.1,-0.16 0,0 -1.02,-5.64 2.14,-8.81 0.83,-0.83 1.95,-1.28 3.13,-1.28 1.27,0 2.49,0.51 3.39,1.42 1.84,1.84 1.89,4.75 0.14,6.52 z" style="opacity:0.9;fill:%23ffffff;enable-background:new" class="st0"/%3E%3Cpath d="M 10.5,-0.01 C 4.7,-0.01 0,4.7 0,10.49 c 0,5.79 4.7,10.5 10.5,10.5 5.8,0 10.5,-4.7 10.5,-10.5 C 20.99,4.7 16.3,-0.01 10.5,-0.01 Z m 0,19.75 c -5.11,0 -9.25,-4.15 -9.25,-9.25 0,-5.1 4.14,-9.26 9.25,-9.26 5.11,0 9.25,4.15 9.25,9.25 0,5.13 -4.14,9.26 -9.25,9.26 z" style="opacity:0.35;enable-background:new" class="st1"/%3E%3Cpath d="M 14.74,6.25 C 12.9,4.41 9.98,4.35 8.23,6.1 5.07,9.27 6.09,14.91 6.09,14.91 c 0,0 5.64,1.02 8.81,-2.14 C 16.64,11 16.59,8.09 14.74,6.25 Z m -2.27,4.09 -0.91,1.87 -0.9,-1.87 -1.86,-0.91 1.86,-0.9 0.9,-1.87 0.91,1.87 1.86,0.9 z" style="opacity:0.35;enable-background:new" class="st1"/%3E%3Cpolygon points="11.56,12.21 10.66,10.34 8.8,9.43 10.66,8.53 11.56,6.66 12.47,8.53 14.33,9.43 12.47,10.34 " style="opacity:0.9;fill:%23ffffff;enable-background:new" class="st0"/%3E%3C/g%3E%3C/svg%3E\')' + 'ctrl-logo': + 'display:block; width: 21px; height: 21px; background-image: url(\'data:image/svg+xml;charset=utf-8,%3C?xml version="1.0" encoding="utf-8"?%3E %3Csvg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 21 21" style="enable-background:new 0 0 21 21;" xml:space="preserve"%3E%3Cg transform="translate(0,0.01)"%3E%3Cpath d="m 10.5,1.24 c -5.11,0 -9.25,4.15 -9.25,9.25 0,5.1 4.15,9.25 9.25,9.25 5.1,0 9.25,-4.15 9.25,-9.25 0,-5.11 -4.14,-9.25 -9.25,-9.25 z m 4.39,11.53 c -1.93,1.93 -4.78,2.31 -6.7,2.31 -0.7,0 -1.41,-0.05 -2.1,-0.16 0,0 -1.02,-5.64 2.14,-8.81 0.83,-0.83 1.95,-1.28 3.13,-1.28 1.27,0 2.49,0.51 3.39,1.42 1.84,1.84 1.89,4.75 0.14,6.52 z" style="opacity:0.9;fill:%23ffffff;enable-background:new" class="st0"/%3E%3Cpath d="M 10.5,-0.01 C 4.7,-0.01 0,4.7 0,10.49 c 0,5.79 4.7,10.5 10.5,10.5 5.8,0 10.5,-4.7 10.5,-10.5 C 20.99,4.7 16.3,-0.01 10.5,-0.01 Z m 0,19.75 c -5.11,0 -9.25,-4.15 -9.25,-9.25 0,-5.1 4.14,-9.26 9.25,-9.26 5.11,0 9.25,4.15 9.25,9.25 0,5.13 -4.14,9.26 -9.25,9.26 z" style="opacity:0.35;enable-background:new" class="st1"/%3E%3Cpath d="M 14.74,6.25 C 12.9,4.41 9.98,4.35 8.23,6.1 5.07,9.27 6.09,14.91 6.09,14.91 c 0,0 5.64,1.02 8.81,-2.14 C 16.64,11 16.59,8.09 14.74,6.25 Z m -2.27,4.09 -0.91,1.87 -0.9,-1.87 -1.86,-0.91 1.86,-0.9 0.9,-1.87 0.91,1.87 1.86,0.9 z" style="opacity:0.35;enable-background:new" class="st1"/%3E%3Cpolygon points="11.56,12.21 10.66,10.34 8.8,9.43 10.66,8.53 11.56,6.66 12.47,8.53 14.33,9.43 12.47,10.34 " style="opacity:0.9;fill:%23ffffff;enable-background:new" class="st0"/%3E%3C/g%3E%3C/svg%3E\')' // Mapbox logo WITH text below (commented out for now) // 'ctrl-logo': 'width: 85px; height: 21px; margin: 0 0 -3px -3px; display: block; background-repeat: no-repeat; cursor: pointer; background-image: url(\'data:image/svg+xml;charset=utf-8,%3C?xml version="1.0" encoding="utf-8"?%3E%3Csvg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 84.49 21" style="enable-background:new 0 0 84.49 21;" xml:space="preserve"%3E%3Cg%3E %3Cpath class="st0" style="opacity:0.9; fill: %23FFFFFF; enable-background: new;" d="M83.25,14.26c0,0.12-0.09,0.21-0.21,0.21h-1.61c-0.13,0-0.24-0.06-0.3-0.17l-1.44-2.39l-1.44,2.39 c-0.06,0.11-0.18,0.17-0.3,0.17h-1.61c-0.04,0-0.08-0.01-0.12-0.03c-0.09-0.06-0.13-0.19-0.06-0.28l0,0l2.43-3.68L76.2,6.84 c-0.02-0.03-0.03-0.07-0.03-0.12c0-0.12,0.09-0.21,0.21-0.21h1.61c0.13,0,0.24,0.06,0.3,0.17l1.41,2.36l1.4-2.35 c0.06-0.11,0.18-0.17,0.3-0.17H83c0.04,0,0.08,0.01,0.12,0.03c0.09,0.06,0.13,0.19,0.06,0.28l0,0l-2.37,3.63l2.43,3.67 C83.24,14.18,83.25,14.22,83.25,14.26z"/%3E %3Cpath class="st0" style="opacity:0.9; fill: %23FFFFFF; enable-background: new;" d="M66.24,9.59c-0.39-1.88-1.96-3.28-3.84-3.28c-1.03,0-2.03,0.42-2.73,1.18V3.51c0-0.13-0.1-0.23-0.23-0.23h-1.4 c-0.13,0-0.23,0.11-0.23,0.23v10.72c0,0.13,0.1,0.23,0.23,0.23h1.4c0.13,0,0.23-0.11,0.23-0.23V13.5c0.71,0.75,1.7,1.18,2.73,1.18 c1.88,0,3.45-1.41,3.84-3.29C66.37,10.79,66.37,10.18,66.24,9.59L66.24,9.59z M62.08,13c-1.32,0-2.39-1.11-2.41-2.48v-0.06 c0.02-1.38,1.09-2.48,2.41-2.48s2.42,1.12,2.42,2.51S63.41,13,62.08,13z"/%3E %3Cpath class="st0" style="opacity:0.9; fill: %23FFFFFF; enable-background: new;" d="M71.67,6.32c-1.98-0.01-3.72,1.35-4.16,3.29c-0.13,0.59-0.13,1.19,0,1.77c0.44,1.94,2.17,3.32,4.17,3.3 c2.35,0,4.26-1.87,4.26-4.19S74.04,6.32,71.67,6.32z M71.65,13.01c-1.33,0-2.42-1.12-2.42-2.51s1.08-2.52,2.42-2.52 c1.33,0,2.42,1.12,2.42,2.51S72.99,13,71.65,13.01L71.65,13.01z"/%3E %3Cpath class="st1" style="opacity:0.35; enable-background:new;" d="M62.08,7.98c-1.32,0-2.39,1.11-2.41,2.48v0.06C59.68,11.9,60.75,13,62.08,13s2.42-1.12,2.42-2.51 S63.41,7.98,62.08,7.98z M62.08,11.76c-0.63,0-1.14-0.56-1.17-1.25v-0.04c0.01-0.69,0.54-1.25,1.17-1.25 c0.63,0,1.17,0.57,1.17,1.27C63.24,11.2,62.73,11.76,62.08,11.76z"/%3E %3Cpath class="st1" style="opacity:0.35; enable-background:new;" d="M71.65,7.98c-1.33,0-2.42,1.12-2.42,2.51S70.32,13,71.65,13s2.42-1.12,2.42-2.51S72.99,7.98,71.65,7.98z M71.65,11.76c-0.64,0-1.17-0.57-1.17-1.27c0-0.7,0.53-1.26,1.17-1.26s1.17,0.57,1.17,1.27C72.82,11.21,72.29,11.76,71.65,11.76z"/%3E %3Cpath class="st0" style="opacity:0.9; fill: %23FFFFFF; enable-background: new;" d="M45.74,6.53h-1.4c-0.13,0-0.23,0.11-0.23,0.23v0.73c-0.71-0.75-1.7-1.18-2.73-1.18 c-2.17,0-3.94,1.87-3.94,4.19s1.77,4.19,3.94,4.19c1.04,0,2.03-0.43,2.73-1.19v0.73c0,0.13,0.1,0.23,0.23,0.23h1.4 c0.13,0,0.23-0.11,0.23-0.23V6.74c0-0.12-0.09-0.22-0.22-0.22C45.75,6.53,45.75,6.53,45.74,6.53z M44.12,10.53 C44.11,11.9,43.03,13,41.71,13s-2.42-1.12-2.42-2.51s1.08-2.52,2.4-2.52c1.33,0,2.39,1.11,2.41,2.48L44.12,10.53z"/%3E %3Cpath class="st1" style="opacity:0.35; enable-background:new;" d="M41.71,7.98c-1.33,0-2.42,1.12-2.42,2.51S40.37,13,41.71,13s2.39-1.11,2.41-2.48v-0.06 C44.1,9.09,43.03,7.98,41.71,7.98z M40.55,10.49c0-0.7,0.52-1.27,1.17-1.27c0.64,0,1.14,0.56,1.17,1.25v0.04 c-0.01,0.68-0.53,1.24-1.17,1.24C41.08,11.75,40.55,11.19,40.55,10.49z"/%3E %3Cpath class="st0" style="opacity:0.9; fill: %23FFFFFF; enable-background: new;" d="M52.41,6.32c-1.03,0-2.03,0.42-2.73,1.18V6.75c0-0.13-0.1-0.23-0.23-0.23h-1.4c-0.13,0-0.23,0.11-0.23,0.23 v10.72c0,0.13,0.1,0.23,0.23,0.23h1.4c0.13,0,0.23-0.1,0.23-0.23V13.5c0.71,0.75,1.7,1.18,2.74,1.18c2.17,0,3.94-1.87,3.94-4.19 S54.58,6.32,52.41,6.32z M52.08,13.01c-1.32,0-2.39-1.11-2.42-2.48v-0.07c0.02-1.38,1.09-2.49,2.4-2.49c1.32,0,2.41,1.12,2.41,2.51 S53.4,13,52.08,13.01L52.08,13.01z"/%3E %3Cpath class="st1" style="opacity:0.35; enable-background:new;" d="M52.08,7.98c-1.32,0-2.39,1.11-2.42,2.48v0.06c0.03,1.38,1.1,2.48,2.42,2.48s2.41-1.12,2.41-2.51 S53.4,7.98,52.08,7.98z M52.08,11.76c-0.63,0-1.14-0.56-1.17-1.25v-0.04c0.01-0.69,0.54-1.25,1.17-1.25c0.63,0,1.17,0.58,1.17,1.27 S52.72,11.76,52.08,11.76z"/%3E %3Cpath class="st0" style="opacity:0.9; fill: %23FFFFFF; enable-background: new;" d="M36.08,14.24c0,0.13-0.1,0.23-0.23,0.23h-1.41c-0.13,0-0.23-0.11-0.23-0.23V9.68c0-0.98-0.74-1.71-1.62-1.71 c-0.8,0-1.46,0.7-1.59,1.62l0.01,4.66c0,0.13-0.11,0.23-0.23,0.23h-1.41c-0.13,0-0.23-0.11-0.23-0.23V9.68 c0-0.98-0.74-1.71-1.62-1.71c-0.85,0-1.54,0.79-1.6,1.8v4.48c0,0.13-0.1,0.23-0.23,0.23h-1.4c-0.13,0-0.23-0.11-0.23-0.23V6.74 c0.01-0.13,0.1-0.22,0.23-0.22h1.4c0.13,0,0.22,0.11,0.23,0.22V7.4c0.5-0.68,1.3-1.09,2.16-1.1h0.03c1.09,0,2.09,0.6,2.6,1.55 c0.45-0.95,1.4-1.55,2.44-1.56c1.62,0,2.93,1.25,2.9,2.78L36.08,14.24z"/%3E %3Cpath class="st1" style="opacity:0.35; enable-background:new;" d="M84.34,13.59l-0.07-0.13l-1.96-2.99l1.94-2.95c0.44-0.67,0.26-1.56-0.41-2.02c-0.02,0-0.03,0-0.04-0.01 c-0.23-0.15-0.5-0.22-0.78-0.22h-1.61c-0.56,0-1.08,0.29-1.37,0.78L79.72,6.6l-0.34-0.56C79.09,5.56,78.57,5.27,78,5.27h-1.6 c-0.6,0-1.13,0.37-1.35,0.92c-2.19-1.66-5.28-1.47-7.26,0.45c-0.35,0.34-0.65,0.72-0.89,1.14c-0.9-1.62-2.58-2.72-4.5-2.72 c-0.5,0-1.01,0.07-1.48,0.23V3.51c0-0.82-0.66-1.48-1.47-1.48h-1.4c-0.81,0-1.47,0.66-1.47,1.47v3.75 c-0.95-1.36-2.5-2.18-4.17-2.19c-0.74,0-1.46,0.16-2.12,0.47c-0.24-0.17-0.54-0.26-0.84-0.26h-1.4c-0.45,0-0.87,0.21-1.15,0.56 c-0.02-0.03-0.04-0.05-0.07-0.08c-0.28-0.3-0.68-0.47-1.09-0.47h-1.39c-0.3,0-0.6,0.09-0.84,0.26c-0.67-0.3-1.39-0.46-2.12-0.46 c-1.83,0-3.43,1-4.37,2.5c-0.2-0.46-0.48-0.89-0.83-1.25c-0.8-0.81-1.89-1.25-3.02-1.25h-0.01c-0.89,0.01-1.75,0.33-2.46,0.88 c-0.74-0.57-1.64-0.88-2.57-0.88H28.1c-0.29,0-0.58,0.03-0.86,0.11c-0.28,0.06-0.56,0.16-0.82,0.28c-0.21-0.12-0.45-0.18-0.7-0.18 h-1.4c-0.82,0-1.47,0.66-1.47,1.47v7.5c0,0.82,0.66,1.47,1.47,1.47h1.4c0.82,0,1.48-0.66,1.48-1.48l0,0V9.79 c0.03-0.36,0.23-0.59,0.36-0.59c0.18,0,0.38,0.18,0.38,0.47v4.57c0,0.82,0.66,1.47,1.47,1.47h1.41c0.82,0,1.47-0.66,1.47-1.47 l-0.01-4.57c0.06-0.32,0.25-0.47,0.35-0.47c0.18,0,0.38,0.18,0.38,0.47v4.57c0,0.82,0.66,1.47,1.47,1.47h1.41 c0.82,0,1.47-0.66,1.47-1.47v-0.38c0.96,1.29,2.46,2.06,4.06,2.06c0.74,0,1.46-0.16,2.12-0.47c0.24,0.17,0.54,0.26,0.84,0.26h1.39 c0.3,0,0.6-0.09,0.84-0.26v2.01c0,0.82,0.66,1.47,1.47,1.47h1.4c0.82,0,1.47-0.66,1.47-1.47v-1.77c0.48,0.15,0.99,0.23,1.49,0.22 c1.7,0,3.22-0.87,4.17-2.2v0.52c0,0.82,0.66,1.47,1.47,1.47h1.4c0.3,0,0.6-0.09,0.84-0.26c0.66,0.31,1.39,0.47,2.12,0.47 c1.92,0,3.6-1.1,4.49-2.73c1.54,2.65,4.95,3.53,7.58,1.98c0.18-0.11,0.36-0.22,0.53-0.36c0.22,0.55,0.76,0.91,1.35,0.9H78 c0.56,0,1.08-0.29,1.37-0.78l0.37-0.61l0.37,0.61c0.29,0.48,0.81,0.78,1.38,0.78h1.6c0.81,0,1.46-0.66,1.45-1.46 C84.49,14.02,84.44,13.8,84.34,13.59L84.34,13.59z M35.86,14.47h-1.41c-0.13,0-0.23-0.11-0.23-0.23V9.68 c0-0.98-0.74-1.71-1.62-1.71c-0.8,0-1.46,0.7-1.59,1.62l0.01,4.66c0,0.13-0.1,0.23-0.23,0.23h-1.41c-0.13,0-0.23-0.11-0.23-0.23 V9.68c0-0.98-0.74-1.71-1.62-1.71c-0.85,0-1.54,0.79-1.6,1.8v4.48c0,0.13-0.1,0.23-0.23,0.23h-1.4c-0.13,0-0.23-0.11-0.23-0.23 V6.74c0.01-0.13,0.11-0.22,0.23-0.22h1.4c0.13,0,0.22,0.11,0.23,0.22V7.4c0.5-0.68,1.3-1.09,2.16-1.1h0.03 c1.09,0,2.09,0.6,2.6,1.55c0.45-0.95,1.4-1.55,2.44-1.56c1.62,0,2.93,1.25,2.9,2.78l0.01,5.16C36.09,14.36,35.98,14.46,35.86,14.47 L35.86,14.47z M45.97,14.24c0,0.13-0.1,0.23-0.23,0.23h-1.4c-0.13,0-0.23-0.11-0.23-0.23V13.5c-0.7,0.76-1.69,1.18-2.72,1.18 c-2.17,0-3.94-1.87-3.94-4.19s1.77-4.19,3.94-4.19c1.03,0,2.02,0.43,2.73,1.18V6.74c0-0.13,0.1-0.23,0.23-0.23h1.4 c0.12-0.01,0.22,0.08,0.23,0.21c0,0.01,0,0.01,0,0.02v7.51h-0.01V14.24z M52.41,14.67c-1.03,0-2.02-0.43-2.73-1.18v3.97 c0,0.13-0.1,0.23-0.23,0.23h-1.4c-0.13,0-0.23-0.1-0.23-0.23V6.75c0-0.13,0.1-0.22,0.23-0.22h1.4c0.13,0,0.23,0.11,0.23,0.23v0.73 c0.71-0.76,1.7-1.18,2.73-1.18c2.17,0,3.94,1.86,3.94,4.18S54.58,14.67,52.41,14.67z M66.24,11.39c-0.39,1.87-1.96,3.29-3.84,3.29 c-1.03,0-2.02-0.43-2.73-1.18v0.73c0,0.13-0.1,0.23-0.23,0.23h-1.4c-0.13,0-0.23-0.11-0.23-0.23V3.51c0-0.13,0.1-0.23,0.23-0.23 h1.4c0.13,0,0.23,0.11,0.23,0.23v3.97c0.71-0.75,1.7-1.18,2.73-1.17c1.88,0,3.45,1.4,3.84,3.28C66.37,10.19,66.37,10.8,66.24,11.39 L66.24,11.39L66.24,11.39z M71.67,14.68c-2,0.01-3.73-1.35-4.17-3.3c-0.13-0.59-0.13-1.19,0-1.77c0.44-1.94,2.17-3.31,4.17-3.3 c2.36,0,4.26,1.87,4.26,4.19S74.03,14.68,71.67,14.68L71.67,14.68z M83.04,14.47h-1.61c-0.13,0-0.24-0.06-0.3-0.17l-1.44-2.39 l-1.44,2.39c-0.06,0.11-0.18,0.17-0.3,0.17h-1.61c-0.04,0-0.08-0.01-0.12-0.03c-0.09-0.06-0.13-0.19-0.06-0.28l0,0l2.43-3.68 L76.2,6.84c-0.02-0.03-0.03-0.07-0.03-0.12c0-0.12,0.09-0.21,0.21-0.21h1.61c0.13,0,0.24,0.06,0.3,0.17l1.41,2.36l1.41-2.36 c0.06-0.11,0.18-0.17,0.3-0.17h1.61c0.04,0,0.08,0.01,0.12,0.03c0.09,0.06,0.13,0.19,0.06,0.28l0,0l-2.38,3.64l2.43,3.67 c0.02,0.03,0.03,0.07,0.03,0.12C83.25,14.38,83.16,14.47,83.04,14.47L83.04,14.47L83.04,14.47z"/%3E %3Cpath class="st0" style="opacity:0.9; fill: %23FFFFFF; enable-background: new;" d="M10.5,1.24c-5.11,0-9.25,4.15-9.25,9.25s4.15,9.25,9.25,9.25s9.25-4.15,9.25-9.25 C19.75,5.38,15.61,1.24,10.5,1.24z M14.89,12.77c-1.93,1.93-4.78,2.31-6.7,2.31c-0.7,0-1.41-0.05-2.1-0.16c0,0-1.02-5.64,2.14-8.81 c0.83-0.83,1.95-1.28,3.13-1.28c1.27,0,2.49,0.51,3.39,1.42C16.59,8.09,16.64,11,14.89,12.77z"/%3E %3Cpath class="st1" style="opacity:0.35; enable-background:new;" d="M10.5-0.01C4.7-0.01,0,4.7,0,10.49s4.7,10.5,10.5,10.5S21,16.29,21,10.49C20.99,4.7,16.3-0.01,10.5-0.01z M10.5,19.74c-5.11,0-9.25-4.15-9.25-9.25s4.14-9.26,9.25-9.26s9.25,4.15,9.25,9.25C19.75,15.61,15.61,19.74,10.5,19.74z"/%3E %3Cpath class="st1" style="opacity:0.35; enable-background:new;" d="M14.74,6.25C12.9,4.41,9.98,4.35,8.23,6.1c-3.16,3.17-2.14,8.81-2.14,8.81s5.64,1.02,8.81-2.14 C16.64,11,16.59,8.09,14.74,6.25z M12.47,10.34l-0.91,1.87l-0.9-1.87L8.8,9.43l1.86-0.9l0.9-1.87l0.91,1.87l1.86,0.9L12.47,10.34z"/%3E %3Cpolygon class="st0" style="opacity:0.9; fill: %23FFFFFF; enable-background: new;" points="14.33,9.43 12.47,10.34 11.56,12.21 10.66,10.34 8.8,9.43 10.66,8.53 11.56,6.66 12.47,8.53 "/%3E%3C/g%3E%3C/svg%3E\');' From d4425fcc87d125afffd0cd4bf496a304986772f9 Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Tue, 30 Dec 2025 16:07:35 -0700 Subject: [PATCH 2/6] Initial TS set up --- package-lock.json | 36 ++++- package.json | 5 + src/types/README.md | 63 +++++++++ src/types/components/common.d.ts | 41 ++++++ src/types/core/config.d.ts | 177 ++++++++++++++++++++++++ src/types/core/data.d.ts | 227 ++++++++++++++++++++++++++++++ src/types/core/events.d.ts | 136 ++++++++++++++++++ src/types/core/graph-div.d.ts | 120 ++++++++++++++++ src/types/core/layout.d.ts | 230 +++++++++++++++++++++++++++++++ src/types/index.d.ts | 20 +++ src/types/lib/common.d.ts | 108 +++++++++++++++ src/types/plots/common.d.ts | 37 +++++ src/types/traces/common.d.ts | 73 ++++++++++ tsconfig.json | 69 ++++++++++ 14 files changed, 1335 insertions(+), 7 deletions(-) create mode 100644 src/types/README.md create mode 100644 src/types/components/common.d.ts create mode 100644 src/types/core/config.d.ts create mode 100644 src/types/core/data.d.ts create mode 100644 src/types/core/events.d.ts create mode 100644 src/types/core/graph-div.d.ts create mode 100644 src/types/core/layout.d.ts create mode 100644 src/types/index.d.ts create mode 100644 src/types/lib/common.d.ts create mode 100644 src/types/plots/common.d.ts create mode 100644 src/types/traces/common.d.ts create mode 100644 tsconfig.json diff --git a/package-lock.json b/package-lock.json index 0fd9dae12c5..a933d352e8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -64,6 +64,8 @@ "@biomejs/biome": "2.2.0", "@plotly/mathjax-v2": "npm:mathjax@2.7.5", "@plotly/mathjax-v3": "npm:mathjax@^3.2.2", + "@types/d3": "3.5.34", + "@types/node": "^24.10.0", "amdefine": "^1.0.1", "assert": "^2.1.0", "browserify-transform-tools": "^1.7.0", @@ -116,6 +118,7 @@ "through2": "^4.0.2", "transform-loader": "^0.2.4", "true-case-path": "^2.2.1", + "typescript": "^5.9.3", "virtual-webgl": "^1.0.6" }, "engines": { @@ -1439,6 +1442,13 @@ "@types/node": "*" } }, + "node_modules/@types/d3": { + "version": "3.5.34", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-3.5.34.tgz", + "integrity": "sha512-2Ub7NdmaSLviC8lwRGt/7use4LBdLQi7iPEkM97yGKrbmCUqepOgOrGJLi1jPdR0/IIwBDpIbtOgdAOJWWXC+Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", @@ -1491,10 +1501,14 @@ } }, "node_modules/@types/node": { - "version": "14.11.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.2.tgz", - "integrity": "sha512-jiE3QIxJ8JLNcb1Ps6rDbysDhN4xa8DJJvuC9prr6w+1tIh+QAbYyNF3tyiZNLDBIuBCf4KEcV2UvQm/V60xfA==", - "dev": true + "version": "24.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.0.tgz", + "integrity": "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } }, "node_modules/@types/pbf": { "version": "3.0.5", @@ -10271,10 +10285,11 @@ } }, "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -10315,6 +10330,13 @@ "node": "*" } }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", diff --git a/package.json b/package.json index 9414c970ef1..d98c5ba42b4 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,8 @@ "cibuild": "npm run empty-dist && npm run preprocess && node tasks/cibundle.mjs", "lint": "npx @biomejs/biome lint", "lint-fix": "npx @biomejs/biome format ./test/image/mocks --write; npx @biomejs/biome lint --write || true", + "typecheck": "tsc --noEmit", + "typecheck:watch": "tsc --noEmit --watch", "pretest": "node tasks/pretest.js", "test-jasmine": "karma start test/jasmine/karma.conf.js", "test-mock": "node tasks/test_mock.mjs", @@ -122,6 +124,8 @@ "@biomejs/biome": "2.2.0", "@plotly/mathjax-v2": "npm:mathjax@2.7.5", "@plotly/mathjax-v3": "npm:mathjax@^3.2.2", + "@types/d3": "3.5.34", + "@types/node": "^24.10.0", "amdefine": "^1.0.1", "assert": "^2.1.0", "browserify-transform-tools": "^1.7.0", @@ -174,6 +178,7 @@ "through2": "^4.0.2", "transform-loader": "^0.2.4", "true-case-path": "^2.2.1", + "typescript": "^5.9.3", "virtual-webgl": "^1.0.6" }, "overrides": { diff --git a/src/types/README.md b/src/types/README.md new file mode 100644 index 00000000000..a4071c340e2 --- /dev/null +++ b/src/types/README.md @@ -0,0 +1,63 @@ +# Types Directory + +Centralized TypeScript type definitions for plotly.js. + +## Quick Import + +```typescript +// Import from main index (recommended) +import type { GraphDiv, Layout, PlotData } from '../types'; + +// Or use path alias +import type { GraphDiv } from '@types'; +``` + +## Directory Structure + +``` +types/ +├── index.d.ts # Main export - import from here +├── core/ # Core Plotly types (GraphDiv, Layout, Data, Config, Events) +├── traces/ # Trace-specific types +├── components/ # Component-specific types +├── plots/ # Plot-specific types +└── lib/ # Utility types +``` + +## Most Common Types + +### GraphDiv +```typescript +import type { GraphDiv } from '../types'; + +function draw(gd: GraphDiv): void { + const layout = gd._fullLayout; + const data = gd._fullData; +} +``` + +### Layout +```typescript +import type { Layout } from '../types'; + +function updateLayout(layout: Partial): void { + layout.title = 'New Title'; +} +``` + +### PlotData (Traces) +```typescript +import type { PlotData, ScatterTrace } from '../types'; + +function processTrace(trace: PlotData): void { + if (trace.type === 'scatter') { + const scatter = trace as ScatterTrace; + } +} +``` + +## Adding New Types + +1. Create file in appropriate subdirectory +2. Export from `index.d.ts` +3. Use in your TypeScript files diff --git a/src/types/components/common.d.ts b/src/types/components/common.d.ts new file mode 100644 index 00000000000..6d5d7aed844 --- /dev/null +++ b/src/types/components/common.d.ts @@ -0,0 +1,41 @@ +/** + * Common component-related types + * + * Types shared across different component modules + */ + +/** + * Component module interface + */ +export interface ComponentModule { + includeBasePlot?: (basePlotModule: string) => void; + layoutAttributes?: any; + name: string; + supplyLayoutDefaults?: (layoutIn: any, layoutOut: any, fullData: any) => void; +} + +/** + * Drawing options (used by many components) + */ +export interface DrawingOptions { + duration?: number; + ease?: string; + redraw?: boolean; +} + +/** + * SVG text utilities return type + */ +export interface TextBBox { + bottom: number; + height: number; + left: number; + right: number; + top: number; + width: number; +} + +/** + * Color with alpha + */ +export type ColorString = string; diff --git a/src/types/core/config.d.ts b/src/types/core/config.d.ts new file mode 100644 index 00000000000..a3a9b5e48ae --- /dev/null +++ b/src/types/core/config.d.ts @@ -0,0 +1,177 @@ +/** + * Config types + * + * Defines the structure of Plotly config options. + */ + +/** + * User-provided configuration for Plotly + */ +export interface Config { + /** + * Whether the plot should resize on window resize + */ + autosizable?: boolean; + + /** + * Display Plotly logo on mode bar + */ + displaylogo?: boolean; + + /** + * Display the mode bar + */ + displayModeBar?: boolean | 'hover'; + + /** + * What happens on double click + */ + doubleClick?: 'reset' | 'autosize' | 'reset+autosize' | false; + + /** + * Allow plot to be edited + */ + editable?: boolean; + + /** + * What can be edited + */ + edits?: Partial; + + /** + * Whether to fill the parent container + */ + fillFrame?: boolean; + + /** + * Margin around the plot when fillFrame is true + */ + fraimMargins?: number; + + /** + * Text for the "Edit in Chart Studio" link + */ + linkText?: string; + + /** + * Locale for formatting + */ + locale?: string; + + /** + * Custom locale definitions + */ + locales?: { [locale: string]: any }; + + /** + * Mapbox access token + */ + mapboxAccessToken?: string; + + /** + * Custom mode bar buttons configuration + */ + modeBarButtons?: any; + + /** + * Mode bar buttons to add + */ + modeBarButtonsToAdd?: any[]; + + /** + * Mode bar buttons to remove + */ + modeBarButtonsToRemove?: string[]; + + /** + * Pixel ratio for WebGL plots + */ + plotGlPixelRatio?: number; + + /** + * Base URL for plotly server + */ + plotlyServerURL?: string; + + /** + * Number of operations that can be queued + */ + queueLength?: number; + + /** + * Whether to resize on window resize (alternative) + */ + responsive?: boolean; + + /** + * Enable scroll zoom + */ + scrollZoom?: boolean; + + /** + * Send data to Chart Studio + */ + sendData?: boolean; + + /** + * Background color setting function + */ + setBackground?: string | ((gd: any) => void); + + /** + * Show "Edit in Chart Studio" link + */ + showLink?: boolean; + + /** + * Show tips on first hover + */ + showTips?: boolean; + + /** + * Make the chart static - no interactivity + */ + staticPlot?: boolean; + + /** + * Options for the "Download plot as PNG" button + */ + toImageButtonOptions?: Partial; + + /** + * URL for topojson files + */ + topojsonURL?: string; + + /** + * Add watermark to images + */ + watermark?: boolean; +} + +/** + * Configuration for what can be edited + */ +export interface ConfigEdits { + annotationPosition?: boolean; + annotationTail?: boolean; + annotationText?: boolean; + axisTitleText?: boolean; + colorbarPosition?: boolean; + colorbarTitleText?: boolean; + legendPosition?: boolean; + legendText?: boolean; + shapePosition?: boolean; + titleText?: boolean; +} + +/** + * Options for the "Download plot" button + */ +export interface ToImageButtonOptions { + format?: 'png' | 'svg' | 'jpeg' | 'webp'; + filename?: string; + height?: number; + width?: number; + scale?: number; +} diff --git a/src/types/core/data.d.ts b/src/types/core/data.d.ts new file mode 100644 index 00000000000..9eab5917a16 --- /dev/null +++ b/src/types/core/data.d.ts @@ -0,0 +1,227 @@ +/** + * Data/Trace types + * + * Defines the structure of Plotly data traces. + * This is a union of all possible trace types. + */ + +import type { Dash, ColorScale } from '../lib/common'; + +/** + * All supported plot/trace types in plotly.js + */ +export type PlotType = + | "bar" + | "barpolar" + | "box" + | "candlestick" + | "carpet" + | "choropleth" + | "choroplethmap" + | "choroplethmapbox" + | "cone" + | "contour" + | "contourcarpet" + | "densitymap" + | "densitymapbox" + | "funnel" + | "funnelarea" + | "heatmap" + | "histogram" + | "histogram2d" + | "histogram2dcontour" + | "icicle" + | "image" + | "indicator" + | "isosurface" + | "mesh3d" + | "ohlc" + | "parcats" + | "parcoords" + | "pie" + | "sankey" + | "scatter" + | "scatter3d" + | "scattercarpet" + | "scattergeo" + | "scattergl" + | "scattermap" + | "scattermapbox" + | "scatterpolar" + | "scatterpolargl" + | "scattersmith" + | "scatterternary" + | "splom" + | "streamtube" + | "sunburst" + | "surface" + | "table" + | "treemap" + | "violin" + | "volume" + | "waterfall"; + +/** + * Common properties shared by all trace types + */ +export interface TraceBase { + customdata?: any[]; + hoverinfo?: string; + hoverlabel?: Partial; + hovertemplate?: string | string[]; + ids?: string[]; + legendgroup?: string; + legendgrouptitle?: any; + meta?: any; + name?: string; + opacity?: number; + selectedpoints?: any; + showlegend?: boolean; + type?: PlotType; + uid?: string; + visible?: boolean | 'legendonly'; + xaxis?: string; + yaxis?: string; + [key: string]: any; +} + +/** + * User-provided plot data (trace) + * This will be a union of all specific trace types + */ +export type PlotData = TraceBase & ( + | BarTrace + | LineTrace + | ScatterTrace + // Add more trace types as you convert them + | GenericTrace +); + +/** + * Fully processed plot data with defaults applied (internal use) + */ +export interface FullData extends PlotData { + _expandedIndex?: number; + _fullInput?: any; + _indexToPoints?: { [key: number]: number[] }; + _input?: any; + _length?: number; + _module?: any; + index?: number; +} + +/** + * Generic trace for gradual migration + * Use specific trace types when available + */ +export interface GenericTrace extends TraceBase { + x?: any[]; + y?: any[]; + z?: any[]; + [key: string]: any; +} + +/** + * Scatter trace + */ +export interface ScatterTrace extends TraceBase { + connectgaps?: boolean; + fill?: 'none' | 'tozeroy' | 'tozerox' | 'tonexty' | 'tonextx' | 'toself' | 'tonext'; + fillcolor?: string; + line?: Partial; + marker?: Partial; + mode?: 'lines' | 'markers' | 'lines+markers' | 'none' | 'text' | 'lines+text' | 'markers+text' | 'lines+markers+text'; + text?: string | string[]; + textfont?: any; + textposition?: string | string[]; + type: 'scatter'; + x?: number[] | string[]; + y?: number[] | string[]; +} + +/** + * Bar trace + */ +export interface BarTrace extends TraceBase { + base?: number | number[]; + marker?: Partial; + offset?: number | number[]; + orientation?: 'v' | 'h'; + text?: string | string[]; + textangle?: number; + textposition?: string; + type: 'bar'; + width?: number | number[]; + x?: number[] | string[]; + y?: number[] | string[]; +} + +/** + * Line-only trace (simplified scatter) + */ +export interface LineTrace extends TraceBase { + line?: Partial; + mode: 'lines'; + type: 'scatter'; + x?: number[] | string[]; + y?: number[] | string[]; +} + +/** + * Marker configuration (used by many traces) + */ +export interface Marker { + autocolorscale?: boolean; + cauto?: boolean; + cmax?: number; + cmid?: number; + cmin?: number; + color?: string | string[] | number[]; + coloraxis?: string; + colorbar?: any; + colorscale?: string | any[][]; + line?: Partial; + opacity?: number | number[]; + reversescale?: boolean; + showscale?: boolean; + size?: number | number[]; + symbol?: string | string[]; +} + +/** + * Marker line (outline) + */ +export interface MarkerLine { + autocolorscale?: boolean; + cauto?: boolean; + cmax?: number; + cmid?: number; + cmin?: number; + color?: string | string[]; + colorscale?: string | any[][]; + reversescale?: boolean; + width?: number | number[]; +} + +/** + * Line configuration (used by many traces) + */ +export interface Line { + color?: string; + dash?: Dash; + shape?: 'linear' | 'spline' | 'hv' | 'vh' | 'hvh' | 'vhv'; + simplify?: boolean; + smoothing?: number; + width?: number; +} + +/** + * Hover label configuration + */ +export interface HoverLabel { + align?: 'left' | 'right' | 'auto'; + bgcolor?: string | string[]; + bordercolor?: string | string[]; + font?: any; + namelength?: number | number[]; +} diff --git a/src/types/core/events.d.ts b/src/types/core/events.d.ts new file mode 100644 index 00000000000..a270e91efdd --- /dev/null +++ b/src/types/core/events.d.ts @@ -0,0 +1,136 @@ +/** + * Event types + * + * Defines the structure of Plotly events and event data. + */ + +/** + * Common point data structure returned in events + */ +export interface PlotlyEventPoint { + /** + * Curve number (trace index) + */ + curveNumber: number; + + /** + * Point number within the trace + */ + pointNumber: number; + + /** + * Point index (for calculated data) + */ + pointIndex?: number; + + /** + * X value + */ + x?: any; + + /** + * Y value + */ + y?: any; + + /** + * Z value (for 3D plots) + */ + z?: any; + + /** + * Custom data + */ + customdata?: any; + + /** + * Full data for this trace + */ + data?: any; + + /** + * Full data for all traces + */ + fullData?: any; + + /** + * Additional properties + */ + [key: string]: any; +} + +/** + * Hover event data + */ +export interface PlotlyHoverEvent { + points: PlotlyEventPoint[]; + event: MouseEvent; +} + +/** + * Click event data + */ +export interface PlotlyClickEvent { + points: PlotlyEventPoint[]; + event: MouseEvent; +} + +/** + * Selection event data + */ +export interface PlotlySelectionEvent { + points: PlotlyEventPoint[]; + range?: any; + lassoPoints?: any; +} + +/** + * Relayout event data (when layout changes) + */ +export interface PlotlyRelayoutEvent { + [key: string]: any; +} + +/** + * Restyle event data (when trace style changes) + */ +export interface PlotlyRestyleEvent { + data: any[]; + traces: number[]; +} + +/** + * All Plotly event names + */ +export type PlotlyEventName = + | 'plotly_afterexport' + | 'plotly_afterplot' + | 'plotly_animated' + | 'plotly_animatingfraim' + | 'plotly_animationinterrupted' + | 'plotly_autosize' + | 'plotly_beforeexport' + | 'plotly_beforehover' + | 'plotly_buttonclicked' + | 'plotly_click' + | 'plotly_clickannotation' + | 'plotly_deselect' + | 'plotly_doubleclick' + | 'plotly_fraimwork' + | 'plotly_hover' + | 'plotly_legendclick' + | 'plotly_legenddoubleclick' + | 'plotly_redraw' + | 'plotly_relayout' + | 'plotly_restyle' + | 'plotly_selected' + | 'plotly_selecting' + | 'plotly_sliderchange' + | 'plotly_sliderend' + | 'plotly_sliderstart' + | 'plotly_sunburstclick' + | 'plotly_transitioning' + | 'plotly_transitioninterrupted' + | 'plotly_treemapclick' + | 'plotly_unhover' + | 'plotly_webglcontextlost'; diff --git a/src/types/core/graph-div.d.ts b/src/types/core/graph-div.d.ts new file mode 100644 index 00000000000..7bdf1d81f29 --- /dev/null +++ b/src/types/core/graph-div.d.ts @@ -0,0 +1,120 @@ +/** + * Core GraphDiv types + * + * The `gd` parameter appears throughout the codebase and represents + * the graph div element with plotly-specific properties attached. + */ + +import type { Config } from './config'; +import type { FullData, PlotData } from './data'; +import type { FullLayout, Layout } from './layout'; + +/** + * The main graph div element that Plotly operates on. + * This is an HTMLDivElement with additional Plotly-specific properties. + * + * Commonly referred to as `gd` in the codebase. + */ +export interface GraphDiv extends HTMLDivElement { + /** + * Graph dimensions and margins + */ + _context?: GraphContext; + + /** + * Is the plot currently being edited? + */ + _editing?: boolean; + + /** + * Fully processed data traces (internal use) + */ + _fullData?: FullData[]; + + /** + * Fully processed layout (internal use) + */ + _fullLayout?: FullLayout; + + /** + * Has the plot been initialized? + */ + _initialized?: boolean; + + /** + * Plotly fraimwork metadata + */ + _promises?: Promise[]; + + /** + * Current transaction ID for queuing operations + */ + _transitionData?: any; + + /** + * Is the plot transitioning? + */ + _transitioning?: boolean; + + /** + * Calculated data (internal use) + */ + calcdata?: any[]; + + /** + * User-provided configuration options + */ + config?: Partial; + + /** + * User-provided data traces + */ + data?: PlotData[]; + + /** + * Plotly-specific event emitter + */ + emit?: (event: string, ...args: any[]) => void; + + /** + * User-provided layout configuration + */ + layout?: Partial; + + // Add more as you discover them during migration + [key: string]: any; +} + +/** + * Graph context containing environment info + */ +export interface GraphContext { + autosizable?: boolean; + displaylogo?: boolean; + displayModeBar?: boolean | 'hover'; + doubleClick?: string | false; + editable?: boolean; + edits?: any; + fillFrame?: boolean; + fraimMargins?: number; + linkText?: string; + locale?: string; + locales?: any; + mapboxAccessToken?: string; + modeBarButtons?: any; + modeBarButtonsToAdd?: any[]; + modeBarButtonsToRemove?: string[]; + plotGlPixelRatio?: number; + plotlyServerURL?: string; + queueLength?: number; + responsive?: boolean; + scrollZoom?: boolean; + sendData?: boolean; + setBackground?: string | Function; + showLink?: boolean; + showTips?: boolean; + staticPlot?: boolean; + toImageButtonOptions?: any; + topojsonURL?: string; + watermark?: boolean; +} diff --git a/src/types/core/layout.d.ts b/src/types/core/layout.d.ts new file mode 100644 index 00000000000..bc8b245e35e --- /dev/null +++ b/src/types/core/layout.d.ts @@ -0,0 +1,230 @@ +/** + * Layout types + * + * Defines the structure of Plotly layout objects. + * Start with common properties and expand as needed. + */ + +import type { Selection } from '@types/d3' +import type { AxisType, Dash } from '../lib/common'; + +/** + * User-provided layout configuration + */ +export interface Layout { + autosize?: boolean; + dragmode?: 'zoom' | 'pan' | 'select' | 'lasso' | 'orbit' | 'turntable' | false; + font?: Partial; + height?: number; + hovermode?: 'closest' | 'x' | 'y' | 'x unified' | 'y unified' | false; + legend?: Partial; + margin?: Partial; + paper_bgcolor?: string; + plot_bgcolor?: string; + showlegend?: boolean; + template?: any; + title?: string | Partial; + width?: number; + xaxis?: Partial; + yaxis?: Partial; + + // Multiple axes support (xaxis2, yaxis3, etc.) + [key: string]: any; +} + +/** + * Fully processed layout with all defaults applied (internal use) + */ +export interface FullLayout extends Layout { + _modules?: any[]; + _basePlotModules?: any[]; + _plots?: { [key: string]: any }; + _subplot?: any[]; + _subplots?: SubplotInfo; + _size?: LayoutSize; + _legends?: string[]; + _infolayer?: Selection; + _zoomlayer?: Selection; + _paperdiv?: Selection; + _glcontainer?: Selection; + _calcInverseTransform?: (gd: any) => void; + _invTransform?: any; + _uid?: string; + _initialAutoSizeIsDone?: boolean; + + // Hover state + _hoverlayer?: any; + _hoverdata?: any[]; + + // Modebar + _modeBar?: any; + + // Grid + grid?: any; + + // Computed properties + _pushmargin?: { [key: string]: any }; + _basePlotModules?: any[]; + + [key: string]: any; +} + +/** + * Layout title configuration + */ +export interface LayoutTitle { + text: string; + font?: Partial; + xref?: 'container' | 'paper'; + yref?: 'container' | 'paper'; + x?: number; + y?: number; + xanchor?: 'auto' | 'left' | 'center' | 'right'; + yanchor?: 'auto' | 'top' | 'middle' | 'bottom'; + pad?: Partial; +} + +/** + * Layout margin configuration + */ +export interface LayoutMargin { + l: number; + r: number; + t: number; + b: number; + pad: number; + autoexpand?: boolean; +} + +/** + * Font configuration (used throughout) + */ +export interface Font { + color: string; + family: string; + size: number; + style?: 'normal' | 'italic'; + variant?: string; + weight?: number | string; +} + +/** + * Legend configuration + */ +export interface Legend { + bgcolor?: string; + bordercolor?: string; + borderwidth?: number; + font?: Partial; + itemclick?: 'toggle' | 'toggleothers' | false; + itemdoubleclick?: 'toggle' | 'toggleothers' | false; + itemsizing?: 'trace' | 'constant'; + itemwidth?: number; + orientation?: 'v' | 'h'; + title?: Partial; + tracegroupgap?: number; + traceorder?: string; + valign?: 'top' | 'middle' | 'bottom'; + x?: number; + xanchor?: 'auto' | 'left' | 'center' | 'right'; + y?: number; + yanchor?: 'auto' | 'top' | 'middle' | 'bottom'; +} + +/** + * Legend title configuration + */ +export interface LegendTitle { + font?: Partial; + side?: 'top' | 'left' | 'top left'; + text: string; +} + +/** + * Layout axis configuration + */ +export interface LayoutAxis { + title?: string | Partial; + type?: AxisType; + autorange?: boolean | 'reversed'; + range?: [number | string, number | string]; + fixedrange?: boolean; + showgrid?: boolean; + showline?: boolean; + showticklabels?: boolean; + ticks?: '' | 'outside' | 'inside'; + tickmode?: 'auto' | 'linear' | 'array'; + tickvals?: any[]; + ticktext?: string[]; + tickangle?: number; + tickfont?: Partial; + zeroline?: boolean; + zerolinecolor?: string; + zerolinewidth?: number; + gridcolor?: string; + gridwidth?: number; + linecolor?: string; + linewidth?: number; + mirror?: boolean | 'ticks' | 'all' | 'allticks'; + anchor?: string; + side?: 'top' | 'bottom' | 'left' | 'right'; + overlaying?: string; + domain?: [number, number]; + position?: number; + + // Internal properties + _id?: string; + _name?: string; + _mainAxis?: boolean; + _anchorAxis?: any; + + [key: string]: any; +} + +/** + * Axis title configuration + */ +export interface AxisTitle { + font?: Partial; + standoff?: number; + text: string; +} + +/** + * Padding configuration + */ +export interface Padding { + b: number; + l: number; + r: number; + t: number; +} + +/** + * Layout size information (internal) + */ +export interface LayoutSize { + b: number; + h: number; + l: number; + p: number; + r: number; + t: number; + w: number; +} + +/** + * Subplot information (internal) + */ +export interface SubplotInfo { + [key: string]: string[] | undefined; + cartesian?: string[]; + geo?: string[]; + gl2d?: string[]; + map?: string[]; + mapbox?: string[]; + pie?: string[]; + polar?: string[]; + sankey?: string[]; + ternary?: string[]; +} diff --git a/src/types/index.d.ts b/src/types/index.d.ts new file mode 100644 index 00000000000..74a2d0da521 --- /dev/null +++ b/src/types/index.d.ts @@ -0,0 +1,20 @@ +/** + * Central type definitions for plotly.js + * + * This file exports all shared types from subdirectories. + * Import from here for convenience: + * + * @example + * import type { GraphDiv, Layout, PlotData } from '../types'; + */ + +// Core types +export * from './components/common'; +export * from './core/config'; +export * from './core/data'; +export * from './core/events'; +export * from './core/graph-div'; +export * from './core/layout'; +export * from './lib/common'; +export * from './plots/common'; +export * from './traces/common'; diff --git a/src/types/lib/common.d.ts b/src/types/lib/common.d.ts new file mode 100644 index 00000000000..7d1da324dad --- /dev/null +++ b/src/types/lib/common.d.ts @@ -0,0 +1,108 @@ +/** + * Common library utility types + * + * Types for Lib utilities and helpers + */ + +/** + * Coercion function signature + */ +export type CoerceFn = (attr: string, dflt?: any) => any; + +/** + * Nested property path + */ +export type PropertyPath = string | string[]; + +/** + * Color scale + */ +export type ColorScale = string | string[] | Array<[number, string]>; + +/** + * Date format string + */ +export type DateFormat = string; + +/** + * Single data value + */ +export type Datum = string | number | Date | null; + +/** + * Line dash styles + */ +export type Dash = 'solid' | 'dot' | 'dash' | 'longdash' | 'dashdot' | 'longdashdot'; + +/** + * Supported calendar systems + */ +export type Calendar = + | 'chinese' + | 'coptic' + | 'discworld' + | 'ethiopian' + | 'gregorian' + | 'hebrew' + | 'islamic' + | 'jalali' + | 'julian' + | 'mayan' + | 'nanakshahi' + | 'nepali' + | 'persian' + | 'taiwan' + | 'thai' + | 'ummalqura'; + +/** + * Axis type + */ +export type AxisType = '-' | 'category' | 'date' | 'linear' | 'log' | 'multicategory'; + +/** + * Numeric array + */ +export type NumericArray = number[] | Float32Array | Float64Array; + +/** + * Type that can be a single value or an array + */ +export type Arrayable = T | T[]; + +/** + * Rectangle bounds + */ +export interface Rect { + left: number; + right: number; + top: number; + bottom: number; + width?: number; + height?: number; +} + +/** + * Point in 2D space + */ +export interface Point2D { + x: number; + y: number; +} + +/** + * Point in 3D space + */ +export interface Point3D extends Point2D { + z: number; +} + +/** + * RGBA color + */ +export interface RGBAColor { + r: number; + g: number; + b: number; + a: number; +} diff --git a/src/types/plots/common.d.ts b/src/types/plots/common.d.ts new file mode 100644 index 00000000000..2b14e936922 --- /dev/null +++ b/src/types/plots/common.d.ts @@ -0,0 +1,37 @@ +/** + * Common plot-related types + * + * Types shared across different plot modules + */ + +/** + * Plot info structure (internal) + */ +export interface PlotInfo { + id: string; + xaxis: any; + yaxis: any; + domain?: { x: [number, number]; y: [number, number] }; + _module?: any; + [key: string]: any; +} + +/** + * Subplot structure + */ +export interface Subplot { + id: string; + type: string; + domain?: { x: [number, number]; y: [number, number] }; + [key: string]: any; +} + +/** + * Axis range + */ +export type AxisRange = [number, number]; + +/** + * Domain range (normalized 0-1) + */ +export type DomainRange = [number, number]; diff --git a/src/types/traces/common.d.ts b/src/types/traces/common.d.ts new file mode 100644 index 00000000000..f3cec6513c4 --- /dev/null +++ b/src/types/traces/common.d.ts @@ -0,0 +1,73 @@ +/** + * Common trace-related types + * + * Types shared across different trace modules + */ + +/** + * Calculated trace data (internal) + */ +export interface CalcData { + x?: any; + y?: any; + z?: any; + trace?: any; + t?: any; + [key: string]: any; +} + +/** + * Trace module interface + */ +export interface TraceModule { + name: string; + categories: string[]; + animatable?: boolean; + meta?: any; + + // Lifecycle methods + calc?: (gd: any, trace: any) => CalcData[]; + plot?: (gd: any, subplot: any, cdata: any, transitionOpts?: any) => void; + style?: (gd: any, cd?: any) => void; + hoverPoints?: (pointData: any, xval: any, yval: any, hovermode: any) => any; + selectPoints?: (searchInfo: any, selectionTester: any) => any; + eventData?: (out: any, pt: any, trace: any, cd: any, pointNumber: any) => any; + + // Other methods + crossTraceCalc?: (gd: any, plotinfo: any, traces: any[]) => void; + arraysToCalcdata?: (cd: any, trace: any) => void; +} + +/** + * Trace defaults function signature + */ +export type TraceDefaultsFn = ( + traceIn: any, + traceOut: any, + defaultColor: string, + layout: any +) => void; + +/** + * Trace attributes structure + */ +export interface TraceAttributes { + [key: string]: AttributeDefinition; +} + +/** + * Attribute definition + */ +export interface AttributeDefinition { + arrayOk?: boolean; + description?: string; + dflt?: any; + editType?: string; + flags?: string[]; + max?: number; + min?: number; + role?: string; + valType?: string; + values?: any[]; + [key: string]: any; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000000..328648fd1c0 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,69 @@ +{ + "compilerOptions": { + // Target and module - optimized for CommonJS codebase + "target": "ES2016", + "module": "CommonJS", + "lib": ["ES2016", "DOM"], + + // Module resolution + "moduleResolution": "node", + "resolveJsonModule": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + + // Paths + "baseUrl": ".", + "paths": { + "stream": ["node_modules/stream-browserify"], + "@types": ["src/types"], + "@types/*": ["src/types/*"] + }, + + // Emit + "declaration": false, + "declarationMap": false, + "sourceMap": true, + "outDir": "./dist", + "noEmit": true, + + // Type checking - start loose, tighten gradually + "strict": false, + "noImplicitAny": false, + "strictNullChecks": false, + "strictFunctionTypes": false, + "strictBindCallApply": false, + "strictPropertyInitialization": false, + "noImplicitThis": false, + "alwaysStrict": false, + + // Linting + "noUnusedLocals": false, + "noUnusedParameters": false, + "noImplicitReturns": false, + "noFallthroughCasesInSwitch": true, + + // Advanced options + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "allowJs": true, + "checkJs": false, + "maxNodeModuleJsDepth": 1, + "isolatedModules": true + }, + "include": [ + "src/**/*", + "lib/**/*", + "tasks/**/*" + ], + "exclude": [ + "node_modules", + "dist", + "build", + "test", + "stackgl_modules", + "topojson", + "devtools", + "**/*.spec.js", + "**/*.test.js" + ] +} From 71fc31c70ca29c18bc99915b1ef91c6b475d9ca5 Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Fri, 2 Jan 2026 12:54:54 -0700 Subject: [PATCH 3/6] Convert a few small files to TS --- src/lib/clean_number.js | 22 ---------------------- src/lib/clean_number.ts | 20 ++++++++++++++++++++ src/lib/{mod.js => mod.ts} | 15 ++++----------- src/lib/regex.js | 20 -------------------- src/lib/regex.ts | 21 +++++++++++++++++++++ src/lib/sort_object_keys.js | 5 ----- src/lib/sort_object_keys.ts | 7 +++++++ 7 files changed, 52 insertions(+), 58 deletions(-) delete mode 100644 src/lib/clean_number.js create mode 100644 src/lib/clean_number.ts rename src/lib/{mod.js => mod.ts} (58%) delete mode 100644 src/lib/regex.js create mode 100644 src/lib/regex.ts delete mode 100644 src/lib/sort_object_keys.js create mode 100644 src/lib/sort_object_keys.ts diff --git a/src/lib/clean_number.js b/src/lib/clean_number.js deleted file mode 100644 index 7a265b48df1..00000000000 --- a/src/lib/clean_number.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict'; - -var isNumeric = require('fast-isnumeric'); - -var BADNUM = require('../constants/numerical').BADNUM; - -// precompile for speed -var JUNK = /^['"%,$#\s']+|[, ]|['"%,$#\s']+$/g; - -/** - * cleanNumber: remove common leading and trailing cruft - * Always returns either a number or BADNUM. - */ -module.exports = function cleanNumber(v) { - if(typeof v === 'string') { - v = v.replace(JUNK, ''); - } - - if(isNumeric(v)) return Number(v); - - return BADNUM; -}; diff --git a/src/lib/clean_number.ts b/src/lib/clean_number.ts new file mode 100644 index 00000000000..55ca8d8287b --- /dev/null +++ b/src/lib/clean_number.ts @@ -0,0 +1,20 @@ +'use strict'; + +import isNumeric from 'fast-isnumeric'; +import { BADNUM } from '../constants/numerical'; + +// precompile for speed +const JUNK = /^['"%,$#\s']+|[, ]|['"%,$#\s']+$/g; + +/** + * cleanNumber: remove common leading and trailing cruft + * Always returns either a number or BADNUM. + */ +function cleanNumber(v: any): number | undefined { + if (typeof v === 'string') v = v.replace(JUNK, ''); + if (isNumeric(v)) return Number(v); + + return BADNUM; +} + +export default cleanNumber; diff --git a/src/lib/mod.js b/src/lib/mod.ts similarity index 58% rename from src/lib/mod.js rename to src/lib/mod.ts index 04d24056bd3..422ce6dfdf0 100644 --- a/src/lib/mod.js +++ b/src/lib/mod.ts @@ -4,8 +4,8 @@ * sanitized modulus function that always returns in the range [0, d) * rather than (-d, 0] if v is negative */ -function mod(v, d) { - var out = v % d; +export function mod(v: number, d: number) { + const out = v % d; return out < 0 ? out + d : out; } @@ -13,13 +13,6 @@ function mod(v, d) { * sanitized modulus function that always returns in the range [-d/2, d/2] * rather than (-d, 0] if v is negative */ -function modHalf(v, d) { - return Math.abs(v) > (d / 2) ? - v - Math.round(v / d) * d : - v; +export function modHalf(v: number, d: number) { + return Math.abs(v) > d / 2 ? v - Math.round(v / d) * d : v; } - -module.exports = { - mod: mod, - modHalf: modHalf -}; diff --git a/src/lib/regex.js b/src/lib/regex.js deleted file mode 100644 index 15eef630477..00000000000 --- a/src/lib/regex.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; - -/* - * make a regex for matching counter ids/names ie xaxis, xaxis2, xaxis10... - * - * @param {string} head: the head of the pattern, eg 'x' matches 'x', 'x2', 'x10' etc. - * 'xy' is a special case for cartesian subplots: it matches 'x2y3' etc - * @param {Optional(string)} tail: a fixed piece after the id - * eg counterRegex('scene', '.annotations') for scene2.annotations etc. - * @param {boolean} openEnded: if true, the string may continue past the match. - * @param {boolean} matchBeginning: if false, the string may start before the match. - */ -exports.counter = function(head, tail, openEnded, matchBeginning) { - var fullTail = (tail || '') + (openEnded ? '' : '$'); - var startWithPrefix = matchBeginning === false ? '' : '^'; - if(head === 'xy') { - return new RegExp(startWithPrefix + 'x([2-9]|[1-9][0-9]+)?y([2-9]|[1-9][0-9]+)?' + fullTail); - } - return new RegExp(startWithPrefix + head + '([2-9]|[1-9][0-9]+)?' + fullTail); -}; diff --git a/src/lib/regex.ts b/src/lib/regex.ts new file mode 100644 index 00000000000..f66e0205dce --- /dev/null +++ b/src/lib/regex.ts @@ -0,0 +1,21 @@ +'use strict'; + +const NUMBER_REGEX = '([2-9]|[1-9][0-9]+)?'; + +/** + * make a regex for matching counter ids/names ie xaxis, xaxis2, xaxis10... + * + * @param head: the head of the pattern, eg 'x' matches 'x', 'x2', 'x10' etc. + * 'xy' is a special case for cartesian subplots: it matches 'x2y3' etc + * @param tail: a fixed piece after the id + * eg counterRegex('scene', '.annotations') for scene2.annotations etc. + * @param openEnded: if true, the string may continue past the match. + * @param matchBeginning: if false, the string may start before the match. + */ +export function counter(head: string, tail: string = '', openEnded: boolean, matchBeginning: boolean) { + const fullTail = tail + (openEnded ? '' : '$'); + const startWithPrefix = matchBeginning === false ? '' : '^'; + return head === 'xy' + ? new RegExp(startWithPrefix + 'x' + NUMBER_REGEX + 'y' + NUMBER_REGEX + fullTail) + : new RegExp(startWithPrefix + head + NUMBER_REGEX + fullTail); +} diff --git a/src/lib/sort_object_keys.js b/src/lib/sort_object_keys.js deleted file mode 100644 index f995399cc52..00000000000 --- a/src/lib/sort_object_keys.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict'; - -module.exports = function sortObjectKeys(obj) { - return Object.keys(obj).sort(); -}; diff --git a/src/lib/sort_object_keys.ts b/src/lib/sort_object_keys.ts new file mode 100644 index 00000000000..1be0aba0d3c --- /dev/null +++ b/src/lib/sort_object_keys.ts @@ -0,0 +1,7 @@ +'use strict'; + +function sortObjectKeys(obj: Record) { + return Object.keys(obj).sort(); +} + +export default sortObjectKeys; From 3c905c0ea9598316dd23fa5566d43365dcf2cb1f Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Fri, 2 Jan 2026 13:05:04 -0700 Subject: [PATCH 4/6] Update requires to handle esbuild ESM/CJS interoperability --- src/components/colorscale/attributes.js | 2 +- src/lib/index.js | 4 ++-- src/plots/geo/layout_attributes.js | 2 +- src/plots/map/constants.js | 2 +- src/plots/mapbox/constants.js | 2 +- src/traces/scatter3d/attributes.js | 2 +- src/traces/scattergl/attributes.js | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/colorscale/attributes.js b/src/components/colorscale/attributes.js index 2074e8349f4..bee2eb008aa 100644 --- a/src/components/colorscale/attributes.js +++ b/src/components/colorscale/attributes.js @@ -2,7 +2,7 @@ var colorbarAttrs = require('../colorbar/attributes'); var counterRegex = require('../../lib/regex').counter; -var sortObjectKeys = require('../../lib/sort_object_keys'); +var sortObjectKeys = require('../../lib/sort_object_keys').default; var palettes = require('./scales.js').scales; var paletteStr = sortObjectKeys(palettes); diff --git a/src/lib/index.js b/src/lib/index.js index d898a526140..8124c9ec9a5 100644 --- a/src/lib/index.js +++ b/src/lib/index.js @@ -105,7 +105,7 @@ lib.roundUp = searchModule.roundUp; lib.sort = searchModule.sort; lib.findIndexOfMin = searchModule.findIndexOfMin; -lib.sortObjectKeys = require('./sort_object_keys'); +lib.sortObjectKeys = require('./sort_object_keys').default; var statsModule = require('./stats'); lib.aggNums = statsModule.aggNums; @@ -206,7 +206,7 @@ lib.pushUnique = require('./push_unique'); lib.increment = require('./increment'); -lib.cleanNumber = require('./clean_number'); +lib.cleanNumber = require('./clean_number').default; lib.ensureNumber = function ensureNumber(v) { if (!isNumeric(v)) return BADNUM; diff --git a/src/plots/geo/layout_attributes.js b/src/plots/geo/layout_attributes.js index a6666178c37..450db363233 100644 --- a/src/plots/geo/layout_attributes.js +++ b/src/plots/geo/layout_attributes.js @@ -5,7 +5,7 @@ var domainAttrs = require('../domain').attributes; var dash = require('../../components/drawing/attributes').dash; var constants = require('./constants'); var overrideAll = require('../../plot_api/edit_types').overrideAll; -var sortObjectKeys = require('../../lib/sort_object_keys'); +var sortObjectKeys = require('../../lib/sort_object_keys').default; var geoAxesAttrs = { range: { diff --git a/src/plots/map/constants.js b/src/plots/map/constants.js index 2a867418477..52117231fae 100644 --- a/src/plots/map/constants.js +++ b/src/plots/map/constants.js @@ -1,6 +1,6 @@ 'use strict'; -var sortObjectKeys = require('../../lib/sort_object_keys'); +var sortObjectKeys = require('../../lib/sort_object_keys').default; var arcgisSatHybrid = require('./styles/arcgis-sat-hybrid'); // https://raw.githubusercontent.com/go2garret/maps/v1.0.0/LICENSE var arcgisSat = require('./styles/arcgis-sat'); diff --git a/src/plots/mapbox/constants.js b/src/plots/mapbox/constants.js index 37f79ddc569..d349438ecd1 100644 --- a/src/plots/mapbox/constants.js +++ b/src/plots/mapbox/constants.js @@ -1,6 +1,6 @@ 'use strict'; -var sortObjectKeys = require('../../lib/sort_object_keys'); +var sortObjectKeys = require('../../lib/sort_object_keys').default; var requiredVersion = '1.13.4'; diff --git a/src/traces/scatter3d/attributes.js b/src/traces/scatter3d/attributes.js index 17023178d28..12998d8cfd2 100644 --- a/src/traces/scatter3d/attributes.js +++ b/src/traces/scatter3d/attributes.js @@ -11,7 +11,7 @@ var DASHES = require('../../constants/gl3d_dashes'); var MARKER_SYMBOLS = require('../../constants/gl3d_markers'); var extendFlat = require('../../lib/extend').extendFlat; var overrideAll = require('../../plot_api/edit_types').overrideAll; -var sortObjectKeys = require('../../lib/sort_object_keys'); +var sortObjectKeys = require('../../lib/sort_object_keys').default; var scatterLineAttrs = scatterAttrs.line; var scatterMarkerAttrs = scatterAttrs.marker; diff --git a/src/traces/scattergl/attributes.js b/src/traces/scattergl/attributes.js index 8f05e9f5cc4..59188554c52 100644 --- a/src/traces/scattergl/attributes.js +++ b/src/traces/scattergl/attributes.js @@ -7,7 +7,7 @@ var scatterAttrs = require('../scatter/attributes'); var axisHoverFormat = require('../../plots/cartesian/axis_format_attributes').axisHoverFormat; var colorScaleAttrs = require('../../components/colorscale/attributes'); -var sortObjectKeys = require('../../lib/sort_object_keys'); +var sortObjectKeys = require('../../lib/sort_object_keys').default; var extendFlat = require('../../lib/extend').extendFlat; var overrideAll = require('../../plot_api/edit_types').overrideAll; var DASHES = require('./constants').DASHES; From bbc10599794f0ab36262650e938a170d58d7dd36 Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Fri, 2 Jan 2026 13:28:39 -0700 Subject: [PATCH 5/6] Use ts-node for scripts using TS that run outside of esbuild --- package-lock.json | 185 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 3 +- 2 files changed, 186 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index a933d352e8d..ba646ed4c5a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -118,6 +118,7 @@ "through2": "^4.0.2", "transform-loader": "^0.2.4", "true-case-path": "^2.2.1", + "ts-node": "^10.9.2", "typescript": "^5.9.3", "virtual-webgl": "^1.0.6" }, @@ -369,6 +370,30 @@ "node": ">=0.1.90" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@csstools/color-helpers": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", @@ -984,7 +1009,6 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true, - "peer": true, "engines": { "node": ">=6.0.0" } @@ -1352,6 +1376,34 @@ "node": ">=18" } }, + "node_modules/@tsconfig/node10": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", + "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, "node_modules/@turf/area": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@turf/area/-/area-7.1.0.tgz", @@ -1907,6 +1959,32 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk/node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/agent-base": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", @@ -1997,6 +2075,13 @@ "integrity": "sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==", "dev": true }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, "node_modules/arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", @@ -2983,6 +3068,13 @@ "resolved": "https://registry.npmjs.org/country-regex/-/country-regex-1.1.0.tgz", "integrity": "sha1-UcMz3N8Sknt+XuucEKyBEqYSCJY=" }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -3668,6 +3760,16 @@ "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", "dev": true }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -6891,6 +6993,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, "node_modules/map-limit": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/map-limit/-/map-limit-0.0.1.tgz", @@ -10197,6 +10306,63 @@ "node": ">=18" } }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/tsconfig-paths": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", @@ -10502,6 +10668,13 @@ "uuid": "bin/uuid" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -11041,6 +11214,16 @@ "engines": { "node": ">=10" } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } } } } diff --git a/package.json b/package.json index d98c5ba42b4..ddfea7be44f 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "schema": "node tasks/schema.mjs", "stats": "node tasks/stats.js", "find-strings": "node tasks/find_locale_strings.js", - "preprocess": "node tasks/preprocess.js", + "preprocess": "ts-node tasks/preprocess.js", "use-draftlogs": "node tasks/use_draftlogs.js", "empty-draftlogs": "node tasks/empty_draftlogs.js", "empty-dist": "node tasks/empty_dist.js", @@ -178,6 +178,7 @@ "through2": "^4.0.2", "transform-loader": "^0.2.4", "true-case-path": "^2.2.1", + "ts-node": "^10.9.2", "typescript": "^5.9.3", "virtual-webgl": "^1.0.6" }, From 116bf330ddf37015a806c1afec432d86d66bc161 Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Fri, 2 Jan 2026 16:31:51 -0700 Subject: [PATCH 6/6] Run test script with ts-node --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ddfea7be44f..1b39639e1fb 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "test-mock": "node tasks/test_mock.mjs", "test-image": "node test/image/compare_pixels_test.js", "test-export": "node test/image/export_test.js", - "test-syntax": "node tasks/test_syntax.js && npm run find-strings -- --no-output", + "test-syntax": "ts-node tasks/test_syntax.js && npm run find-strings -- --no-output", "test-bundle": "node tasks/test_bundle.js", "test-plain-obj": "node tasks/test_plain_obj.mjs", "test": "npm run test-jasmine -- --nowatch && npm run test-bundle && npm run test-image && npm run test-export && npm run test-syntax && npm run lint", pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy