Giter Club home page Giter Club logo

vite-plugin-image-optimizer's Introduction

vite logo

Vite Image Optimizer

Plugin for Vite to optimize all images assets using Sharp.js and SVGO at build time.

node-current npm peer dependency version npm bundle size GitHub release licence

 

Features

  • Optimize SVG assets using SVGO and pass custom configs.
  • Optimize scalar assets (png, jpeg, gif, tiff, webp, avif) using Sharp.js with the option to pass custom configs for each extension type.
  • Option to process all assets from your public directory defined in the bundler.
  • Configure test, include, and exclude to filter assets.
  • Skip processing assets if their optimized size is greater than their original size.
  • Log the optimization stats showing the before and after size difference, ratio and total savings (optional) terminal output image

Motivation

This plugin is based on the awesome image-minimizer-webpack-plugin for Webpack. I wanted to combine the optimization capabilities of Sharp.js and SVGO in a single package and I couldn't find a plugin for Vite that could accomplish this. I initially thought of adding squoosh and imagemin support as well but dropped the idea since they are no longer maintained.

If you find the plugin useful, consider showing your support by giving a ⭐

Contributions are most welcome! We follow conventional-commits

Installation

You can add it as a dev dependency to any of the package managers (NPM, Yarn, PNPM)

Supports Vite >=3 and Node >=14

npm install vite-plugin-image-optimizer --save-dev

Warning

sharp and svgo don't come installed as part of the package. You will have to install them manually and add it as a dev dependency. This is a design decision so you can choose to skip installing sharp if you only want to optimize svg assets using svgo and vice versa.

npm install sharp --save-dev
npm install svgo --save-dev

Usage

import { ViteImageOptimizer } from 'vite-plugin-image-optimizer';
import { defineConfig } from 'vite';

export default defineConfig(() => {
  return {
    plugins: [
      ViteImageOptimizer({
        /* pass your config */
      }),
    ],
  };
});

Default Configuration

The default configuration is made for lossless compression of image assets.

const DEFAULT_OPTIONS = {
  test: /\.(jpe?g|png|gif|tiff|webp|svg|avif)$/i,
  exclude: undefined,
  include: undefined,
  includePublic: true,
  logStats: true,
  ansiColors: true,
  svg: {
    multipass: true,
    plugins: [
      {
        name: 'preset-default',
        params: {
          overrides: {
            cleanupNumericValues: false,
            removeViewBox: false, // https://github.com/svg/svgo/issues/1128
          },
          cleanupIDs: {
            minify: false,
            remove: false,
          },
          convertPathData: false,
        },
      },
      'sortAttrs',
      {
        name: 'addAttributesToSVGElement',
        params: {
          attributes: [{ xmlns: 'http://www.w3.org/2000/svg' }],
        },
      },
    ],
  },
  png: {
    // https://sharp.pixelplumbing.com/api-output#png
    quality: 100,
  },
  jpeg: {
    // https://sharp.pixelplumbing.com/api-output#jpeg
    quality: 100,
  },
  jpg: {
    // https://sharp.pixelplumbing.com/api-output#jpeg
    quality: 100,
  },
  tiff: {
    // https://sharp.pixelplumbing.com/api-output#tiff
    quality: 100,
  },
  // gif does not support lossless compression
  // https://sharp.pixelplumbing.com/api-output#gif
  gif: {},
  webp: {
    // https://sharp.pixelplumbing.com/api-output#webp
    lossless: true,
  },
  avif: {
    // https://sharp.pixelplumbing.com/api-output#avif
    lossless: true,
  },
  cache: false,
  cacheLocation: undefined,
};

Plugin Options

test

Type: RegExp

Default: /\.(jpe?g|png|gif|tiff|webp|svg|avif)$/i

Test to match files against.

exclude

Type: String | RegExp | Array<string>

Default: undefined

Files to exclude.

include

Type: String | RegExp | Array<string>

Default: undefined

Files to include.

Warning

This will override any options set in test and exclude and has a higher preference. Use this option if you want to include specific assets only.

includePublic

Type: boolean

Default: true

Include all assets within the public directory defined in Vite. When true it will recursively traverse the directory and optimize all the assets.

logStats

Type: boolean

Default: true

Logs the optimization stats to terminal output with file size difference in kB, percent increase/decrease and total savings.

ansiColors

Type: boolean

Default: true

Logs the optimization stats or errors with ansi colors in the terminal. Set it to false for shells that don't support color text.

svg

Type: SVGOConfig

Default:

