diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000..e5b6d8d --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..a23f17e --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.0.5/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "restricted", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [], + "privatePackages": { "version": true, "tag": true } +} diff --git a/.changeset/kind-chefs-relate.md b/.changeset/kind-chefs-relate.md new file mode 100644 index 0000000..e140ba1 --- /dev/null +++ b/.changeset/kind-chefs-relate.md @@ -0,0 +1,5 @@ +--- +"focal-point-picker": patch +--- + +Add a Changelog and a release flow using `@changesets/cli` and `@changesets/action`. Also some minor readme optimizations. diff --git a/.github/actions/install-playwright/action.yml b/.github/actions/install-playwright/action.yml new file mode 100644 index 0000000..eadd57a --- /dev/null +++ b/.github/actions/install-playwright/action.yml @@ -0,0 +1,65 @@ +name: Install Playwright +description: Install Playwright and dependencies with cache + +# https://github.com/microsoft/playwright/issues/7249#issuecomment-2334627973 + +inputs: + working-directory: + description: Where to install Playwright + default: ./ + browsers: + description: Browsers to install + default: chromium webkit firefox + +outputs: + version: + description: Installed version of Playwright + value: ${{ steps.version.outputs.version }} + cache-hit: + description: Whether cache for Playwright was found + value: ${{ steps.cache.outputs.cache-hit }} + +runs: + using: composite + steps: + - name: Get Playwright version + uses: actions/github-script@v7 + id: version + with: + script: | + // https://github.com/actions/toolkit/issues/1624 + // const workingDirectory = core.getInput("working-directory"); + const workingDirectory = "${{ inputs.working-directory }}"; + console.debug("Specified working directory:", workingDirectory); + if (workingDirectory) process.chdir(workingDirectory); + console.debug("Actual working directory:", process.cwd()); + let version = ""; + try { + version = require("@playwright/test/package.json").version; + } catch (error) { + console.log(error.message); + } + console.debug("Version:", version); + if (version) { + core.exportVariable("PLAYWRIGHT_VERSION", version); + core.setOutput("version", version); + } else core.setFailed("Couldn't get Playwright version"); + + - name: Cache Playwright + id: cache + uses: actions/cache@v4 + with: + path: ~/.cache/ms-playwright + key: playwright-${{ env.PLAYWRIGHT_VERSION }} + + - name: Install Playwright and its dependencies + shell: bash + if: steps.cache.outputs.cache-hit != 'true' + working-directory: ${{ inputs.working-directory }} + run: npx playwright install ${{ inputs.browsers }} --with-deps + + - name: Install just Playwright's dependencies + shell: bash + if: steps.cache.outputs.cache-hit == 'true' + working-directory: ${{ inputs.working-directory }} + run: npx playwright install-deps diff --git a/.github/actions/shared-setup/action.yml b/.github/actions/shared-setup/action.yml new file mode 100644 index 0000000..20c69a9 --- /dev/null +++ b/.github/actions/shared-setup/action.yml @@ -0,0 +1,49 @@ +name: Run Shared Setup + +inputs: + php-version: + description: The PHP version to install + default: 8.3 + playwright: + description: Should Playwright be installed? + default: false + +runs: + using: composite + steps: + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ inputs.php-version }} + tools: composer:v2 + coverage: xdebug + + - name: Install Composer Dependencies + uses: ramsey/composer-install@v3 + + - name: Setup PNPM + uses: pnpm/action-setup@v4 + with: + version: latest + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: pnpm + + - name: Install Dependencies + shell: bash + run: pnpm install --frozen-lockfile + + - name: Install Playwright + if: ${{ inputs.playwright }} == 'true' + id: install-playwright + uses: ./.github/actions/install-playwright + + - name: Debug Playwright Cache + if: ${{ inputs.playwright }} == 'true' + shell: bash + run: | + echo "Playwright version: ${{ steps.install-playwright.outputs.version }}" + echo "Playwright cached: ${{ steps.install-playwright.outputs.cache-hit }}" \ No newline at end of file diff --git a/.github/workflows/version-or-publish.yml b/.github/workflows/version-or-publish.yml new file mode 100644 index 0000000..16ea41c --- /dev/null +++ b/.github/workflows/version-or-publish.yml @@ -0,0 +1,73 @@ +name: Version or Publish + +on: + push: + branches: + - main + +permissions: + contents: write + pull-requests: write + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +jobs: + package-infos: + name: Get Package Infos + runs-on: ubuntu-latest + outputs: + fullName: ${{ steps.package-infos.outputs.fullName }} + vendorName: ${{ steps.package-infos.outputs.vendorName }} + packageName: ${{ steps.package-infos.outputs.packageName }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Read and Write Package Infos to Output + id: package-infos + run: | + NAME=$(jq -r '.name' composer.json) + echo "fullName=${NAME}" >> $GITHUB_OUTPUT + echo "vendorName=${NAME%%/*}" >> $GITHUB_OUTPUT + echo "packageName=${NAME#*/}" >> $GITHUB_OUTPUT + cat "$GITHUB_OUTPUT" + + release: + needs: package-infos + if: ${{ github.repository == needs.package-infos.outputs.fullName }} + + name: Create Version PR or Publish + runs-on: ubuntu-latest + + strategy: + fail-fast: true + + steps: + - name: Configure Git + run: | + git config --global user.email "bot@rassohilber.com" + git config --global user.name "Rasso Hilber's Bot" + + - name: Check out repository + uses: actions/checkout@v4 + + - name: Shared Setup + uses: ./.github/actions/shared-setup + with: + playwright: false + + # Run changesets action either if there are unreleased changesets (= a PR must be created) + # or if the commit message matches the release PR (= new versions must be published) + - name: Create changesets PR or Publish + id: cs + uses: changesets/action@v1 + with: + title: "[CI] Release" + commit: "[CI] Release" + version: pnpm run version + publish: pnpm changeset tag + env: + # Do not run husky/lintstaged + HUSKY: 0 + # Doesn't work with GITHUB_TOKEN for some reason + GITHUB_TOKEN: ${{ secrets.HIRASSO_ACTIONS_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..5ddad42 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1 @@ +# Changelog \ No newline at end of file diff --git a/bin/cli.js b/bin/cli.js new file mode 100755 index 0000000..891cc9e --- /dev/null +++ b/bin/cli.js @@ -0,0 +1,101 @@ +#!/usr/bin/env node + +import { parseArgs } from "node:util"; +import { basename } from "node:path"; +import { fileURLToPath } from "node:url"; + +import pc from "picocolors"; +const { blue, red, bold } = pc; + +import { + dd, + createRelease, + testRelease, + pushReleaseToDist, + patchVersion, + prepareDistFolder, + isAtRootDir, + testDev, + error, +} from "./support.js"; +import { exit } from "node:process"; + +// Get the equivalent of __filename +const __filename = fileURLToPath(import.meta.url); + +/** + * @typedef {Object} Command + * @property {Function} fn - The function to execute the command. + * @property {string} description - A brief description of what the command does. + */ + +/** + * An object containing available commands with their respective handlers and descriptions. + * + * @type {Object} + */ +const commands = { + "release:create": { + fn: createRelease, + description: "Create a scoped release", + }, + "version:patch": { + fn: patchVersion, + description: "Patch the version in the main plugin file", + }, + "dist:prepare": { + fn: prepareDistFolder, + description: "Prepare the folder for pushing to the dist repo", + }, + "dist:push": { + fn: pushReleaseToDist, + description: "Push the prepared dist folder to the dist repo", + }, + "test:dev": { + fn: testDev, + description: + "Run tests against the development (unscoped) version of the plugin", + }, + "test:release": { + fn: testRelease, + description: "Run tests against the release (scoped) version of the plugin", + }, + help: { + fn: printUsage, + description: "Show available commands for this cli", + }, +}; + +const { + positionals: [command], +} = parseArgs({ allowPositionals: true }); + +// Function to print usage +function printUsage() { + const commandList = []; + for (const [name, { description }] of Object.entries(commands)) { + commandList.push(`${blue(name)} – ${description}`); + } + console.log(` +Usage: cli.js ${blue(``)} + +Available commands: + ${commandList.join("\n ")}`); +} + +// Validate correct invocation +if (!command || typeof commands[command] === "undefined") { + console.log(`\n ❌ ${red(bold(`Unkown command: ${command}`))}`); + printUsage(); + exit(); +} + +// Ensure the script is run from the project root +if (!isAtRootDir()) { + error( + `${basename(__filename)} must be executed from the package root directory`, + ); +} + +// Execute the command +commands[command].fn(); diff --git a/bin/support.js b/bin/support.js new file mode 100644 index 0000000..a0f4aef --- /dev/null +++ b/bin/support.js @@ -0,0 +1,521 @@ +import { + copyFileSync, + cpSync, + existsSync, + mkdirSync, + readFileSync, + rmSync, + writeFileSync, +} from "node:fs"; +import { fileURLToPath } from "node:url"; +import path, { basename, extname, resolve } from "node:path"; +import { execSync } from "node:child_process"; +import { chdir, cwd, env, exit } from "node:process"; +import pc from "picocolors"; +import fg from "fast-glob"; + +/** extract colors from common.js module picocolors */ +const { blue, red, bold, gray, green } = pc; + +/** Get the equivalent of __filename */ +const __filename = fileURLToPath(import.meta.url); + +/** + * Dump and die + * @param {...any} args + */ +export function dd(...args) { + console.log(...args); + process.exit(); +} + +/** + * Validate that the script is being run from the root dir + * This is being achieved by comparing the package name to + */ +export function isAtRootDir() { + return ( + existsSync(resolve(cwd(), "package.json")) && + existsSync(resolve(cwd(), "composer.json")) + ); +} + +/** + * Get the current version from the package.json + * In this project, the version in package.json is the + * source of truth, as releases are handled by @changesets/action + * @return {{version: string}} + */ +export function getInfosFromPackageJSON() { + const packageJsonPath = path.join(process.cwd(), "./package.json"); + const { version } = JSON.parse(readFileSync(packageJsonPath, "utf8")); + if (!version) { + error(`No version found in package.json`); + } + return { version }; +} + +/** + * Get the path to the scoped folder + */ +export function getScopedFolder() { + const { packageName } = getInfosFromComposerJSON(); + return `scoped/${packageName}`; +} + +/** + * Get infos from the composer.json + * @return {{ + * fullName: string, + * vendorName: string, + * packageName: string, + * dependencies: string[], + * devDependencies: string[] + * }} + */ +export function getInfosFromComposerJSON() { + const composerJsonPath = path.join(process.cwd(), "./composer.json"); + const json = JSON.parse(readFileSync(composerJsonPath, "utf8")); + const fullName = json.name; + const dependencies = json["require"] || {}; + const devDependencies = json["require-dev"] || {}; + if (!fullName) { + throw new Error(`No name found in composer.json`); + } + if (!fullName.includes("/")) { + throw new Error( + `Invalid name found in composer.json. It must be 'vendor-name/package-name'`, + ); + } + const [vendorName, packageName] = fullName.split("/"); + return { fullName, vendorName, packageName, dependencies, devDependencies }; +} + +/** + * Run a command, stop execution on errors ({ stdio: "inherit" }) + * @param {string} command + */ +export const run = (command) => execSync(command, { stdio: "inherit" }); + +/** + * Log an info message + * @param {string} message + * @param {...any} rest + */ +export const info = (message, ...rest) => { + console.log(`💡 ${gray(message)}`, ...rest); +}; + +/** + * Log a success message + * @param {string} message + * @param {...any} rest + */ +export const success = (message, ...rest) => { + console.log(`✅ ${green(message)}`, ...rest); +}; + +/** + * Log a success message + * @param {string} message + */ +export const headline = (message) => { + message = ` ℹī¸ ${message} `; + line(); + console.log(blue("-".repeat(message.length))); + console.log(`${blue(message)}`); + console.log(blue("-".repeat(message.length))); + line(); +}; + +/** + * Log an error message and exit + * @param {string} message + * @param {...any} rest + */ +export const error = (message, ...rest) => { + line(); + console.log(` ❌ ${red(bold(`${message}`))}`, ...rest); + exit(1); +}; + +/** + * Log a line + */ +export const line = () => console.log(""); + +/** + * Debug something to the console + * @param {...any} args + */ +export const debug = (...args) => { + line(); + console.log("🐛 ", ...args); + line(); +}; + +/** + * Check if currently running on GitHub actions + */ +export const isGitHubActions = () => env.GITHUB_ACTIONS === "true"; + +/** + * Compare two directories + * @param {string} dir1 + * @param {string} dir2 + * @param {string[]} ignore + */ +export const validateDirectories = async (dir1, dir2, ignore = [".git"]) => { + try { + const pattern = ["*", ...ignore.map((ig) => `!${ig}`)]; + + const { files1, files2 } = { + files1: await fg(pattern, { cwd: dir1, onlyFiles: false }), + files2: await fg(pattern, { cwd: dir2, onlyFiles: false }), + }; + + return ( + !!files1.length && + !!files2.length && + files1.length === files2.length && + files1.every((file, index) => file === files2[index]) + ); + } catch (err) { + error("Error comparing directories:", err); + } +}; + +/** + * Create release files for usage in the release asset and dist repo + * - scopes dependency namespaces using php-scoper + * - creates a folder scoped/ with all required plugin files + * - creates a zip file from the scoped/ folder, named after the package + */ +export function createRelease() { + headline(`Creating Release Files...`); + + const { packageName } = getInfosFromComposerJSON(); + const scopedFolder = getScopedFolder(); + + line(); + info(`Creating a scoped release in ${blue(scopedFolder)}...`); + line(); + + /** Ensure php-scoper is available */ + const phpScoperPath = "config/php-scoper"; + info("Ensuring php-scoper is available..."); + + if (!existsSync(phpScoperPath)) { + run(`curl -sL https://github.com/humbug/php-scoper/releases/download/0.18.15/php-scoper.phar -o ${phpScoperPath}`); // prettier-ignore + run(`chmod +x ${phpScoperPath}`); + } + + info("Installing non-dev composer dependencies..."); + run("composer install --no-scripts --no-dev --quiet"); + + info("Scoping non-dev dependencies..."); + rmSync(scopedFolder, { recursive: true, force: true }); + run(`${phpScoperPath} add-prefix --quiet --output-dir=${scopedFolder} --config=config/scoper.config.php`); // prettier-ignore + success("Successfully scoped all namespaces!"); + line(); + + info("Re-installing dev depdendencies..."); + run("composer install --no-scripts --quiet"); + + /** + * This needs to be done manually, since PUC causes problems when scoped. + * All changes to the vendor dir have to run BEFORE dumping the autolaoder! + */ + info(`Copying plugin-update-checker/ to ${scopedFolder}/...`); + cpSync( + "vendor/yahnis-elsts/plugin-update-checker", + `${scopedFolder}/vendor/yahnis-elsts/plugin-update-checker`, + { force: true, recursive: true }, + ); + + /** Dump the autoloader in the scoped directory */ + info(`Dumping the autoloader in ${scopedFolder}...`); + run( + `composer dump-autoload --working-dir=${scopedFolder} --classmap-authoritative`, + ); + + line(); + + /** Clean up the scoped directory */ + info(`Cleaning up ${scopedFolder}...`); + ["composer.json", "composer.lock"].forEach((file) => { + rmSync(resolve(`${cwd()}/${scopedFolder}`, file), { force: true }); + }); + + info(`Overwriting the composer.json in ${scopedFolder}/...`); + cpSync("composer.dist.json", `${scopedFolder}/composer.json`); + + line(); + + /** Create a zip file from the scoped directory */ + info(`Creating a zip file from ${scopedFolder}...`); + run( + `cd ${scopedFolder} && zip -rq "../../${packageName}.zip" . && cd - >/dev/null`, + ); + + line(); + success(`Created a scoped release folder: ${blue(scopedFolder)}`); + success(`Created a scoped release asset: ${blue(`${packageName}.zip`)}`); + line(); +} + +/** + * Read a file, fall back to undefined if it doesn't exist + * @param {string} path + */ +function readFile(path) { + return existsSync(path) + ? readFileSync(path, { encoding: "utf-8" }) + : undefined; +} + +/** + * Run Unit and E2E tests from the unscoped version + */ +export function testDev() { + if (existsSync(".wp-env.override.json")) { + info(`Deleting plugins in .wp-env.override.json...`); + const overrides = JSON.parse(readFile(".wp-env.override.json") || "{}"); + rmSync(".wp-env.override.json", { force: true }); + delete overrides.plugins; + if (Object.values(overrides).length) { + writeJsonFile(".wp-env.override.json", overrides); + } + + info(`Re-Starting wp-env with root folder...`); + run(`wp-env start --update`); + } + + info(`Running tests against the development version...`); + run("pnpm run test"); +} + +/** + * Write JSON to a file + * @param {string} name + * @param {any} data + */ +function writeJsonFile(name, data) { + writeFileSync(name, JSON.stringify(data, undefined, 2), "utf-8"); +} + +/** + * Run E2E tests from the scoped release folder. + * This command is only required for local tests. + */ +export function testRelease() { + createRelease(); + + const scopedFolder = getScopedFolder(); + + // info(`Installing dev dependencies in ${scopedFolder}...`); + // const { devDependencies } = getInfosFromComposerJSON(); + + // const requireDev = Object.entries(devDependencies).reduce( + // /** + // * @param {string[]} acc - The accumulator array. + // * @param {[string, string]} entry - An array containing the dependency name and version. + // * @returns {string[]} The updated accumulator array. + // */ + // (acc, [name, version]) => { + // acc.push(`"${name}:${version}"`); + // return acc; + // }, + // [], + // ); + + // run(`composer require --dev ${requireDev.join(" ")} --quiet --working-dir=${scopedFolder} --with-all-dependencies`); // prettier-ignore + + if (!isGitHubActions()) { + /** @type {{ plugins: string[] }} */ + const { plugins } = JSON.parse(readFile(".wp-env.json") || "{}"); + const overrides = JSON.parse(readFile(".wp-env.override.json") || "{}"); + + overrides.plugins = plugins.map((path) => { + // return path.replace(/^\.\/?/, `./${scopedFolder}/`); + return path === "." ? `./${scopedFolder}/` : path; + }); + + writeJsonFile(".wp-env.override.json", overrides); + debug("Contents of .wp-env.override.json:", overrides); + + info(`Re-Starting wp-env with ${scopedFolder}...`); + + run(`wp-env start --update`); + } + + info(`Running e2e tests against ${scopedFolder}...`); + run("pnpm run test:e2e"); +} + +/** + * Prepare the dist folder + * - clones the dist repo into dist/ + * - checks out the empty root commit in dist/ + * - copies all files from scoped/ into dist/ + */ +export function prepareDistFolder() { + headline(`Preparing Dist Folder...`); + + const { fullName } = getInfosFromComposerJSON(); + const scopedFolder = getScopedFolder(); + + /** Check if the scoped folder exists */ + if (!existsSync(scopedFolder)) { + error(`'${scopedFolder}' scoped folder does not exist`); + } + + /** Re-create the release files if the scoped folder is not clean */ + if (existsSync(`${scopedFolder}/phpunit.xml`)) { + createRelease(); + } + + /** Initialize the dist folder if not in GitHub Actions */ + if (env.GITHUB_ACTIONS !== "true") { + info(`Cloning the dist repo into dist/...`); + rmSync("dist", { recursive: true, force: true }); + run(`git clone -b empty git@github.com:${fullName}-dist.git dist/`); // prettier-ignore + } + + info(`Checking out the empty tagged root commit..`); + run("git -C dist checkout --detach empty"); + + line(); + + info(`Copying files from ${scopedFolder} to dist/...`); + cpSync(scopedFolder, "dist", { recursive: true, force: true }); + + success(`Dist folder preparation complete!`); +} + +/** + * Copy files from one foldder to another + * + * @param {string} sourceDir + * @param {string} destDir + * @param {string} pattern + */ +export async function copyFiles(sourceDir, destDir, pattern = "**/*.{js,css}") { + const files = await fg(pattern, { + cwd: sourceDir, + absolute: true, + }); + + /** Ensure the destination directory exists */ + mkdirSync(destDir, { recursive: true }); + + /** Copy each file */ + files.forEach((file) => { + const relativePath = path.relative(sourceDir, file); + const destPath = path.join(destDir, relativePath); + + /** Ensure destination subdirectories exist */ + mkdirSync(path.dirname(destPath), { recursive: true }); + + /** Copy the file */ + copyFileSync(file, destPath); + + success(`Copied: ${sourceDir}/${relativePath} → ${destPath}`); + }); +} + +/** + * Push scoped release files to the dist repo + */ +export async function pushReleaseToDist() { + const rootDir = cwd(); + const packageInfos = getInfosFromPackageJSON(); + const { packageName } = getInfosFromComposerJSON(); + const packageVersion = `v${packageInfos.version}`; + const scopedFolder = getScopedFolder(); + + const onGitHub = isGitHubActions(); + debug({ onGitHub }); + + const hasValidDirectories = await validateDirectories(scopedFolder, "dist"); + + debug({ hasValidDirectories }); + + if (hasValidDirectories !== true) { + error( + `The validation of the scoped and dist folder failed.`, + `Did you run 'release:prepare'?`, + ); + } + + /** Ensure the script is running in a GitHub Action */ + if (!onGitHub) { + error(`${basename(__filename)} can only run on GitHub`); + } + + if (!packageVersion) { + error("Empty package version"); + } + + info(`Committing and pushing new release: 'v${packageVersion}'...`); + line(); + + /** Navigate to the dist folder and perform Git operations */ + try { + chdir("dist/"); + run(`git add .`); + run(`git commit -m "Release: ${packageName}@${packageVersion}"`); + run(`git tag "${packageVersion}"`); + run(`git push origin "${packageVersion}"`); + success(`Released '${packageVersion}' to the dist repo.`); + chdir(rootDir); + } catch (err) { + error("An error occurred while releasing the package.", err); + } + + /** Change back to the root dir */ + chdir(rootDir); +} + +/** + * Patch the version in the main plugin php file, based on the + * current version in the package.json + */ +export async function patchVersion() { + const { version: packageVersion } = getInfosFromPackageJSON(); + const { packageName } = getInfosFromComposerJSON(); + + const phpFiles = await fg("*.php"); + const versionRegexp = /\*\s*Version:\s*(\d+\.\d+\.\d+)/; + + const fileName = phpFiles.find((file) => versionRegexp.test(readFileSync(file, "utf-8"))); + + if (!fileName) { + return error(`Main plugin file not found: ${fileName}`); + } + + const contents = readFileSync(fileName, "utf8"); + const currentVersion = contents.match(versionRegexp)?.[1]; + + line(); + info(`Patching version in ${fileName}...`); + + if (!currentVersion) { + error(`No version found in file: ${fileName}`); + process.exit(1); + } + + if (currentVersion === packageVersion) { + success(`Version already patched in ${fileName}: ${currentVersion}`); + process.exit(0); + } + + writeFileSync( + fileName, + contents.replace(versionRegexp, `* Version: ${packageVersion}`), + "utf8", + ); + + success(`Patched version to ${packageVersion} in ${fileName}`); + line(); +} diff --git a/composer.json b/composer.json index 0000d56..4125616 100644 --- a/composer.json +++ b/composer.json @@ -1,26 +1,26 @@ { - "name": "hirasso/focal-point-picker", - "description": "A WordPress plugin to set a custom focal point for your images, directly in the WP media grid", - "type": "wordpress-plugin", - "license": "GPL-3.0-or-later", - "authors": [ - { - "name": "Rasso Hilber", - "email": "mail@rassohilber.com" - } - ], - "minimum-stability": "stable", - "require": { - "php": ">=8.2", - "composer/installers": "^2.3" - }, - "require-dev": { - "symfony/var-dumper": "^7.1", - "friendsofphp/php-cs-fixer": "^3.59" - }, - "config": { - "allow-plugins": { - "composer/installers": true - } + "name": "hirasso/focal-point-picker", + "description": "Zero-dependency custom focal point picker for your WordPress images đŸŽ¯", + "type": "wordpress-plugin", + "license": "GPL-3.0-or-later", + "authors": [ + { + "name": "Rasso Hilber", + "email": "mail@rassohilber.com" } + ], + "minimum-stability": "stable", + "require": { + "php": ">=8.2", + "composer/installers": "^2.3" + }, + "require-dev": { + "symfony/var-dumper": "^7.1", + "friendsofphp/php-cs-fixer": "^3.59" + }, + "config": { + "allow-plugins": { + "composer/installers": true + } + } } diff --git a/focal-point-picker.php b/focal-point-picker.php index 8a74984..920c3ea 100644 --- a/focal-point-picker.php +++ b/focal-point-picker.php @@ -1,8 +1,9 @@ =6.9.0'} + + '@changesets/apply-release-plan@7.0.7': + resolution: {integrity: sha512-qnPOcmmmnD0MfMg9DjU1/onORFyRpDXkMMl2IJg9mECY6RnxL3wN0TCCc92b2sXt1jt8DgjAUUsZYGUGTdYIXA==} + + '@changesets/assemble-release-plan@6.0.5': + resolution: {integrity: sha512-IgvBWLNKZd6k4t72MBTBK3nkygi0j3t3zdC1zrfusYo0KpdsvnDjrMM9vPnTCLCMlfNs55jRL4gIMybxa64FCQ==} + + '@changesets/changelog-git@0.2.0': + resolution: {integrity: sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==} + + '@changesets/cli@2.27.11': + resolution: {integrity: sha512-1QislpE+nvJgSZZo9+Lj3Lno5pKBgN46dAV8IVxKJy9wX8AOrs9nn5pYVZuDpoxWJJCALmbfOsHkyxujgetQSg==} + hasBin: true + + '@changesets/config@3.0.5': + resolution: {integrity: sha512-QyXLSSd10GquX7hY0Mt4yQFMEeqnO5z/XLpbIr4PAkNNoQNKwDyiSrx4yd749WddusH1v3OSiA0NRAYmH/APpQ==} + + '@changesets/errors@0.2.0': + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} + + '@changesets/get-dependents-graph@2.1.2': + resolution: {integrity: sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==} + + '@changesets/get-release-plan@4.0.6': + resolution: {integrity: sha512-FHRwBkY7Eili04Y5YMOZb0ezQzKikTka4wL753vfUA5COSebt7KThqiuCN9BewE4/qFGgF/5t3AuzXx1/UAY4w==} + + '@changesets/get-version-range-type@0.4.0': + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + + '@changesets/git@3.0.2': + resolution: {integrity: sha512-r1/Kju9Y8OxRRdvna+nxpQIsMsRQn9dhhAZt94FLDeu0Hij2hnOozW8iqnHBgvu+KdnJppCveQwK4odwfw/aWQ==} + + '@changesets/logger@0.1.1': + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} + + '@changesets/parse@0.4.0': + resolution: {integrity: sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==} + + '@changesets/pre@2.0.1': + resolution: {integrity: sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==} + + '@changesets/read@0.6.2': + resolution: {integrity: sha512-wjfQpJvryY3zD61p8jR87mJdyx2FIhEcdXhKUqkja87toMrP/3jtg/Yg29upN+N4Ckf525/uvV7a4tzBlpk6gg==} + + '@changesets/should-skip-package@0.1.1': + resolution: {integrity: sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==} + + '@changesets/types@4.1.0': + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + + '@changesets/types@6.0.0': + resolution: {integrity: sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==} + + '@changesets/write@0.3.2': + resolution: {integrity: sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==} + + '@manypkg/find-root@1.1.0': + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + + '@manypkg/get-packages@1.1.3': + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + ansi-escapes@6.2.1: resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} engines: {node: '>=14.16'} + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + ansi-regex@6.0.1: resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} engines: {node: '>=12'} @@ -32,6 +129,17 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -40,6 +148,13 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + cli-cursor@4.0.0: resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -59,6 +174,10 @@ packages: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + debug@4.3.5: resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} engines: {node: '>=6.0'} @@ -68,9 +187,26 @@ packages: supports-color: optional: true + detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + emoji-regex@10.3.0: resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} @@ -78,10 +214,36 @@ packages: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} + extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + + external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fastq@1.18.0: + resolution: {integrity: sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + get-east-asian-width@1.2.0: resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} engines: {node: '>=18'} @@ -90,6 +252,20 @@ packages: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + human-id@1.0.2: + resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} + human-signals@5.0.0: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} @@ -99,6 +275,18 @@ packages: engines: {node: '>=18'} hasBin: true + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + is-fullwidth-code-point@4.0.0: resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} engines: {node: '>=12'} @@ -107,6 +295,10 @@ packages: resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} engines: {node: '>=18'} + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -115,9 +307,24 @@ packages: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + lilconfig@3.1.2: resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} engines: {node: '>=14'} @@ -131,6 +338,13 @@ packages: resolution: {integrity: sha512-Lllokma2mtoniUOS94CcOErHWAug5iu7HOmDrvWgpw8jyQH2fomgB+7lZS4HWZxytUuQwkGOwe49FvwVaA85Xw==} engines: {node: '>=18.0.0'} + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + log-update@6.0.0: resolution: {integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==} engines: {node: '>=18'} @@ -138,10 +352,18 @@ packages: merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + micromatch@4.0.7: resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} engines: {node: '>=8.6'} + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} @@ -150,6 +372,10 @@ packages: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} @@ -165,6 +391,40 @@ packages: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + + p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-manager-detector@0.2.8: + resolution: {integrity: sha512-ts9KSdroZisdvKMWVAVCXiKqnqNfXz4+IbrBG8/BWx/TR5le+jfenvoBuIZ6UWM9nz47W7AbD9qYfAwfWMIwzA==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -173,6 +433,13 @@ packages: resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} engines: {node: '>=12'} + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -182,18 +449,56 @@ packages: engines: {node: '>=0.10'} hasBin: true + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + prettier@3.3.3: resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} engines: {node: '>=14'} hasBin: true + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + restore-cursor@4.0.0: resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -209,6 +514,10 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + slice-ansi@5.0.0: resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} engines: {node: '>=12'} @@ -217,6 +526,12 @@ packages: resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} engines: {node: '>=18'} + spawndamnit@3.0.1: + resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -225,18 +540,38 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + strip-ansi@7.1.0: resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + strip-final-newline@3.0.0: resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} + term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -253,18 +588,212 @@ packages: snapshots: + '@babel/runtime@7.26.0': + dependencies: + regenerator-runtime: 0.14.1 + + '@changesets/apply-release-plan@7.0.7': + dependencies: + '@changesets/config': 3.0.5 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.2 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.6.3 + + '@changesets/assemble-release-plan@6.0.5': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.6.3 + + '@changesets/changelog-git@0.2.0': + dependencies: + '@changesets/types': 6.0.0 + + '@changesets/cli@2.27.11': + dependencies: + '@changesets/apply-release-plan': 7.0.7 + '@changesets/assemble-release-plan': 6.0.5 + '@changesets/changelog-git': 0.2.0 + '@changesets/config': 3.0.5 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/get-release-plan': 4.0.6 + '@changesets/git': 3.0.2 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.1 + '@changesets/read': 0.6.2 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@changesets/write': 0.3.2 + '@manypkg/get-packages': 1.1.3 + ansi-colors: 4.1.3 + ci-info: 3.9.0 + enquirer: 2.4.1 + external-editor: 3.1.0 + fs-extra: 7.0.1 + mri: 1.2.0 + p-limit: 2.3.0 + package-manager-detector: 0.2.8 + picocolors: 1.1.1 + resolve-from: 5.0.0 + semver: 7.6.3 + spawndamnit: 3.0.1 + term-size: 2.2.1 + + '@changesets/config@3.0.5': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/logger': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.8 + + '@changesets/errors@0.2.0': + dependencies: + extendable-error: 0.1.7 + + '@changesets/get-dependents-graph@2.1.2': + dependencies: + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + picocolors: 1.1.1 + semver: 7.6.3 + + '@changesets/get-release-plan@4.0.6': + dependencies: + '@changesets/assemble-release-plan': 6.0.5 + '@changesets/config': 3.0.5 + '@changesets/pre': 2.0.1 + '@changesets/read': 0.6.2 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/get-version-range-type@0.4.0': {} + + '@changesets/git@3.0.2': + dependencies: + '@changesets/errors': 0.2.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.8 + spawndamnit: 3.0.1 + + '@changesets/logger@0.1.1': + dependencies: + picocolors: 1.1.1 + + '@changesets/parse@0.4.0': + dependencies: + '@changesets/types': 6.0.0 + js-yaml: 3.14.1 + + '@changesets/pre@2.0.1': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + + '@changesets/read@0.6.2': + dependencies: + '@changesets/git': 3.0.2 + '@changesets/logger': 0.1.1 + '@changesets/parse': 0.4.0 + '@changesets/types': 6.0.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.1 + + '@changesets/should-skip-package@0.1.1': + dependencies: + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/types@4.1.0': {} + + '@changesets/types@6.0.0': {} + + '@changesets/write@0.3.2': + dependencies: + '@changesets/types': 6.0.0 + fs-extra: 7.0.1 + human-id: 1.0.2 + prettier: 2.8.8 + + '@manypkg/find-root@1.1.0': + dependencies: + '@babel/runtime': 7.26.0 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + + '@manypkg/get-packages@1.1.3': + dependencies: + '@babel/runtime': 7.26.0 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.18.0 + + '@types/node@12.20.55': {} + + ansi-colors@4.1.3: {} + ansi-escapes@6.2.1: {} + ansi-regex@5.0.1: {} + ansi-regex@6.0.1: {} ansi-styles@6.2.1: {} + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + array-union@2.1.0: {} + + better-path-resolve@1.0.0: + dependencies: + is-windows: 1.0.2 + braces@3.0.3: dependencies: fill-range: 7.1.1 chalk@5.3.0: {} + chardet@0.7.0: {} + + ci-info@3.9.0: {} + cli-cursor@4.0.0: dependencies: restore-cursor: 4.0.0 @@ -284,12 +813,31 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + debug@4.3.5: dependencies: ms: 2.1.2 + detect-indent@6.1.0: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + emoji-regex@10.3.0: {} + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + esprima@4.0.1: {} + eventemitter3@5.0.1: {} execa@8.0.1: @@ -304,30 +852,111 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 + extendable-error@0.1.7: {} + + external-editor@3.1.0: + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fastq@1.18.0: + dependencies: + reusify: 1.0.4 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + get-east-asian-width@1.2.0: {} get-stream@8.0.1: {} + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + graceful-fs@4.2.11: {} + + human-id@1.0.2: {} + human-signals@5.0.0: {} husky@9.1.1: {} + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + is-extglob@2.1.1: {} + is-fullwidth-code-point@4.0.0: {} is-fullwidth-code-point@5.0.0: dependencies: get-east-asian-width: 1.2.0 + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + is-number@7.0.0: {} is-stream@3.0.0: {} + is-subdir@1.2.0: + dependencies: + better-path-resolve: 1.0.0 + + is-windows@1.0.2: {} + isexe@2.0.0: {} + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + lilconfig@3.1.2: {} lint-staged@15.2.7: @@ -354,6 +983,12 @@ snapshots: rfdc: 1.4.1 wrap-ansi: 9.0.0 + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + lodash.startcase@4.4.0: {} + log-update@6.0.0: dependencies: ansi-escapes: 6.2.1 @@ -364,15 +999,24 @@ snapshots: merge-stream@2.0.0: {} + merge2@1.4.1: {} + micromatch@4.0.7: dependencies: braces: 3.0.3 picomatch: 2.3.1 + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + mimic-fn@2.1.0: {} mimic-fn@4.0.0: {} + mri@1.2.0: {} + ms@2.1.2: {} npm-run-path@5.3.0: @@ -387,23 +1031,78 @@ snapshots: dependencies: mimic-fn: 4.0.0 + os-tmpdir@1.0.2: {} + + outdent@0.5.0: {} + + p-filter@2.1.0: + dependencies: + p-map: 2.1.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-map@2.1.0: {} + + p-try@2.2.0: {} + + package-manager-detector@0.2.8: {} + + path-exists@4.0.0: {} + path-key@3.1.1: {} path-key@4.0.0: {} + path-type@4.0.0: {} + + picocolors@1.1.1: {} + picomatch@2.3.1: {} pidtree@0.6.0: {} + pify@4.0.1: {} + + prettier@2.8.8: {} + prettier@3.3.3: {} + queue-microtask@1.2.3: {} + + read-yaml-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.1 + pify: 4.0.1 + strip-bom: 3.0.0 + + regenerator-runtime@0.14.1: {} + + resolve-from@5.0.0: {} + restore-cursor@4.0.0: dependencies: onetime: 5.1.2 signal-exit: 3.0.7 + reusify@1.0.4: {} + rfdc@1.4.1: {} + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safer-buffer@2.1.2: {} + + semver@7.6.3: {} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -414,6 +1113,8 @@ snapshots: signal-exit@4.1.0: {} + slash@3.0.0: {} + slice-ansi@5.0.0: dependencies: ansi-styles: 6.2.1 @@ -424,6 +1125,13 @@ snapshots: ansi-styles: 6.2.1 is-fullwidth-code-point: 5.0.0 + spawndamnit@3.0.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + sprintf-js@1.0.3: {} + string-argv@0.3.2: {} string-width@7.2.0: @@ -432,16 +1140,30 @@ snapshots: get-east-asian-width: 1.2.0 strip-ansi: 7.1.0 + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + strip-ansi@7.1.0: dependencies: ansi-regex: 6.0.1 + strip-bom@3.0.0: {} + strip-final-newline@3.0.0: {} + term-size@2.2.1: {} + + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 + universalify@0.1.2: {} + which@2.0.2: dependencies: isexe: 2.0.0 diff --git a/readme.md b/readme.md index f7f8e7e..8f6444b 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ -# focal-point-picker +# Focal Point Picker -Zero-dependency [focal point](<[url](https://en.wikipedia.org/wiki/Focus_(optics))>) picker for your WordPress website. Works with older installs, too. +Zero-dependency custom [focal point](<[url](https://en.wikipedia.org/wiki/Focus_(optics))>) picker for your WordPress images đŸŽ¯ ![CleanShot 2024-06-24 at 15 18 15@2x](https://github.com/hirasso/focal-point-picker/assets/869813/3717cedb-d1db-4192-b24d-9997e48432c9) diff --git a/readme.txt b/readme.txt index 3815fab..ee8981c 100644 --- a/readme.txt +++ b/readme.txt @@ -1,105 +1,15 @@ -=== focal-point-picker === +=== Focal Point Picker === -Zero-dependency [focal point](<[url](https://en.wikipedia.org/wiki/Focus_(optics))>) picker for your WordPress website. Works with older installs, too. +Zero-dependency custom [focal point](<[url](https://en.wikipedia.org/wiki/Focus_(optics))>) picker for your WordPress images đŸŽ¯ ![CleanShot 2024-06-24 at 15 18 15@2x](https://github.com/hirasso/focal-point-picker/assets/869813/3717cedb-d1db-4192-b24d-9997e48432c9) -== Installation == +== Description == -= Via Composer (recommended): = +Zero-dependency custom [focal point](<[url](https://en.wikipedia.org/wiki/Focus_(optics))>) picker for your WordPress images đŸŽ¯ -1. You'll need a custom entry in the `repositories` array in your `composer.json`: +**→ [Browse the docs on GitHub](https://github.com/hirasso/focal-point-picker)** -
{
-  "repositories": [
-    {
-      "type": "vcs",
-      "url": "git@github.com:hirasso/focal-point-picker.git"
-    }
-  ]
-}
+== Changelog == -2. Run `composer require hirasso/focal-point-picker` in your terminal – Done! - -= Manually: = - -1. Download and extract the plugin -2. Copy the `focal-point-picker` folder into your `wp-content/plugins` folder -3. Activate the plugin via the plugins admin page – Done! -4. Handle updates via [afragen/git-updater](https://github.com/afragen/git-updater) - -== Data structure == - -You can retrieve the focal point for an image like this: - -
$focalPoint = fcp_get_focalpoint($imageID);
-var_dump($focalPoint);
- -= Output: = - -
object(FocalPointPicker\FocalPoint)#2796 (4) {
-  ["left"]=>
-  float(0.5)
-  ["top"]=>
-  float(0.5)
-  ["leftPercent"]=>
-  float(50)
-  ["topPercent"]=>
-  float(50)
-}
- -== Usage in your templates: == - -= Object Position = - -

-
-
-
-
- -
- -= Background Position = - -

-
-
-
-
-
+**→ [View the changelog on GitHub](https://github.com/hirasso/focal-point-picker/blob/main/CHANGELOG.md)** \ No newline at end of file