diff --git a/assets/conf-img/sizes/square-native.json b/assets/conf-img/sizes/square-native.json
new file mode 100644
index 00000000..957b72d7
--- /dev/null
+++ b/assets/conf-img/sizes/square-native.json
@@ -0,0 +1,12 @@
+[
+ {
+ "width": 500,
+ "height": 500,
+ "crop": true
+ },
+ {
+ "width": 1000,
+ "height": 1000,
+ "crop": true
+ }
+]
diff --git a/assets/conf-img/tpl/default-native-caption.tpl b/assets/conf-img/tpl/default-native-caption.tpl
new file mode 100644
index 00000000..daf9c71e
--- /dev/null
+++ b/assets/conf-img/tpl/default-native-caption.tpl
@@ -0,0 +1,5 @@
+%%data-location%%
+
+
+ %%caption%%
+
diff --git a/assets/conf-img/tpl/default-native.tpl b/assets/conf-img/tpl/default-native.tpl
new file mode 100644
index 00000000..baf82163
--- /dev/null
+++ b/assets/conf-img/tpl/default-native.tpl
@@ -0,0 +1,2 @@
+%%data-location%%
+
diff --git a/config/WebpackImageSizesPlugin.js b/config/WebpackImageSizesPlugin.js
deleted file mode 100644
index e718dbd6..00000000
--- a/config/WebpackImageSizesPlugin.js
+++ /dev/null
@@ -1,266 +0,0 @@
-const chalk = require('chalk')
-const path = require('path')
-const fs = require('fs')
-const sharp = require('sharp')
-
-const logId = '[' + chalk.blue('WebpackImageSizesPlugin') + ']'
-
-class WebpackImageSizesPlugin {
- constructor(options) {
- // folders
- this._confImgFolder = path.resolve(__dirname, '../assets/conf-img') + '/'
- this._tplFolder = this._confImgFolder + 'tpl/'
- this._defaultImagesFolder = path.resolve(__dirname, '../dist/images') + '/'
-
- // files
- this._imageSisesJson = this._confImgFolder + 'image-sizes.json'
- this._imageLocationsJson = this._confImgFolder + 'image-locations.json'
- this._imageDefault = path.resolve(__dirname, '../src/img/static') + '/default.jpg'
-
- // list of [filnename]: sizes
- this._defaultImages = {}
-
- if (options.watch) {
- fs.watch(this._tplFolder, () => {
- this.generateImageJsonFiles()
- this.generateDefaultImages()
- })
- }
-
- this.generateImageJsonFiles()
- }
-
- /**
- * apply
- */
- apply(compiler) {
- compiler.hooks.afterEmit.tapAsync('WebpackImageSizesPlugin', (compilation, callback) => {
- this.generateDefaultImages()
- callback()
- })
- }
-
- /**
- * Generate image-sises.json and image-location.json
- */
- generateImageJsonFiles() {
- const that = this
- const regex = {
- srcset: /srcset="(.[^"]*)"/gm,
- crop: /data-crop="(.[^"]*)"/gm,
- img: /img-\d*-\d*/gm,
- }
-
- const locations = {}
- const sizes = {}
-
- let nbLocations = 0
- let nbSizes = 0
-
- /**
- * reset defaultImages
- */
- this._defaultImages = {}
-
- /**
- * Return an array of names of tpl files
- * @return {array}
- */
- function getTemplateFileNames() {
- return fs.readdirSync(that._tplFolder).filter((tpl) => {
- if (
- tpl !== 'default-picture.tpl' &&
- tpl !== 'default-picture-caption.tpl' &&
- tpl !== 'default-picture-nolazyload.tpl' &&
- tpl !== 'default-picture-nolazyload-caption.tpl'
- ) {
- return tpl
- }
- })
- }
-
- /**
- * Return content of tpl file
- * @param {string} templateFileName
- * @return {string}
- */
- function getTemplateFileContent(templateFileName) {
- return fs.readFileSync(that._tplFolder + templateFileName, 'utf8')
- }
-
- /**
- * Create a json file
- * @param {string} destPath
- * @param data
- * @return undefined
- */
- function createJsonFile(destPath, data) {
- createFile(destPath, JSON.stringify(data, null, 2))
- }
-
- /**
- * Remove extension template name
- * @param {string} name
- * @return {String}
- */
- function removeFileExtension(name) {
- return name.split('.')[0]
- }
-
- /**
- * Generate default location name based on image size
- * @param {String} size
- * @return {String}
- */
- function getDefaultImgName(str) {
- return `${str.replace('img', 'default')}.jpg`
- }
-
- /**
- * Check if srcset is retina
- * @param {String} src
- * @return {Array}
- */
- function isRetina(src) {
- const retina = []
- src.split(',').forEach((val) => {
- if (val.includes('2x')) {
- retina.push('2x')
- } else {
- retina.push('')
- }
- })
- return retina
- }
-
- /**
- * Create file if he does not exist
- * @param {String} filename
- * @param {String} json
- */
- function createFile(filename, json) {
- fs.open(filename, 'r', () => {
- fs.writeFileSync(filename, json)
- })
- }
-
- /**
- * Get image locations informations from tpl files
- */
- function imageLocationsFromTpl() {
- const templateFileNames = getTemplateFileNames()
-
- templateFileNames.forEach((tplName) => {
- nbLocations += 1
- const tplContent = getTemplateFileContent(tplName)
- const srcsetArr = tplContent.match(regex.srcset) || []
- const cropArr = tplContent.match(regex.crop)
- const storage = {
- srcsets: [],
- default_img: '',
- img_base: '',
- }
-
- srcsetArr.forEach((src) => {
- const dimensions = src.match(regex.img)
- const retina = isRetina(src)
- const crop = !(cropArr && cropArr[0] === 'data-crop="false"')
-
- dimensions.forEach((size, index) => {
- const splitSize = size.split('-')
- const srcsetObj = {
- srcset: retina[index],
- size,
- }
-
- if (sizes[size] && sizes[size].crop !== crop) {
- console.log(logId, '\nSize already exists but crop is not equal :', size)
- }
-
- if (!sizes[size]) {
- sizes[size] = {
- width: splitSize[1],
- height: splitSize[2],
- crop,
- }
-
- nbSizes += 1
- }
-
- storage.srcsets.push(srcsetObj)
- storage.default_img = getDefaultImgName(size)
- storage.img_base = size
-
- that._defaultImages[getDefaultImgName(size)] = sizes[size]
- })
-
- locations[removeFileExtension(tplName)] = [storage]
- })
- })
- }
-
- /**
- * Init
- */
- console.log(logId, 'Generate image locations and sizes JSON files')
-
- imageLocationsFromTpl()
-
- createJsonFile(this._imageLocationsJson, [locations])
- createJsonFile(this._imageSisesJson, [sizes])
-
- console.log(logId, 'JSON files successfully generated !')
- console.log(logId, 'Number of locations:', nbLocations)
- console.log(logId, 'Number of sizes:', nbSizes)
-
- return this
- }
-
- /**
- * generate default images
- */
- generateDefaultImages() {
- if (!fs.existsSync(this._defaultImagesFolder)) {
- fs.mkdirSync(this._defaultImagesFolder, { recursive: true })
- }
-
- for (const filename in this._defaultImages) {
- const sizes = this._defaultImages[filename]
- const outputFile = this._defaultImagesFolder + filename
-
- try {
- if (fs.existsSync(outputFile)) {
- continue
- }
-
- const width = parseInt(sizes.width, 10)
- const height = parseInt(sizes.height, 10)
-
- if (width >= 9999 || height >= 9999) {
- continue
- }
-
- sharp(this._imageDefault)
- .resize(width, height, {
- fit: 'cover',
- position: 'center',
- })
- .jpeg({ quality: 70, chromaSubsampling: '4:4:4' })
- .toFile(outputFile, (err, info) => {
- if (err) {
- console.error(logId, err)
- } else {
- console.log(logId, `Created ${info.width}x${info.height} image`)
- console.log(logId, 'at', outputFile.split('/themes/')[1] || '')
- }
- })
- } catch (err) {
- console.error(logId, err)
- }
- }
-
- return this
- }
-}
-
-module.exports = WebpackImageSizesPlugin
diff --git a/config/plugins.js b/config/plugins.js
index be971bb1..866ecb12 100644
--- a/config/plugins.js
+++ b/config/plugins.js
@@ -9,7 +9,7 @@ const WebpackBar = require('webpackbar')
const DependencyExtractionWebpackPlugin = require('@wordpress/dependency-extraction-webpack-plugin')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
-const WebpackImageSizesPlugin = require('./WebpackImageSizesPlugin')
+const WebpackImageSizesPlugin = require('./webpack-image-sizes-plugin')
module.exports = {
get: function (mode) {
@@ -33,7 +33,15 @@ module.exports = {
}),
new DependencyExtractionWebpackPlugin(),
new WebpackImageSizesPlugin({
- watch: mode !== 'production',
+ confImgPath: 'assets/conf-img', // Path to the conf-img folder
+ sizesSubdir: 'sizes', // Subdirectory containing the sizes JSON files
+ tplSubdir: 'tpl', // Subdirectory containing TPL templates
+ outputImageLocations: 'image-locations.json', // Output locations file name
+ outputImageSizes: 'image-sizes.json', // Output sizes file name
+ generateDefaultImages: true, // Generate default images
+ defaultImageSource: 'src/img/static/default.jpg', // Source image for generation
+ defaultImagesOutputDir: 'dist/images', // Default images output directory
+ defaultImageFormat: 'jpg', // Generated image format (jpg, png, webp, avif)
}),
]
diff --git a/config/webpack-image-sizes-plugin.js b/config/webpack-image-sizes-plugin.js
new file mode 100644
index 00000000..f8cac011
--- /dev/null
+++ b/config/webpack-image-sizes-plugin.js
@@ -0,0 +1,509 @@
+const fs = require('fs')
+const path = require('path')
+
+// Try to require sharp, fallback gracefully if not available
+let sharp
+try {
+ sharp = require('sharp')
+} catch (error) {
+ console.warn('⚠️ Sharp not available. Default image generation will be disabled.')
+}
+
+/**
+ * Webpack plugin that generates image-locations.json and image-sizes.json files
+ * by parsing JSON files in sizes/ subdirectory and TPL files in tpl/ subdirectory.
+ *
+ * @class WebpackImageSizesPlugin
+ */
+class WebpackImageSizesPlugin {
+ /**
+ * Creates an instance of WebpackImageSizesPlugin.
+ *
+ * @param {Object} [options={}] - Plugin configuration options
+ * @param {string} [options.confImgPath='assets/conf-img'] - Path to the conf-img directory
+ * @param {string} [options.sizesSubdir='sizes'] - Subdirectory containing JSON size files
+ * @param {string} [options.tplSubdir='tpl'] - Subdirectory containing TPL template files
+ * @param {string} [options.outputImageLocations='image-locations.json'] - Output filename for image locations
+ * @param {string} [options.outputImageSizes='image-sizes.json'] - Output filename for image sizes
+ * @param {boolean} [options.generateDefaultImages=false] - Whether to generate default images
+ * @param {string} [options.defaultImageSource='src/img/static/default.jpg'] - Path to the source image for generating defaults
+ * @param {string} [options.defaultImagesOutputDir='dist/images'] - Directory where default images will be generated
+ * @param {string} [options.defaultImageFormat='jpg'] - Format for generated images (jpg, png, webp, avif)
+ * @memberof WebpackImageSizesPlugin
+ */
+ constructor(options = {}) {
+ this.options = {
+ confImgPath: options.confImgPath || 'assets/conf-img',
+ sizesSubdir: options.sizesSubdir || 'sizes',
+ tplSubdir: options.tplSubdir || 'tpl',
+ outputImageLocations: options.outputImageLocations || 'image-locations.json',
+ outputImageSizes: options.outputImageSizes || 'image-sizes.json',
+ generateDefaultImages: options.generateDefaultImages || false,
+ defaultImageSource: options.defaultImageSource || 'src/img/static/default.jpg',
+ defaultImagesOutputDir: options.defaultImagesOutputDir || 'dist/images',
+ defaultImageFormat: options.defaultImageFormat || 'jpg',
+ ...options,
+ }
+ }
+
+ /**
+ * Applies the plugin to the webpack compiler.
+ * Sets up hooks for initial build and watch mode rebuilds.
+ *
+ * @param {Object} compiler - The webpack compiler instance
+ * @memberof WebpackImageSizesPlugin
+ */
+ apply(compiler) {
+ // Execute on first build and each rebuild
+ const runGeneration = async (compilation, callback) => {
+ try {
+ const confImgPath = path.resolve(compiler.context, this.options.confImgPath)
+ const sizesPath = path.join(confImgPath, this.options.sizesSubdir)
+ const tplPath = path.join(confImgPath, this.options.tplSubdir)
+
+ console.log('🔧 Starting WebpackImageSizesPlugin generation...')
+
+ // Check for deleted/renamed files if output files already exist
+ this.checkForDeletedFiles(confImgPath, sizesPath, tplPath)
+
+ // Generate image-locations.json from JSON and TPL files
+ const imageLocations = this.generateImageLocations(sizesPath, tplPath)
+
+ // Generate image-sizes.json from JSON files and TPL files
+ const imageSizes = this.generateImageSizes(sizesPath, tplPath, imageLocations)
+
+ // Write output files
+ const imageLocationsPath = path.join(confImgPath, this.options.outputImageLocations)
+ const imageSizesPath = path.join(confImgPath, this.options.outputImageSizes)
+
+ fs.writeFileSync(imageLocationsPath, JSON.stringify(imageLocations, null, 2))
+ fs.writeFileSync(imageSizesPath, JSON.stringify(imageSizes, null, 2))
+
+ console.log(`✅ Generated ${this.options.outputImageLocations} and ${this.options.outputImageSizes}`)
+
+ // Generate default images if option is enabled
+ if (this.options.generateDefaultImages) {
+ await this.generateDefaultImages(compiler.context, imageSizes)
+ }
+
+ if (callback) {
+ callback()
+ }
+ } catch (error) {
+ console.error('❌ Error in WebpackImageSizesPlugin:', error)
+ if (callback) {
+ callback(error)
+ }
+ }
+ }
+
+ // Hook for initial build
+ compiler.hooks.emit.tapAsync('WebpackImageSizesPlugin', runGeneration)
+
+ // Hook for rebuilds in watch mode
+ compiler.hooks.watchRun.tapAsync('WebpackImageSizesPlugin', (compiler, callback) => {
+ console.log('👀 Watch mode: checking for conf-img changes...')
+ runGeneration(null, callback)
+ })
+
+ // Add directories to watch
+ compiler.hooks.afterEnvironment.tap('WebpackImageSizesPlugin', () => {
+ const confImgPath = path.resolve(compiler.context, this.options.confImgPath)
+ const sizesPath = path.join(confImgPath, this.options.sizesSubdir)
+ const tplPath = path.join(confImgPath, this.options.tplSubdir)
+
+ // Add directories to watched dependencies
+ compiler.hooks.compilation.tap('WebpackImageSizesPlugin', (compilation) => {
+ // Watch configuration directories
+ if (fs.existsSync(sizesPath)) {
+ compilation.contextDependencies.add(sizesPath)
+ console.log('📁 Added sizes directory to watch dependencies')
+ }
+ if (fs.existsSync(tplPath)) {
+ compilation.contextDependencies.add(tplPath)
+ console.log('📁 Added tpl directory to watch dependencies')
+ }
+ })
+ })
+ }
+
+ /**
+ * Generates image sizes configuration by parsing JSON files in the sizes directory
+ * and extracting sizes from TPL files.
+ *
+ * @param {string} sizesPath - Path to the sizes directory containing JSON files
+ * @param {string} tplPath - Path to the tpl directory containing template files
+ * @param {Array} imageLocations - Generated image locations to extract additional sizes
+ * @returns {Array} Array containing image sizes configuration object
+ * @memberof WebpackImageSizesPlugin
+ */
+ generateImageSizes(sizesPath, tplPath, imageLocations) {
+ // Completely reset image sizes
+ const imageSizes = [{}]
+ const allSizes = new Set() // To avoid duplicates
+
+ if (!fs.existsSync(sizesPath)) {
+ console.warn(`⚠️ Sizes directory not found: ${sizesPath}`)
+ return imageSizes
+ }
+
+ const sizeFiles = fs.readdirSync(sizesPath).filter((file) => file.endsWith('.json'))
+ console.log(`📋 Processing ${sizeFiles.length} size files: ${sizeFiles.join(', ')}`)
+
+ sizeFiles.forEach((file) => {
+ try {
+ const filePath = path.join(sizesPath, file)
+ const sizesData = JSON.parse(fs.readFileSync(filePath, 'utf8'))
+
+ // Convert sizes to image-sizes.json format
+ sizesData.forEach((size) => {
+ const sizeKey = `img-${size.width}-${size.height}`
+
+ // Avoid duplicates between files
+ if (!allSizes.has(sizeKey)) {
+ allSizes.add(sizeKey)
+ imageSizes[0][sizeKey] = {
+ width: size.width.toString(),
+ height: size.height.toString(),
+ crop: size.crop,
+ }
+ }
+ })
+ } catch (error) {
+ console.error(`❌ Error parsing ${file}:`, error)
+ }
+ })
+
+ // Extract additional sizes from TPL files that are not in JSON files
+ this.extractSizesFromTPLFiles(tplPath, imageLocations, imageSizes[0], allSizes)
+
+ console.log(`📐 Generated ${Object.keys(imageSizes[0]).length} unique image sizes`)
+ return imageSizes
+ }
+
+ /**
+ * Extracts image sizes from TPL files and adds them to the sizes configuration.
+ * This method parses image locations to find sizes that are referenced in TPL files
+ * but not defined in JSON files.
+ *
+ * @param {string} tplPath - Path to the tpl directory
+ * @param {Array} imageLocations - Generated image locations containing srcsets
+ * @param {Object} imageSizesObj - Image sizes object to populate
+ * @param {Set} allSizes - Set of already processed sizes to avoid duplicates
+ * @memberof WebpackImageSizesPlugin
+ */
+ extractSizesFromTPLFiles(tplPath, imageLocations, imageSizesObj, allSizes) {
+ if (!fs.existsSync(tplPath) || !imageLocations[0]) {
+ return
+ }
+
+ // Extract all unique sizes from image locations
+ const tplSizes = new Set()
+
+ Object.values(imageLocations[0]).forEach((locationArray) => {
+ locationArray.forEach((location) => {
+ if (location.srcsets) {
+ location.srcsets.forEach((srcset) => {
+ if (srcset.size && srcset.size.startsWith('img-')) {
+ tplSizes.add(srcset.size)
+ }
+ })
+ }
+ })
+ })
+
+ // Add sizes that are not already defined
+ tplSizes.forEach((sizeKey) => {
+ if (!allSizes.has(sizeKey)) {
+ // Extract width and height from size key (e.g., "img-100-100" -> width: 100, height: 100)
+ const matches = sizeKey.match(/img-(\d+)-(\d+)/)
+ if (matches) {
+ const width = matches[1]
+ const height = matches[2]
+
+ allSizes.add(sizeKey)
+ imageSizesObj[sizeKey] = {
+ width: width,
+ height: height,
+ crop: true, // Default crop value for TPL-extracted sizes
+ }
+
+ console.log(`🎨 Added size from TPL: ${sizeKey}`)
+ }
+ }
+ })
+ }
+
+ /**
+ * Generates image locations configuration by parsing JSON and TPL files.
+ *
+ * @param {string} sizesPath - Path to the sizes directory containing JSON files
+ * @param {string} tplPath - Path to the tpl directory containing template files
+ * @returns {Array} Array containing image locations configuration object
+ * @memberof WebpackImageSizesPlugin
+ */
+ generateImageLocations(sizesPath, tplPath) {
+ // Completely reset image locations
+ const imageLocations = [{}]
+ const processedFiles = new Set() // For tracking processed files
+
+ if (!fs.existsSync(sizesPath)) {
+ console.warn(`⚠️ Sizes directory not found: ${sizesPath}`)
+ return imageLocations
+ }
+
+ // Process JSON files in sizes/ first
+ const sizeFiles = fs.readdirSync(sizesPath).filter((file) => file.endsWith('.json'))
+ console.log(`📋 Processing ${sizeFiles.length} JSON files from sizes/: ${sizeFiles.join(', ')}`)
+
+ sizeFiles.forEach((file) => {
+ try {
+ const filename = path.basename(file, '.json')
+ const filePath = path.join(sizesPath, file)
+ const sizesData = JSON.parse(fs.readFileSync(filePath, 'utf8'))
+
+ // Generate srcsets from sizes
+ const srcsets = sizesData.map((size) => ({
+ size: `img-${size.width}-${size.height}`,
+ }))
+
+ imageLocations[0][filename] = [
+ {
+ srcsets: srcsets,
+ },
+ ]
+
+ processedFiles.add(filename)
+ } catch (error) {
+ console.error(`❌ Error parsing JSON ${file}:`, error)
+ }
+ })
+
+ // Then process TPL files for unprocessed or missing files
+ if (fs.existsSync(tplPath)) {
+ const tplFiles = fs.readdirSync(tplPath).filter((file) => file.endsWith('.tpl'))
+ console.log(`📋 Processing ${tplFiles.length} TPL files: ${tplFiles.join(', ')}`)
+
+ tplFiles.forEach((file) => {
+ try {
+ const filename = path.basename(file, '.tpl')
+ const filePath = path.join(tplPath, file)
+ const tplContent = fs.readFileSync(filePath, 'utf8')
+
+ // Extract sizes from templates (pattern %%img-width-height%%)
+ const sizeMatches = tplContent.match(/%%img-(\d+)-(\d+)%%/g)
+
+ // Process only if not already processed by a JSON file or no JSON match
+ if (sizeMatches && !processedFiles.has(filename)) {
+ const srcsets = [...new Set(sizeMatches)].map((match) => {
+ const size = match.replace(/%%/g, '')
+ return { size }
+ })
+
+ imageLocations[0][filename] = [
+ {
+ srcsets: srcsets,
+ },
+ ]
+
+ processedFiles.add(filename)
+ console.log(`📝 Added location from TPL: ${filename}`)
+ }
+ } catch (error) {
+ console.error(`❌ Error parsing TPL ${file}:`, error)
+ }
+ })
+ }
+
+ const totalEntries = Object.keys(imageLocations[0]).length
+ console.log(`📍 Generated ${totalEntries} image locations (${processedFiles.size} files processed)`)
+
+ // Log processed files for debugging
+ if (processedFiles.size > 0) {
+ console.log(`✅ Processed files: ${Array.from(processedFiles).join(', ')}`)
+ }
+
+ return imageLocations
+ }
+
+ /**
+ * Generates default images from the source image based on image sizes configuration.
+ *
+ * @param {string} compilerContext - The webpack compiler context path
+ * @param {Array} imageSizes - Array containing image sizes configuration
+ * @memberof WebpackImageSizesPlugin
+ */
+ async generateDefaultImages(compilerContext, imageSizes) {
+ if (!sharp) {
+ console.warn('⚠️ Sharp not available. Skipping default image generation.')
+ return
+ }
+
+ const sourceImagePath = path.resolve(compilerContext, this.options.defaultImageSource)
+ const outputDir = path.resolve(compilerContext, this.options.defaultImagesOutputDir)
+
+ if (!fs.existsSync(sourceImagePath)) {
+ console.warn(`⚠️ Source image not found: ${sourceImagePath}`)
+ return
+ }
+
+ if (!fs.existsSync(outputDir)) {
+ fs.mkdirSync(outputDir, { recursive: true })
+ }
+
+ const sizesObj = imageSizes[0] || {}
+ const sizeKeys = Object.keys(sizesObj)
+ const format = this.options.defaultImageFormat.toLowerCase()
+
+ // Validate format
+ const supportedFormats = ['jpg', 'jpeg', 'png', 'webp', 'avif']
+ if (!supportedFormats.includes(format)) {
+ console.warn(`⚠️ Unsupported format '${format}'. Using 'jpg' instead.`)
+ this.options.defaultImageFormat = 'jpg'
+ }
+
+ console.log(
+ `🖼️ Generating ${sizeKeys.length} default images (${format.toUpperCase()}) from ${
+ this.options.defaultImageSource
+ }`
+ )
+
+ const promises = sizeKeys.map(async (sizeKey) => {
+ const size = sizesObj[sizeKey]
+ const width = parseInt(size.width)
+ const height = parseInt(size.height)
+ const outputFilename = `default-${width}-${height}.${this.options.defaultImageFormat}`
+ const outputPath = path.join(outputDir, outputFilename)
+
+ try {
+ let sharpInstance = sharp(sourceImagePath)
+
+ if (size.crop) {
+ // Crop and resize to exact dimensions
+ sharpInstance = sharpInstance.resize(width, height, {
+ fit: 'cover',
+ position: 'center',
+ })
+ } else {
+ // Resize maintaining aspect ratio
+ sharpInstance = sharpInstance.resize(width, height, {
+ fit: 'inside',
+ withoutEnlargement: false,
+ })
+ }
+
+ // Apply format-specific options
+ const formatOptions = this.getFormatOptions(this.options.defaultImageFormat)
+ await sharpInstance[formatOptions.method](formatOptions.options).toFile(outputPath)
+
+ console.log(`✨ Generated: ${outputFilename} (${width}x${height}${size.crop ? ', cropped' : ''})`)
+ } catch (error) {
+ console.error(`❌ Error generating ${outputFilename}:`, error.message)
+ }
+ })
+
+ await Promise.all(promises)
+ console.log(`🎉 Default image generation completed!`)
+ }
+
+ /**
+ * Gets format-specific Sharp options for different image formats.
+ *
+ * @param {string} format - The image format (jpg, png, webp, avif)
+ * @returns {Object} Object containing Sharp method and options
+ * @memberof WebpackImageSizesPlugin
+ */
+ getFormatOptions(format) {
+ const formatLower = format.toLowerCase()
+
+ const formatConfigs = {
+ jpg: {
+ method: 'jpeg',
+ options: { quality: 80, progressive: true },
+ },
+ jpeg: {
+ method: 'jpeg',
+ options: { quality: 80, progressive: true },
+ },
+ png: {
+ method: 'png',
+ options: { quality: 80, progressive: true },
+ },
+ webp: {
+ method: 'webp',
+ options: { quality: 80, effort: 4 },
+ },
+ avif: {
+ method: 'avif',
+ options: { quality: 80, effort: 4 },
+ },
+ }
+
+ return formatConfigs[formatLower] || formatConfigs.jpg
+ }
+
+ /**
+ * Checks for deleted or renamed files by comparing current files with existing configuration.
+ *
+ * @param {string} confImgPath - Path to the conf-img directory
+ * @param {string} sizesPath - Path to the sizes directory
+ * @param {string} tplPath - Path to the tpl directory
+ * @memberof WebpackImageSizesPlugin
+ */
+ checkForDeletedFiles(confImgPath, sizesPath, tplPath) {
+ const imageLocationsPath = path.join(confImgPath, this.options.outputImageLocations)
+
+ // Check if image-locations.json file already exists
+ if (!fs.existsSync(imageLocationsPath)) {
+ console.log('📄 No existing image-locations.json found, creating fresh files')
+ return
+ }
+
+ try {
+ // Read existing file
+ const existingData = JSON.parse(fs.readFileSync(imageLocationsPath, 'utf8'))
+ const existingEntries = Object.keys(existingData[0] || {})
+
+ // Get current files
+ const currentSizeFiles = fs.existsSync(sizesPath)
+ ? fs
+ .readdirSync(sizesPath)
+ .filter((file) => file.endsWith('.json'))
+ .map((file) => path.basename(file, '.json'))
+ : []
+
+ const currentTplFiles = fs.existsSync(tplPath)
+ ? fs
+ .readdirSync(tplPath)
+ .filter((file) => file.endsWith('.tpl'))
+ .map((file) => path.basename(file, '.tpl'))
+ : []
+
+ const currentFiles = [...new Set([...currentSizeFiles, ...currentTplFiles])]
+
+ // Detect deleted files
+ const deletedFiles = existingEntries.filter((entry) => !currentFiles.includes(entry))
+
+ if (deletedFiles.length > 0) {
+ console.log(`🗑️ Detected ${deletedFiles.length} deleted/renamed files: ${deletedFiles.join(', ')}`)
+ console.log(' → These entries will be removed from generated files')
+ }
+
+ // Detect new files
+ const newFiles = currentFiles.filter((file) => !existingEntries.includes(file))
+
+ if (newFiles.length > 0) {
+ console.log(`📂 Detected ${newFiles.length} new files: ${newFiles.join(', ')}`)
+ console.log(' → These entries will be added to generated files')
+ }
+
+ if (deletedFiles.length === 0 && newFiles.length === 0) {
+ console.log('📋 No file changes detected')
+ }
+ } catch (error) {
+ console.warn('⚠️ Could not read existing image-locations.json:', error.message)
+ }
+ }
+}
+
+module.exports = WebpackImageSizesPlugin
diff --git a/package.json b/package.json
index d0362d5b..847a0128 100644
--- a/package.json
+++ b/package.json
@@ -17,7 +17,6 @@
"license": "GPL-2.0",
"dependencies": {
"@fontsource/poppins": "^5.0.5",
- "lazysizes": "^5.3.2",
"oneloop.js": "^5.2.1"
},
"devDependencies": {
@@ -53,7 +52,7 @@
"prettier": "^2.2.1",
"sass": "^1.85.1",
"sass-loader": "^16.0.5",
- "sharp": "^0.32.1",
+ "sharp": "^0.34.2",
"style-loader": "^2.0.0",
"stylelint": "^14.13.0",
"stylelint-config-recess-order": "^3.0.0",
diff --git a/src/js/editor.js b/src/js/editor.js
index fbed2e49..771566b5 100644
--- a/src/js/editor.js
+++ b/src/js/editor.js
@@ -2,21 +2,10 @@
/* Customize BFFEditorSettings in inc/Services/Editor.php or with `bff_editor_custom_settings` filter (see readme). */
-import lazySizes from 'lazysizes'
-import 'lazysizes/plugins/native-loading/ls.native-loading'
-import 'lazysizes/plugins/object-fit/ls.object-fit'
import domReady from '@wordpress/dom-ready'
import { addFilter } from '@wordpress/hooks'
import { unregisterBlockStyle, getBlockVariations, unregisterBlockVariation } from '@wordpress/blocks'
-/**
- * LazySizes configuration
- * https://github.com/aFarkas/lazysizes/#js-api---options
- */
-lazySizes.cfg.nativeLoading = {
- setLoadingAttribute: false,
-}
-
// Native Gutenberg
domReady(() => {
// Disable specific block styles
diff --git a/src/js/index.js b/src/js/index.js
index 7a6f043e..64b490f0 100644
--- a/src/js/index.js
+++ b/src/js/index.js
@@ -1,5 +1,3 @@
-import 'lazysizes'
-import 'lazysizes/plugins/print/ls.print'
import './classes/ScrollDirection'
import './classes/ButtonSeoClick'
import './classes/Header'
diff --git a/src/scss/02-tools/_m-placeholder-media.scss b/src/scss/02-tools/_m-placeholder-media.scss
index 9ac0b2d2..dc71bb17 100644
--- a/src/scss/02-tools/_m-placeholder-media.scss
+++ b/src/scss/02-tools/_m-placeholder-media.scss
@@ -28,11 +28,6 @@
content: "";
}
- .lazyload,
- .lazyloading {
- height: 0;
- }
-
#{$targets} {
position: absolute;
top: 0;
diff --git a/src/scss/04-utilities/_lazyload.scss b/src/scss/04-utilities/_lazyload.scss
deleted file mode 100644
index c2a4753e..00000000
--- a/src/scss/04-utilities/_lazyload.scss
+++ /dev/null
@@ -1,77 +0,0 @@
-@use "../01-abstract/variables" as *;
-@use "sass:math";
-
-.lazyload,
-.lazyloading {
- background: $color-primary;
- opacity: 0;
-}
-
-.lazyloaded {
- opacity: 1;
- transition: opacity .5s;
-}
-
-// css loading for bgset items
-// with basicspinner
-$loading-dimensions: 50px;
-
-[data-bgset] {
- position: relative;
- background-repeat: no-repeat;
- background-position: 50% 50%;
- background-size: cover;
- opacity: 1;
-
- &::before {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- z-index: 2;
- content: "";
- background: $color-primary;
- transition: opacity .5s, z-index .5s ease .5s;
- }
-
- &::after {
- position: absolute;
- top: calc(50% - #{math.div($loading-dimensions, 2)});
- left: calc(50% - #{math.div($loading-dimensions, 2)});
- z-index: 3;
- width: $loading-dimensions;
- height: $loading-dimensions;
- content: "";
- border: 5px solid $color-light;
- border-top-color: transparent;
- border-radius: $loading-dimensions;
- opacity: 1;
- transition: opacity .5s, z-index .5s ease .5s;
- transform: translateX(-50%) translateY(-50%);
- animation: loading .5s linear infinite;
- }
-
- &.lazyload {
- opacity: 1;
- transition: opacity .5s;
- }
-
- &.lazyloaded {
- &::after,
- &::before {
- z-index: -1;
- opacity: 0;
- }
- }
-}
-
-@keyframes loading {
- 0% {
- transform: rotate(0deg);
- }
-
- 100% {
- transform: rotate(360deg);
- }
-}
diff --git a/src/scss/editor.scss b/src/scss/editor.scss
index 6e86ec30..25207cf4 100644
--- a/src/scss/editor.scss
+++ b/src/scss/editor.scss
@@ -27,7 +27,6 @@ variables.$entry-file-name: "editor";
@use "04-utilities/wp-admin-bar";
@use "04-utilities/focus";
-@use "04-utilities/lazyload";
@use "04-utilities/seo";
@use "04-utilities/video-wrapper";
@use "04-utilities/palette";
diff --git a/src/scss/style.scss b/src/scss/style.scss
index 4ee6e41e..75d19422 100644
--- a/src/scss/style.scss
+++ b/src/scss/style.scss
@@ -31,7 +31,6 @@ variables.$entry-file-name: "style";
@use "04-utilities/wp-admin-bar";
@use "04-utilities/focus";
-@use "04-utilities/lazyload";
@use "04-utilities/seo";
@use "04-utilities/video-wrapper";
@use "04-utilities/palette";
diff --git a/yarn.lock b/yarn.lock
index a313ba09..60bcc8c9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -409,6 +409,15 @@ __metadata:
languageName: node
linkType: hard
+"@emnapi/runtime@npm:^1.4.3":
+ version: 1.4.3
+ resolution: "@emnapi/runtime@npm:1.4.3"
+ dependencies:
+ tslib: "npm:^2.4.0"
+ checksum: 10/4f90852a1a5912982cc4e176b6420556971bcf6a85ee23e379e2455066d616219751367dcf43e6a6eaf41ea7e95ba9dc830665a52b5d979dfe074237d19578f8
+ languageName: node
+ linkType: hard
+
"@esbuild/android-arm64@npm:0.16.17":
version: 0.16.17
resolution: "@esbuild/android-arm64@npm:0.16.17"
@@ -662,6 +671,195 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-darwin-arm64@npm:0.34.2":
+ version: 0.34.2
+ resolution: "@img/sharp-darwin-arm64@npm:0.34.2"
+ dependencies:
+ "@img/sharp-libvips-darwin-arm64": "npm:1.1.0"
+ dependenciesMeta:
+ "@img/sharp-libvips-darwin-arm64":
+ optional: true
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@img/sharp-darwin-x64@npm:0.34.2":
+ version: 0.34.2
+ resolution: "@img/sharp-darwin-x64@npm:0.34.2"
+ dependencies:
+ "@img/sharp-libvips-darwin-x64": "npm:1.1.0"
+ dependenciesMeta:
+ "@img/sharp-libvips-darwin-x64":
+ optional: true
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@img/sharp-libvips-darwin-arm64@npm:1.1.0":
+ version: 1.1.0
+ resolution: "@img/sharp-libvips-darwin-arm64@npm:1.1.0"
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@img/sharp-libvips-darwin-x64@npm:1.1.0":
+ version: 1.1.0
+ resolution: "@img/sharp-libvips-darwin-x64@npm:1.1.0"
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@img/sharp-libvips-linux-arm64@npm:1.1.0":
+ version: 1.1.0
+ resolution: "@img/sharp-libvips-linux-arm64@npm:1.1.0"
+ conditions: os=linux & cpu=arm64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@img/sharp-libvips-linux-arm@npm:1.1.0":
+ version: 1.1.0
+ resolution: "@img/sharp-libvips-linux-arm@npm:1.1.0"
+ conditions: os=linux & cpu=arm & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@img/sharp-libvips-linux-ppc64@npm:1.1.0":
+ version: 1.1.0
+ resolution: "@img/sharp-libvips-linux-ppc64@npm:1.1.0"
+ conditions: os=linux & cpu=ppc64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@img/sharp-libvips-linux-s390x@npm:1.1.0":
+ version: 1.1.0
+ resolution: "@img/sharp-libvips-linux-s390x@npm:1.1.0"
+ conditions: os=linux & cpu=s390x & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@img/sharp-libvips-linux-x64@npm:1.1.0":
+ version: 1.1.0
+ resolution: "@img/sharp-libvips-linux-x64@npm:1.1.0"
+ conditions: os=linux & cpu=x64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@img/sharp-libvips-linuxmusl-arm64@npm:1.1.0":
+ version: 1.1.0
+ resolution: "@img/sharp-libvips-linuxmusl-arm64@npm:1.1.0"
+ conditions: os=linux & cpu=arm64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@img/sharp-libvips-linuxmusl-x64@npm:1.1.0":
+ version: 1.1.0
+ resolution: "@img/sharp-libvips-linuxmusl-x64@npm:1.1.0"
+ conditions: os=linux & cpu=x64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@img/sharp-linux-arm64@npm:0.34.2":
+ version: 0.34.2
+ resolution: "@img/sharp-linux-arm64@npm:0.34.2"
+ dependencies:
+ "@img/sharp-libvips-linux-arm64": "npm:1.1.0"
+ dependenciesMeta:
+ "@img/sharp-libvips-linux-arm64":
+ optional: true
+ conditions: os=linux & cpu=arm64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@img/sharp-linux-arm@npm:0.34.2":
+ version: 0.34.2
+ resolution: "@img/sharp-linux-arm@npm:0.34.2"
+ dependencies:
+ "@img/sharp-libvips-linux-arm": "npm:1.1.0"
+ dependenciesMeta:
+ "@img/sharp-libvips-linux-arm":
+ optional: true
+ conditions: os=linux & cpu=arm & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@img/sharp-linux-s390x@npm:0.34.2":
+ version: 0.34.2
+ resolution: "@img/sharp-linux-s390x@npm:0.34.2"
+ dependencies:
+ "@img/sharp-libvips-linux-s390x": "npm:1.1.0"
+ dependenciesMeta:
+ "@img/sharp-libvips-linux-s390x":
+ optional: true
+ conditions: os=linux & cpu=s390x & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@img/sharp-linux-x64@npm:0.34.2":
+ version: 0.34.2
+ resolution: "@img/sharp-linux-x64@npm:0.34.2"
+ dependencies:
+ "@img/sharp-libvips-linux-x64": "npm:1.1.0"
+ dependenciesMeta:
+ "@img/sharp-libvips-linux-x64":
+ optional: true
+ conditions: os=linux & cpu=x64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@img/sharp-linuxmusl-arm64@npm:0.34.2":
+ version: 0.34.2
+ resolution: "@img/sharp-linuxmusl-arm64@npm:0.34.2"
+ dependencies:
+ "@img/sharp-libvips-linuxmusl-arm64": "npm:1.1.0"
+ dependenciesMeta:
+ "@img/sharp-libvips-linuxmusl-arm64":
+ optional: true
+ conditions: os=linux & cpu=arm64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@img/sharp-linuxmusl-x64@npm:0.34.2":
+ version: 0.34.2
+ resolution: "@img/sharp-linuxmusl-x64@npm:0.34.2"
+ dependencies:
+ "@img/sharp-libvips-linuxmusl-x64": "npm:1.1.0"
+ dependenciesMeta:
+ "@img/sharp-libvips-linuxmusl-x64":
+ optional: true
+ conditions: os=linux & cpu=x64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@img/sharp-wasm32@npm:0.34.2":
+ version: 0.34.2
+ resolution: "@img/sharp-wasm32@npm:0.34.2"
+ dependencies:
+ "@emnapi/runtime": "npm:^1.4.3"
+ conditions: cpu=wasm32
+ languageName: node
+ linkType: hard
+
+"@img/sharp-win32-arm64@npm:0.34.2":
+ version: 0.34.2
+ resolution: "@img/sharp-win32-arm64@npm:0.34.2"
+ conditions: os=win32 & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@img/sharp-win32-ia32@npm:0.34.2":
+ version: 0.34.2
+ resolution: "@img/sharp-win32-ia32@npm:0.34.2"
+ conditions: os=win32 & cpu=ia32
+ languageName: node
+ linkType: hard
+
+"@img/sharp-win32-x64@npm:0.34.2":
+ version: 0.34.2
+ resolution: "@img/sharp-win32-x64@npm:0.34.2"
+ conditions: os=win32 & cpu=x64
+ languageName: node
+ linkType: hard
+
"@isaacs/cliui@npm:^8.0.2":
version: 8.0.2
resolution: "@isaacs/cliui@npm:8.0.2"
@@ -2003,13 +2201,6 @@ __metadata:
languageName: node
linkType: hard
-"b4a@npm:^1.6.4":
- version: 1.6.7
- resolution: "b4a@npm:1.6.7"
- checksum: 10/1ac056e3bce378d4d3e570e57319360a9d3125ab6916a1921b95bea33d9ee646698ebc75467561fd6fcc80ff697612124c89bb9b95e80db94c6dc23fcb977705
- languageName: node
- linkType: hard
-
"balanced-match@npm:^1.0.0":
version: 1.0.2
resolution: "balanced-match@npm:1.0.2"
@@ -2024,62 +2215,6 @@ __metadata:
languageName: node
linkType: hard
-"bare-events@npm:^2.2.0, bare-events@npm:^2.5.4":
- version: 2.5.4
- resolution: "bare-events@npm:2.5.4"
- checksum: 10/135ef380b13f554ca2c6905bdbcfac8edae08fce85b7f953fa01f09a9f5b0da6a25e414111659bc9a6118216f0dd1f732016acd11ce91517f2afb26ebeb4b721
- languageName: node
- linkType: hard
-
-"bare-fs@npm:^4.0.1":
- version: 4.1.2
- resolution: "bare-fs@npm:4.1.2"
- dependencies:
- bare-events: "npm:^2.5.4"
- bare-path: "npm:^3.0.0"
- bare-stream: "npm:^2.6.4"
- peerDependencies:
- bare-buffer: "*"
- peerDependenciesMeta:
- bare-buffer:
- optional: true
- checksum: 10/e64d22d0311a71a23919e33b8f1c2ea9f5a6260c468c9c70bdd248efdf356b4d5a36754d5f502f526ca5ff5544a780afdd73cd66fcc38ba00003e99287a69f37
- languageName: node
- linkType: hard
-
-"bare-os@npm:^3.0.1":
- version: 3.6.1
- resolution: "bare-os@npm:3.6.1"
- checksum: 10/285d95c391250166128e64da2947f4a348ae127de680afffec1f6c82445856be0d1f259672b471afe06517e4cd3831183c373a1d63ef7799ed4aaa1321b86b67
- languageName: node
- linkType: hard
-
-"bare-path@npm:^3.0.0":
- version: 3.0.0
- resolution: "bare-path@npm:3.0.0"
- dependencies:
- bare-os: "npm:^3.0.1"
- checksum: 10/712d90e9cd8c3263cc11b0e0d386d1531a452706d7840c081ee586b34b00d72544e65df7a40013d47c1b177277495225deeede65cb2984db88a979cb65aaa2ff
- languageName: node
- linkType: hard
-
-"bare-stream@npm:^2.6.4":
- version: 2.6.5
- resolution: "bare-stream@npm:2.6.5"
- dependencies:
- streamx: "npm:^2.21.0"
- peerDependencies:
- bare-buffer: "*"
- bare-events: "*"
- peerDependenciesMeta:
- bare-buffer:
- optional: true
- bare-events:
- optional: true
- checksum: 10/0f5ca2167fbbccc118157bce7c53a933e21726268e03d751461211550d72b2d01c296b767ccf96aae8ab28e106b126407c6fe0d29f915734b844ffe6057f0a08
- languageName: node
- linkType: hard
-
"base64-js@npm:^1.3.1":
version: 1.5.1
resolution: "base64-js@npm:1.5.1"
@@ -2137,7 +2272,6 @@ __metadata:
imagemin-jpegtran: "npm:^7.0.0"
imagemin-optipng: "npm:^8.0.0"
imagemin-svgo: "npm:^10.0.1"
- lazysizes: "npm:^5.3.2"
mini-css-extract-plugin: "npm:^1.5.0"
oneloop.js: "npm:^5.2.1"
postcss: "npm:^8.4.24"
@@ -2150,7 +2284,7 @@ __metadata:
prettier: "npm:^2.2.1"
sass: "npm:^1.85.1"
sass-loader: "npm:^16.0.5"
- sharp: "npm:^0.32.1"
+ sharp: "npm:^0.34.2"
style-loader: "npm:^2.0.0"
stylelint: "npm:^14.13.0"
stylelint-config-recess-order: "npm:^3.0.0"
@@ -2244,17 +2378,6 @@ __metadata:
languageName: node
linkType: hard
-"bl@npm:^4.0.3":
- version: 4.1.0
- resolution: "bl@npm:4.1.0"
- dependencies:
- buffer: "npm:^5.5.0"
- inherits: "npm:^2.0.4"
- readable-stream: "npm:^3.4.0"
- checksum: 10/b7904e66ed0bdfc813c06ea6c3e35eafecb104369dbf5356d0f416af90c1546de3b74e5b63506f0629acf5e16a6f87c3798f16233dcff086e9129383aa02ab55
- languageName: node
- linkType: hard
-
"bluebird@npm:^3.5.0":
version: 3.7.2
resolution: "bluebird@npm:3.7.2"
@@ -2367,7 +2490,7 @@ __metadata:
languageName: node
linkType: hard
-"buffer@npm:^5.2.1, buffer@npm:^5.5.0":
+"buffer@npm:^5.2.1":
version: 5.7.1
resolution: "buffer@npm:5.7.1"
dependencies:
@@ -2638,13 +2761,6 @@ __metadata:
languageName: node
linkType: hard
-"chownr@npm:^1.1.1":
- version: 1.1.4
- resolution: "chownr@npm:1.1.4"
- checksum: 10/115648f8eb38bac5e41c3857f3e663f9c39ed6480d1349977c4d96c95a47266fcacc5a5aabf3cb6c481e22d72f41992827db47301851766c4fd77ac21a4f081d
- languageName: node
- linkType: hard
-
"chownr@npm:^3.0.0":
version: 3.0.0
resolution: "chownr@npm:3.0.0"
@@ -3373,15 +3489,6 @@ __metadata:
languageName: node
linkType: hard
-"decompress-response@npm:^6.0.0":
- version: 6.0.0
- resolution: "decompress-response@npm:6.0.0"
- dependencies:
- mimic-response: "npm:^3.1.0"
- checksum: 10/d377cf47e02d805e283866c3f50d3d21578b779731e8c5072d6ce8c13cc31493db1c2f6784da9d1d5250822120cefa44f1deab112d5981015f2e17444b763812
- languageName: node
- linkType: hard
-
"decompress-tar@npm:^4.0.0, decompress-tar@npm:^4.1.0, decompress-tar@npm:^4.1.1":
version: 4.1.1
resolution: "decompress-tar@npm:4.1.1"
@@ -3445,13 +3552,6 @@ __metadata:
languageName: node
linkType: hard
-"deep-extend@npm:^0.6.0":
- version: 0.6.0
- resolution: "deep-extend@npm:0.6.0"
- checksum: 10/7be7e5a8d468d6b10e6a67c3de828f55001b6eb515d014f7aeb9066ce36bd5717161eb47d6a0f7bed8a9083935b465bc163ee2581c8b128d29bf61092fdf57a7
- languageName: node
- linkType: hard
-
"deep-is@npm:^0.1.3":
version: 0.1.4
resolution: "deep-is@npm:0.1.4"
@@ -3547,10 +3647,10 @@ __metadata:
languageName: node
linkType: hard
-"detect-libc@npm:^2.0.0, detect-libc@npm:^2.0.2":
- version: 2.0.3
- resolution: "detect-libc@npm:2.0.3"
- checksum: 10/b4ea018d623e077bd395f168a9e81db77370dde36a5b01d067f2ad7989924a81d31cb547ff764acb2aa25d50bb7fdde0b0a93bec02212b0cb430621623246d39
+"detect-libc@npm:^2.0.4":
+ version: 2.0.4
+ resolution: "detect-libc@npm:2.0.4"
+ checksum: 10/136e995f8c5ffbc515955b0175d441b967defd3d5f2268e89fa695e9c7170d8bed17993e31a34b04f0fad33d844a3a598e0fd519a8e9be3cad5f67662d96fee0
languageName: node
linkType: hard
@@ -3809,7 +3909,7 @@ __metadata:
languageName: node
linkType: hard
-"end-of-stream@npm:^1.0.0, end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1":
+"end-of-stream@npm:^1.0.0, end-of-stream@npm:^1.1.0":
version: 1.4.4
resolution: "end-of-stream@npm:1.4.4"
dependencies:
@@ -4436,13 +4536,6 @@ __metadata:
languageName: node
linkType: hard
-"expand-template@npm:^2.0.3":
- version: 2.0.3
- resolution: "expand-template@npm:2.0.3"
- checksum: 10/588c19847216421ed92befb521767b7018dc88f88b0576df98cb242f20961425e96a92cbece525ef28cc5becceae5d544ae0f5b9b5e2aa05acb13716ca5b3099
- languageName: node
- linkType: hard
-
"exponential-backoff@npm:^3.1.1":
version: 3.1.2
resolution: "exponential-backoff@npm:3.1.2"
@@ -4518,13 +4611,6 @@ __metadata:
languageName: node
linkType: hard
-"fast-fifo@npm:^1.2.0, fast-fifo@npm:^1.3.2":
- version: 1.3.2
- resolution: "fast-fifo@npm:1.3.2"
- checksum: 10/6bfcba3e4df5af7be3332703b69a7898a8ed7020837ec4395bb341bd96cc3a6d86c3f6071dd98da289618cf2234c70d84b2a6f09a33dd6f988b1ff60d8e54275
- languageName: node
- linkType: hard
-
"fast-glob@npm:^3.2.12, fast-glob@npm:^3.2.7, fast-glob@npm:^3.2.9":
version: 3.3.3
resolution: "fast-glob@npm:3.3.3"
@@ -5049,13 +5135,6 @@ __metadata:
languageName: node
linkType: hard
-"github-from-package@npm:0.0.0":
- version: 0.0.0
- resolution: "github-from-package@npm:0.0.0"
- checksum: 10/2a091ba07fbce22205642543b4ea8aaf068397e1433c00ae0f9de36a3607baf5bcc14da97fbb798cfca6393b3c402031fca06d8b491a44206d6efef391c58537
- languageName: node
- linkType: hard
-
"glob-parent@npm:^5.1.2":
version: 5.1.2
resolution: "glob-parent@npm:5.1.2"
@@ -5792,14 +5871,14 @@ __metadata:
languageName: node
linkType: hard
-"inherits@npm:2, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3":
+"inherits@npm:2, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:~2.0.3":
version: 2.0.4
resolution: "inherits@npm:2.0.4"
checksum: 10/cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521
languageName: node
linkType: hard
-"ini@npm:^1.3.4, ini@npm:^1.3.5, ini@npm:~1.3.0":
+"ini@npm:^1.3.4, ini@npm:^1.3.5":
version: 1.3.8
resolution: "ini@npm:1.3.8"
checksum: 10/314ae176e8d4deb3def56106da8002b462221c174ddb7ce0c49ee72c8cd1f9044f7b10cc555a7d8850982c3b9ca96fc212122749f5234bc2b6fb05fb942ed566
@@ -6624,13 +6703,6 @@ __metadata:
languageName: node
linkType: hard
-"lazysizes@npm:^5.3.2":
- version: 5.3.2
- resolution: "lazysizes@npm:5.3.2"
- checksum: 10/15dfa1cc8bf8c3a4393014d411f161cb1df96ab0888a0776ba4dc34d45c6ba9c5d2b2eca22683c14dfeee552c67173cb9a512d640d3424d9910c0246e15c4edc
- languageName: node
- linkType: hard
-
"levn@npm:^0.4.1":
version: 0.4.1
resolution: "levn@npm:0.4.1"
@@ -7106,13 +7178,6 @@ __metadata:
languageName: node
linkType: hard
-"mimic-response@npm:^3.1.0":
- version: 3.1.0
- resolution: "mimic-response@npm:3.1.0"
- checksum: 10/7e719047612411fe071332a7498cf0448bbe43c485c0d780046c76633a771b223ff49bd00267be122cedebb897037fdb527df72335d0d0f74724604ca70b37ad
- languageName: node
- linkType: hard
-
"min-indent@npm:^1.0.0":
version: 1.0.1
resolution: "min-indent@npm:1.0.1"
@@ -7162,7 +7227,7 @@ __metadata:
languageName: node
linkType: hard
-"minimist@npm:^1.1.3, minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.6":
+"minimist@npm:^1.1.3, minimist@npm:^1.2.0, minimist@npm:^1.2.6":
version: 1.2.8
resolution: "minimist@npm:1.2.8"
checksum: 10/908491b6cc15a6c440ba5b22780a0ba89b9810e1aea684e253e43c4e3b8d56ec1dcdd7ea96dde119c29df59c936cde16062159eae4225c691e19c70b432b6e6f
@@ -7262,13 +7327,6 @@ __metadata:
languageName: node
linkType: hard
-"mkdirp-classic@npm:^0.5.2, mkdirp-classic@npm:^0.5.3":
- version: 0.5.3
- resolution: "mkdirp-classic@npm:0.5.3"
- checksum: 10/3f4e088208270bbcc148d53b73e9a5bd9eef05ad2cbf3b3d0ff8795278d50dd1d11a8ef1875ff5aea3fa888931f95bfcb2ad5b7c1061cfefd6284d199e6776ac
- languageName: node
- linkType: hard
-
"mkdirp@npm:^3.0.1":
version: 3.0.1
resolution: "mkdirp@npm:3.0.1"
@@ -7341,13 +7399,6 @@ __metadata:
languageName: node
linkType: hard
-"napi-build-utils@npm:^2.0.0":
- version: 2.0.0
- resolution: "napi-build-utils@npm:2.0.0"
- checksum: 10/69adcdb828481737f1ec64440286013f6479d5b264e24d5439ba795f65293d0bb6d962035de07c65fae525ed7d2fcd0baab6891d8e3734ea792fec43918acf83
- languageName: node
- linkType: hard
-
"natural-compare@npm:^1.4.0":
version: 1.4.0
resolution: "natural-compare@npm:1.4.0"
@@ -7386,24 +7437,6 @@ __metadata:
languageName: node
linkType: hard
-"node-abi@npm:^3.3.0":
- version: 3.74.0
- resolution: "node-abi@npm:3.74.0"
- dependencies:
- semver: "npm:^7.3.5"
- checksum: 10/314ba5f773690e12a3d87b967d509e9badf16bf2a8ba7619104794f9594545dd268a42f34817d3c81402bf1dc6308545456e2fa9c0200bb6e648cfb75addbe66
- languageName: node
- linkType: hard
-
-"node-addon-api@npm:^6.1.0":
- version: 6.1.0
- resolution: "node-addon-api@npm:6.1.0"
- dependencies:
- node-gyp: "npm:latest"
- checksum: 10/8eea1d4d965930a177a0508695beb0d89b4c1d80bf330646a035357a1e8fc31e0d09686e2374996e96e757b947a7ece319f98ede3146683f162597c0bcb4df90
- languageName: node
- linkType: hard
-
"node-addon-api@npm:^7.0.0":
version: 7.1.1
resolution: "node-addon-api@npm:7.1.1"
@@ -9016,28 +9049,6 @@ __metadata:
languageName: node
linkType: hard
-"prebuild-install@npm:^7.1.1":
- version: 7.1.3
- resolution: "prebuild-install@npm:7.1.3"
- dependencies:
- detect-libc: "npm:^2.0.0"
- expand-template: "npm:^2.0.3"
- github-from-package: "npm:0.0.0"
- minimist: "npm:^1.2.3"
- mkdirp-classic: "npm:^0.5.3"
- napi-build-utils: "npm:^2.0.0"
- node-abi: "npm:^3.3.0"
- pump: "npm:^3.0.0"
- rc: "npm:^1.2.7"
- simple-get: "npm:^4.0.0"
- tar-fs: "npm:^2.0.0"
- tunnel-agent: "npm:^0.6.0"
- bin:
- prebuild-install: bin.js
- checksum: 10/1b7e4c00d2750b532a4fc2a83ffb0c5fefa1b6f2ad071896ead15eeadc3255f5babd816949991af083cf7429e375ae8c7d1c51f73658559da36f948a020a3a11
- languageName: node
- linkType: hard
-
"prelude-ls@npm:^1.2.1":
version: 1.2.1
resolution: "prelude-ls@npm:1.2.1"
@@ -9199,20 +9210,6 @@ __metadata:
languageName: node
linkType: hard
-"rc@npm:^1.2.7":
- version: 1.2.8
- resolution: "rc@npm:1.2.8"
- dependencies:
- deep-extend: "npm:^0.6.0"
- ini: "npm:~1.3.0"
- minimist: "npm:^1.2.0"
- strip-json-comments: "npm:~2.0.1"
- bin:
- rc: ./cli.js
- checksum: 10/5c4d72ae7eec44357171585938c85ce066da8ca79146b5635baf3d55d74584c92575fa4e2c9eac03efbed3b46a0b2e7c30634c012b4b4fa40d654353d3c163eb
- languageName: node
- linkType: hard
-
"react-dom@npm:^17.0.2":
version: 17.0.2
resolution: "react-dom@npm:17.0.2"
@@ -9315,7 +9312,7 @@ __metadata:
languageName: node
linkType: hard
-"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0":
+"readable-stream@npm:^3.1.1":
version: 3.6.2
resolution: "readable-stream@npm:3.6.2"
dependencies:
@@ -9888,6 +9885,15 @@ __metadata:
languageName: node
linkType: hard
+"semver@npm:^7.7.2":
+ version: 7.7.2
+ resolution: "semver@npm:7.7.2"
+ bin:
+ semver: bin/semver.js
+ checksum: 10/7a24cffcaa13f53c09ce55e05efe25cd41328730b2308678624f8b9f5fc3093fc4d189f47950f0b811ff8f3c3039c24a2c36717ba7961615c682045bf03e1dda
+ languageName: node
+ linkType: hard
+
"sentence-case@npm:^3.0.4":
version: 3.0.4
resolution: "sentence-case@npm:3.0.4"
@@ -9980,20 +9986,78 @@ __metadata:
languageName: node
linkType: hard
-"sharp@npm:^0.32.1":
- version: 0.32.6
- resolution: "sharp@npm:0.32.6"
- dependencies:
+"sharp@npm:^0.34.2":
+ version: 0.34.2
+ resolution: "sharp@npm:0.34.2"
+ dependencies:
+ "@img/sharp-darwin-arm64": "npm:0.34.2"
+ "@img/sharp-darwin-x64": "npm:0.34.2"
+ "@img/sharp-libvips-darwin-arm64": "npm:1.1.0"
+ "@img/sharp-libvips-darwin-x64": "npm:1.1.0"
+ "@img/sharp-libvips-linux-arm": "npm:1.1.0"
+ "@img/sharp-libvips-linux-arm64": "npm:1.1.0"
+ "@img/sharp-libvips-linux-ppc64": "npm:1.1.0"
+ "@img/sharp-libvips-linux-s390x": "npm:1.1.0"
+ "@img/sharp-libvips-linux-x64": "npm:1.1.0"
+ "@img/sharp-libvips-linuxmusl-arm64": "npm:1.1.0"
+ "@img/sharp-libvips-linuxmusl-x64": "npm:1.1.0"
+ "@img/sharp-linux-arm": "npm:0.34.2"
+ "@img/sharp-linux-arm64": "npm:0.34.2"
+ "@img/sharp-linux-s390x": "npm:0.34.2"
+ "@img/sharp-linux-x64": "npm:0.34.2"
+ "@img/sharp-linuxmusl-arm64": "npm:0.34.2"
+ "@img/sharp-linuxmusl-x64": "npm:0.34.2"
+ "@img/sharp-wasm32": "npm:0.34.2"
+ "@img/sharp-win32-arm64": "npm:0.34.2"
+ "@img/sharp-win32-ia32": "npm:0.34.2"
+ "@img/sharp-win32-x64": "npm:0.34.2"
color: "npm:^4.2.3"
- detect-libc: "npm:^2.0.2"
- node-addon-api: "npm:^6.1.0"
- node-gyp: "npm:latest"
- prebuild-install: "npm:^7.1.1"
- semver: "npm:^7.5.4"
- simple-get: "npm:^4.0.1"
- tar-fs: "npm:^3.0.4"
- tunnel-agent: "npm:^0.6.0"
- checksum: 10/f0e4a86881e590f86b05ea463229f62cd29afc2dca08b3f597889f872f118c2c456f382bf2c3e90e934b7a1d30f109cf5ed584cf5a23e79d6b6403a8dc0ebe32
+ detect-libc: "npm:^2.0.4"
+ semver: "npm:^7.7.2"
+ dependenciesMeta:
+ "@img/sharp-darwin-arm64":
+ optional: true
+ "@img/sharp-darwin-x64":
+ optional: true
+ "@img/sharp-libvips-darwin-arm64":
+ optional: true
+ "@img/sharp-libvips-darwin-x64":
+ optional: true
+ "@img/sharp-libvips-linux-arm":
+ optional: true
+ "@img/sharp-libvips-linux-arm64":
+ optional: true
+ "@img/sharp-libvips-linux-ppc64":
+ optional: true
+ "@img/sharp-libvips-linux-s390x":
+ optional: true
+ "@img/sharp-libvips-linux-x64":
+ optional: true
+ "@img/sharp-libvips-linuxmusl-arm64":
+ optional: true
+ "@img/sharp-libvips-linuxmusl-x64":
+ optional: true
+ "@img/sharp-linux-arm":
+ optional: true
+ "@img/sharp-linux-arm64":
+ optional: true
+ "@img/sharp-linux-s390x":
+ optional: true
+ "@img/sharp-linux-x64":
+ optional: true
+ "@img/sharp-linuxmusl-arm64":
+ optional: true
+ "@img/sharp-linuxmusl-x64":
+ optional: true
+ "@img/sharp-wasm32":
+ optional: true
+ "@img/sharp-win32-arm64":
+ optional: true
+ "@img/sharp-win32-ia32":
+ optional: true
+ "@img/sharp-win32-x64":
+ optional: true
+ checksum: 10/8c7a6f20d58849a6e33bc69c4525f471d57eb3dea0072331b55ab12bae4b8bd8b99b65264aeaec38e54d52d692db13e3261f6e7bc29430b39b507c409838cbb0
languageName: node
linkType: hard
@@ -10109,24 +10173,6 @@ __metadata:
languageName: node
linkType: hard
-"simple-concat@npm:^1.0.0":
- version: 1.0.1
- resolution: "simple-concat@npm:1.0.1"
- checksum: 10/4d211042cc3d73a718c21ac6c4e7d7a0363e184be6a5ad25c8a1502e49df6d0a0253979e3d50dbdd3f60ef6c6c58d756b5d66ac1e05cda9cacd2e9fc59e3876a
- languageName: node
- linkType: hard
-
-"simple-get@npm:^4.0.0, simple-get@npm:^4.0.1":
- version: 4.0.1
- resolution: "simple-get@npm:4.0.1"
- dependencies:
- decompress-response: "npm:^6.0.0"
- once: "npm:^1.3.1"
- simple-concat: "npm:^1.0.0"
- checksum: 10/93f1b32319782f78f2f2234e9ce34891b7ab6b990d19d8afefaa44423f5235ce2676aae42d6743fecac6c8dfff4b808d4c24fe5265be813d04769917a9a44f36
- languageName: node
- linkType: hard
-
"simple-html-tokenizer@npm:^0.5.7":
version: 0.5.11
resolution: "simple-html-tokenizer@npm:0.5.11"
@@ -10446,20 +10492,6 @@ __metadata:
languageName: node
linkType: hard
-"streamx@npm:^2.15.0, streamx@npm:^2.21.0":
- version: 2.22.0
- resolution: "streamx@npm:2.22.0"
- dependencies:
- bare-events: "npm:^2.2.0"
- fast-fifo: "npm:^1.3.2"
- text-decoder: "npm:^1.1.0"
- dependenciesMeta:
- bare-events:
- optional: true
- checksum: 10/9c329bb316e2085e207e471ecd0da18b4ed5b1cfe5cf10e9e7fad3f8f50c6ca1a6a844bdfd9bc7521560b97f229890de82ca162a0e66115300b91a489b1cbefd
- languageName: node
- linkType: hard
-
"strict-uri-encode@npm:^1.0.0":
version: 1.1.0
resolution: "strict-uri-encode@npm:1.1.0"
@@ -10651,13 +10683,6 @@ __metadata:
languageName: node
linkType: hard
-"strip-json-comments@npm:~2.0.1":
- version: 2.0.1
- resolution: "strip-json-comments@npm:2.0.1"
- checksum: 10/1074ccb63270d32ca28edfb0a281c96b94dc679077828135141f27d52a5a398ef5e78bcf22809d23cadc2b81dfbe345eb5fd8699b385c8b1128907dec4a7d1e1
- languageName: node
- linkType: hard
-
"strip-outer@npm:^1.0.0":
version: 1.0.1
resolution: "strip-outer@npm:1.0.1"
@@ -11035,35 +11060,6 @@ __metadata:
languageName: node
linkType: hard
-"tar-fs@npm:^2.0.0":
- version: 2.1.2
- resolution: "tar-fs@npm:2.1.2"
- dependencies:
- chownr: "npm:^1.1.1"
- mkdirp-classic: "npm:^0.5.2"
- pump: "npm:^3.0.0"
- tar-stream: "npm:^2.1.4"
- checksum: 10/623f7e8e58a43578ba7368002c3cc7e321f6d170053ac0691d95172dbc7daf5dcf4347eb061277627340870ce6cfda89f5a5d633cc274c41ae6d69f54a2374e7
- languageName: node
- linkType: hard
-
-"tar-fs@npm:^3.0.4":
- version: 3.0.8
- resolution: "tar-fs@npm:3.0.8"
- dependencies:
- bare-fs: "npm:^4.0.1"
- bare-path: "npm:^3.0.0"
- pump: "npm:^3.0.0"
- tar-stream: "npm:^3.1.5"
- dependenciesMeta:
- bare-fs:
- optional: true
- bare-path:
- optional: true
- checksum: 10/fdcd1c66dc5e2cad5544ffe7eab9a470b419290b22300c344688df51bf06127963da07a1e3ae23cae80851cd9f60149e80b38e56485dd7a14aea701241ac2f81
- languageName: node
- linkType: hard
-
"tar-stream@npm:^1.5.2":
version: 1.6.2
resolution: "tar-stream@npm:1.6.2"
@@ -11079,30 +11075,6 @@ __metadata:
languageName: node
linkType: hard
-"tar-stream@npm:^2.1.4":
- version: 2.2.0
- resolution: "tar-stream@npm:2.2.0"
- dependencies:
- bl: "npm:^4.0.3"
- end-of-stream: "npm:^1.4.1"
- fs-constants: "npm:^1.0.0"
- inherits: "npm:^2.0.3"
- readable-stream: "npm:^3.1.1"
- checksum: 10/1a52a51d240c118cbcd30f7368ea5e5baef1eac3e6b793fb1a41e6cd7319296c79c0264ccc5859f5294aa80f8f00b9239d519e627b9aade80038de6f966fec6a
- languageName: node
- linkType: hard
-
-"tar-stream@npm:^3.1.5":
- version: 3.1.7
- resolution: "tar-stream@npm:3.1.7"
- dependencies:
- b4a: "npm:^1.6.4"
- fast-fifo: "npm:^1.2.0"
- streamx: "npm:^2.15.0"
- checksum: 10/b21a82705a72792544697c410451a4846af1f744176feb0ff11a7c3dd0896961552e3def5e1c9a6bbee4f0ae298b8252a1f4c9381e9f991553b9e4847976f05c
- languageName: node
- linkType: hard
-
"tar@npm:^7.4.3":
version: 7.4.3
resolution: "tar@npm:7.4.3"
@@ -11170,15 +11142,6 @@ __metadata:
languageName: node
linkType: hard
-"text-decoder@npm:^1.1.0":
- version: 1.2.3
- resolution: "text-decoder@npm:1.2.3"
- dependencies:
- b4a: "npm:^1.6.4"
- checksum: 10/bcdec33c0f070aeac38e46e4cafdcd567a58473ed308bdf75260bfbd8f7dc76acbc0b13226afaec4a169d0cb44cec2ab89c57b6395ccf02e941eaebbe19e124a
- languageName: node
- linkType: hard
-
"text-table@npm:^0.2.0":
version: 0.2.0
resolution: "text-table@npm:0.2.0"
@@ -11331,7 +11294,7 @@ __metadata:
languageName: node
linkType: hard
-"tslib@npm:^2.0.3, tslib@npm:^2.1.0":
+"tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.4.0":
version: 2.8.1
resolution: "tslib@npm:2.8.1"
checksum: 10/3e2e043d5c2316461cb54e5c7fe02c30ef6dccb3384717ca22ae5c6b5bc95232a6241df19c622d9c73b809bea33b187f6dbc73030963e29950c2141bc32a79f7