{
  multipass: true,
  plugins: [
    {
      name: 'preset-default',
      params: {
        overrides: {
          cleanupNumericValues: false,
          removeViewBox: false, // https://github.com/svg/svgo/issues/1128
        },
        cleanupIDs: {
          minify: false,
          remove: false,
        },
        convertPathData: false,
      },
    },
    'sortAttrs',
    {
      name: 'addAttributesToSVGElement',
      params: {
        attributes: [{ xmlns: 'http://www.w3.org/2000/svg' }],
      },
    },
  ]
}

Config object to pass to SVGO, you can override it with your custom config.

png

Type: PngOptions

Default:

{
  // https://sharp.pixelplumbing.com/api-output#png
  quality: 100,
}

Config object to pass to Sharp.js for assets with png extension

jpeg

Type: JpegOptions

Default:

{
  // https://sharp.pixelplumbing.com/api-output#jpeg
  quality: 100,
}

Config object to pass to Sharp.js for assets with jpg or jpeg extension

gif

Type: GifOptions

Default:

{
  // https://sharp.pixelplumbing.com/api-output#gif
}

Config object to pass to Sharp.js for assets with gif extension

tiff

Type: TiffOptions

Default:

{
  // https://sharp.pixelplumbing.com/api-output#tiff
  quality: 100,
}

Config object to pass to Sharp.js for assets with tiff extension

webp

Type: WebpOptions

Default:

{
  // https://sharp.pixelplumbing.com/api-output#webp
  lossless: true,
}

Config object to pass to Sharp.js for assets with webp extension

avif

Type: AvifOptions

Default:

{
  // https://sharp.pixelplumbing.com/api-output#avif
  lossless: true,
}

Config object to pass to Sharp.js for assets with avif extension

cache

Type: boolean

Default: false

Cache assets in cacheLocation. When enabled, reads and writes asset files with their hash suffix from the specified path.

cacheLocation

Type: String

Default: undefined

Path to the cache directory. Can be used with GitHub Actions and other build servers that support cache directories to speed up consecutive builds.

License

MIT

vite-plugin-image-optimizer's People

Contributors

cijiugechu avatar dmkelly avatar fatehak avatar fidian avatar hex-ci avatar maartenba avatar mfjordvald avatar quentiumyt avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

vite-plugin-image-optimizer's Issues

About assetInlineLimit setting inline problems

Describe the feature you'd like to request

If assetsInlineLimit: ()=>true || 100kb is set in the vite build option, the original image will be wrapped in the package

Describe the solution you'd like

can compress only before inline packaging

Additional context

2024-03-21_14-38-24
2024-03-21_14-39-32

Validations

  • Read the docs.
  • Check that there isn't already an issue that requests the same feature to avoid creating a duplicate.

Make peer dependencies agree with vite >= 4

Describe the Bug

When installing the plugin with npm i -D vite-plugin-image-optimizer, it throws an error with a mismatching peer version (in the case of me having a vite version v4 and above).

If you are also experiencing this issue, you can just override it with --force.

Steps to reproduce

  1. Initialize a vite v4 project (preferrably NPM)
  2. Run npm i -D vite-plugin-image-optimizer

System Info

Binaries:
    Node: 18.7.0 - /usr/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 9.2.0 - /usr/local/bin/npm
  Browsers:
    Chrome: 110
    Firefox: 107
  npmPackages:
    vite: ^4.3.0-beta.5 => 4.3.0-beta.5 


### Used Package Manager

npm

### Validations

- [X] Read the [docs](https://github.com/FatehAK/vite-plugin-image-optimizer#readme).
- [X] Check that there isn't [already an issue](https://github.com/FatehAK/vite-plugin-image-optimizer/issues) that reports the same bug to avoid creating a duplicate.

Run from CLI

Describe the feature you'd like to request

I'd like to run this plugin from the CLI while I'm developing the app, to preoptimize files before even pushing to Git.

Describe the solution you'd like

A CLI tool, or an equivalent package.json script.

Additional context

No response

Validations

  • Read the docs.
  • Check that there isn't already an issue that requests the same feature to avoid creating a duplicate.

Type definitions for project

Describe the Bug

When I import ViteImageOptimizer } in nuxt.config.ts on a TypeScript based project
Then a warning about missing type declarations occurs

Steps to reproduce

Create new nuxt project
Install plugins and dependencies (sharp, svgo)

Add to nuxt.config.ts

// `Could not find a declaration file for module 'vite-plugin-image-optimizer'`
import { ViteImageOptimizer } from 'vite-plugin-image-optimizer'

Results in the error above, no types exist for lib.

System Info

Windows 11 (but same result in Ubuntu 22.04 and MacOS latest)

 System:
    OS: Windows 10 10.0.22621
    CPU: (16) x64 AMD Ryzen 7 5800X 8-Core Processor
    Memory: 37.36 GB / 63.93 GB
  Binaries:
    Node: 18.12.1 - C:\Program Files\nodejs\node.EXE
    npm: 9.5.1 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Spartan (44.22621.963.0), Chromium (110.0.1587.49)
    Internet Explorer: 11.0.22621.1
  npmPackages:
    @vitejs/plugin-vue: ^4.0.0 => 4.0.0
    vite: ^4.1.4 => 4.1.4
    vite-plugin-image-optimizer: ^1.0.8 => 1.0.8
    vite-tsconfig-paths: ^4.0.5 => 4.0.5
    vitest: ^0.28.5 => 0.28.5

Used Package Manager

pnpm

Validations

  • Read the docs.
  • Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.

Automatic resizing of images

Describe the feature you'd like to request

It would be useful to based on the file extension or folder structure decide what is the max resolution for each file.
For example, some of my icons are 1024x1024 but that size is unnecessary in production, so it would be nice to before optimization reduce their size to 256x256 and then optimize. Keeping the aspect ratio should not break anything (and it would be optional anyway).

Describe the solution you'd like

An entry in config that helps with resizing the images based on extension or folder structure.

Additional context

No response

Validations

  • Read the docs.
  • Check that there isn't already an issue that requests the same feature to avoid creating a duplicate.

Totals for the stats

Describe the feature you'd like to request

It would be nice if the stats also printed out a total at the bottom: total % and total Kb/Mb saved.

Describe the solution you'd like

If this was another config flag, maybe logStatsTotal, that would also be fine - although I don't think that's nescessary.

Additional context

Thanks very much for this awesome vite plugin - it works great!

Validations

  • Read the docs.
  • Check that there isn't already an issue that requests the same feature to avoid creating a duplicate.

Display only summary of total savings

Describe the feature you'd like to request

Thanks for this awesome plugin! It would be nice with an option to only show the summary of total savings. :)

Describe the solution you'd like

A new option for show totals, or one for show individual files

Additional context

No response

Validations

  • Read the docs.
  • Check that there isn't already an issue that requests the same feature to avoid creating a duplicate.

"Caching" - Support

Describe the feature you'd like to request

I'd like to be able to not run the optimization on images that have already been optimized before.

Describe the solution you'd like

Haven't looked in detail in the code yet so there might be a better approach, but I'd suggest adding 2 configuration parameters, "cache" (boolean) and "cachePath" (string). If cache is set to true, we save a file in the cachePath which is basically a list of the image path + name and it's related hash. This way we could check if an already cached image was changed if not, there is no need to rebuild it

Additional context

We are using this plugin at JetBrains right now to rebuild our blog. As you can imagine we have plenty of pictures and graphics and stuff, so optimizing the image takes roughly 6 minutes right now, every single time

Validations

  • Read the docs.
  • Check that there isn't already an issue that requests the same feature to avoid creating a duplicate.

Input image exceeds pixel limit

当图片(gif)过大,出现这个报错
1704348119282
可以在ViteImageOptimizer调整这个参数么,还是需要sharp里调整参数呢

support vite5

Describe the feature you'd like to request

support vite5

Describe the solution you'd like

support vite5

Additional context

No response

Validations

  • Read the docs.
  • Check that there isn't already an issue that requests the same feature to avoid creating a duplicate.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Pending Approval

These branches will be created by Renovate only once you click their checkbox below.

  • chore(deps-major): Update dependency @commitlint/cli to v19
  • chore(deps-major): Update dependency @typescript-eslint/parser to v7
  • chore(deps-major): Update dependency eslint to v9
  • chore(deps-major): Update dependency eslint-config-prettier to v9
  • chore(deps-major): Update dependency eslint-formatter-pretty to v6
  • chore(deps-major): Update dependency eslint-plugin-sonarjs to v1
  • chore(deps-major): Update dependency husky to v9
  • chore(deps-major): Update dependency lint-staged to v15
  • chore(deps-major): Update dependency prettier to v3
  • chore(deps-major): Update dependency release-it to v17
  • chore(deps-major): Update dependency vite to v5
  • chore(deps-major): Update dependency vite-plugin-dts to v3
  • chore(deps-major): Update pnpm to v9
  • 🔐 Create all pending approval PRs at once 🔐

Awaiting Schedule

These updates are awaiting their schedule. Click on a checkbox to get an update now.

  • chore(deps): Update dependency @types/node to ^20.14.8
  • chore(deps): Lock file maintenance

Detected dependencies

npm
package.json
  • ansi-colors ^4.1.3
  • pathe ^1.1.2
  • @commitlint/cli ^17.8.1
  • @types/node ^20.14.7
  • @typescript-eslint/parser ^5.62.0
  • concurrently ^8.2.2
  • czg 1.9.3
  • eslint ^8.57.0
  • eslint-config-prettier ^8.10.0
  • eslint-config-semistandard ^17.0.0
  • eslint-formatter-pretty ^5.0.0
  • eslint-plugin-only-warn ^1.1.0
  • eslint-plugin-promise ^6.2.0
  • eslint-plugin-sonarjs ^0.25.1
  • husky ^8.0.3
  • lint-staged ^13.3.0
  • prettier ^2.8.8
  • release-it ^15.11.0
  • rimraf ^5.0.7
  • rollup-plugin-visualizer ^5.12.0
  • sharp ^0.33.4
  • svgo ^3.3.2
  • typescript ^5.5.2
  • vite ^4.5.3
  • vite-plugin-dts ^2.3.0
  • pnpm 8.15.8

  • Check this box to trigger a request for Renovate to run again on this repository

image conversion

Describe the feature you'd like to request

Hello, is it possible to convert images to different formats?

Describe the solution you'd like

conversion: [
{from: 'png', to: 'jpeg' },
{ from: 'jpeg', to: 'webp' },
]

Additional context

No response

Validations

  • Read the docs.
  • Check that there isn't already an issue that requests the same feature to avoid creating a duplicate.

Not type-safe with a typescript config for Vite 4.1.1

Describe the Bug

I have to use ViteImageOptimizer() as PluginOption as a workaround, otherwise VSCode complains (no issues with the actual build):

image

Full config:

import react from '@vitejs/plugin-react';
import { ViteImageOptimizer } from 'vite-plugin-image-optimizer';
import { defineConfig, PluginOption } from 'vite';

export default defineConfig({
  plugins: [react(), ViteImageOptimizer() as PluginOption],
});

Steps to reproduce

  • Use a Typescript Vite config "vite.config.ts" with Vite 4.1.1.

System Info

-

Used Package Manager

yarn

Validations

  • Read the docs.
  • Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.

Convert to different image formats

Describe the feature you'd like to request

It would be really great if you could convert an image into a different image formats for production

for example converting a png image into another format available in sharp like webp/avif/etc...

I think this would be great to save people the time when doing the conversion, and to save some additional space.

Describe the solution you'd like

maybe a toFormat option in the config file since that is the name of the method in the sharp package. Where you can specify as a string what format you would like to image to be converted to.

Additional context

https://sharp.pixelplumbing.com/api-output#toformat

Thank You!

Validations

  • Read the docs.
  • Check that there isn't already an issue that requests the same feature to avoid creating a duplicate.

Build fails with custom test regexp

Describe the Bug

When running a build with a custom test regexp option, I get the following error:

[vite-plugin-image-optimizer] options.test.test is not a function
error during build:
TypeError: options.test.test is not a function
    at ./node_modules/vite-plugin-image-optimizer/dist/index.js:216:30
    at Array.forEach (<anonymous>)
    at Object.closeBundle (./node_modules/vite-plugin-image-optimizer/dist/index.js:215:20)

This appears to be related to the deepClone function that is called as part of merging the provided options with the default options. This function checks for whether a value is an object, but doesn't account for the value being a regexp. The test value ends up being replaced with an empty object. The following additional check for if a value is a regexp seems to fix builds:

function deepClone(src) {
  const isRegex = Object.prototype.toString.call(src) === "[object RegExp]";
  if (typeof src !== "object" || src === null || isRegex)
    return src;
  const target = Array.isArray(src) ? [] : {};
  for (const key in src) {
    const value = src[key];
    target[key] = deepClone(value);
  }
  return target;
}

Steps to reproduce

ViteImageOptimizer({
  test: /\.(jpe?g|png|gif|tiff|webp|avif)$/i,
}),

System Info

System:
    OS: macOS 13.2
    CPU: (10) arm64 Apple M2 Pro
    Memory: 82.55 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.13.0 - ~/.nvm/versions/node/v18.13.0/bin/node
    npm: 8.19.3 - ~/.nvm/versions/node/v18.13.0/bin/npm
  Browsers:
    Chrome: 109.0.5414.119
    Safari: 16.3
  npmPackages:
    @vitejs/plugin-react: 3.1.0 => 3.1.0
    vite: 4.1.1 => 4.1.1
    vite-plugin-environment: 1.1.3 => 1.1.3
    vite-plugin-fonts: 0.7.0 => 0.7.0
    vite-plugin-image-optimizer: 1.0.7 => 1.0.7
    vite-plugin-minify: 1.5.2 => 1.5.2
    vite-plugin-preload: 0.2.0 => 0.2.0
    vite-plugin-svgr: 2.4.0 => 2.4.0
    vite-tsconfig-paths: 4.0.5 => 4.0.5

Used Package Manager

npm

Validations

  • Read the docs.
  • Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.

Not working in Laravel 10

Describe the Bug

I'm can't run your plugin. I'm not see stats showing in console after build. I'm not have optimized images.
Снимок экрана 2023-08-20 в 01 34 16
Снимок экрана 2023-08-20 в 01 35 54
Снимок экрана 2023-08-20 в 01 36 32

Steps to reproduce

  1. I have image by path: ./resources/img/logo.png
  2. I'm run command: npm run build
  3. I'll hope to see my image by path ./public/build/assets/img/logo.png

System Info

No error info. I'm not see stats showing in console after build

Used Package Manager

npm

Validations

  • Read the docs.
  • Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.

Option to create copies of assets in webp / avif formats upon build

Describe the feature you'd like to request

Would be really nice if the processor could also make copies of ie. jpg and png in webp and / or avif formats along the way, so that the output would be ie like this on my media/stock/food folder containing the img-7.jpg image:

media/stock/food/img-7.jpg -42% 45.67kb -> 26.67kb
media/stock/food/img-7.webp -72% 16.17kb -> 4.67kb. Added
media/stock/food/img-7.avif -64% 22.57kb -> 6.26kb Added

Describe the solution you'd like

Option to create webp and / or avif images upon build

Even better if option to check if added files are bigger, and then skip

Additional context

Thank you very much in advance!!

Validations

  • Read the docs.
  • Check that there isn't already an issue that requests the same feature to avoid creating a duplicate.

Public folder is being ignored if root is set

Describe the Bug

Hey, congratulations on this amazing plugin.

I'm trying to compress images from the public folder using a customized root folder.

Using default root config plugin works fine 😃

// vite.config.mjs
export default defineConfig({
  plugins: [
    ViteImageOptimizer({}),
  ],
})

Screenshot 2024-02-26 at 3 50 46 PM

Changing root path, public assets are not being compressed. 😢

// vite.config.mjs
export default defineConfig({
  root: './src',
  publicDir: '../public',
  build: {
    outDir: '../dist',
    emptyOutDir: true,
  },
  plugins: [
    ViteImageOptimizer({}),
  ],
})

Screenshot 2024-02-26 at 3 50 16 PM

Steps to reproduce

A broken example can be found on https://github.com/tiagoporto/sign-of-the-horns-single-div/blob/main/vite.config.mjs

npm run build

System Info

System:
    OS: macOS 13.6.2
    CPU: (12) arm64 Apple M2 Pro
    Memory: 2.95 GB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.10.0 - ~/.nvm/versions/node/v20.10.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v20.10.0/bin/yarn
    npm: 10.2.3 - ~/.nvm/versions/node/v20.10.0/bin/npm
    pnpm: 8.15.4 - ~/.nvm/versions/node/v20.10.0/bin/pnpm
  Browsers:
    Chrome: 122.0.6261.69
    Chrome Canary: 124.0.6323.0
    Safari: 16.6
  npmPackages:
    vite: ^5.1.4 => 5.1.4 
    vite-plugin-image-optimizer: ^1.1.7 => 1.1.7 
    vite-plugin-minify: ^1.5.2 => 1.5.2 
    vite-plugin-pwa: ^0.19.0 => 0.19.0

Used Package Manager

npm

Validations

  • Read the docs.
  • Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.

Config cacheLocation throw error when deploy on Vercel.

Describe the Bug

when I deploy my project in vercel, it throw an error:

"Error: ENOENT: no such file or directory, mkdir './node_modules/.cache/imageOptimizer'".

And my configuration:

ViteImageOptimizer({
  cache: true,
  cacheLocation: './node_modules/.cache/imageOptimizer',
})

Steps to reproduce

Deploy an application on Vercel and follow my configuration.

System Info

vite: 4.3.9;
vite-plugin-image-optimizer: 1.1.7;
vue: 3.3.4;
platform: vercel;

Used Package Manager

yarn

Validations

  • Read the docs.
  • Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.