Coder Social home page Coder Social logo

store-block's People

Contributors

dependabot[bot] avatar juaresba avatar vtexgithubbot avatar

Watchers

 avatar

store-block's Issues

Making the countdown block customizable

Making the countdown block customizable

Introduction

Now we have an h1 element rendered, it's possible to used it to display information that depend on the component's properties (props). For that, some concepts will be shown, given that they are essential for the app development.

Concepts

  • Hook

    Hooks are APIs that allow using React features inside functional components. Without the hooks, a functional React component is only able to render UI elements. They, hereby, allow, among other things, state storage between different renders and execute side effets to the component's life cycle. Note: They do not work inside classes.

    e.g:

    const [count, setCount] = useState(0)
  • props interface

    Defines the props Typescript typing that the component will receive, allowing IDE's intellisense about the created component.

    interface CountdownProps {
      exampleProp: string
    }
  • Block's schema

    In VTEX IO, we offer a content management tool called Site Editor. With it, through VTEX Admin, it's possible to change images, texts and behaviours of blocks without having to change the Store's code.

    In order for your block to accept user customizations, you need to export a schema in the React component responsible for the block using JSON schema. This will, automatically, generate a form in Site Editor linked to the block that you're developing. Here's a schema example:

    // react/Countdown.tsx
    Countdown.schema = {
        title: 'editor.countdown.title',
        description: 'editor.countdown.description',
        type: 'object',
        properties: {},
    }

    The schema is also responsible for defining the labels that will be displayed to the user when editing the block content on the form.

Atividade

  1. In the interface defined in Countdown.tsx, add a prop called targetDate, its type is string. We are, hence, defining a component prop that will be used to initialize the countdown.

    The prop definition itself is made through its declaration in the CountdownProps interface in the Countdown.tsx file, shown previously. Thus, add a line that define the targetDate prop of type string:

    // react/Countdown.tsx
    interface CountdownProps {
    +   targetDate: string    
    }
  2. Now, we need to use it on the component, substituting the text used used previously, Countdown Test, for another, using Site Editor.

    Keep in mind that targetDate will be used to define the countdown ending date. However, for now, it will work as a dummy field.

    First, change the component in order for it to use the targetDate prop. To do that, you need to use its variable inside the h1 of the React component.

    // react/Countdown.tsx
    const Countdown: StorefrontFunctionComponent<CountdownProps> = ({ targetDate }) => {
      return (
        <div>
          <h1>{ targetDate }</h1>
        </div>
      ) 
    }
  3. Furthermore, to be able to edit this property through Site Editor, it's necessary to add that same prop to the schema. This is done by adding the targetDate key to the properties object of the schema:

// react/Countdown.tsx
Countdown.schema = {
  title: 'editor.countdown.title',
  description: 'editor.countdown.description',
  type: 'object',
  properties: {
+   targetDate: {
+      title: 'Final date',
+      description: 'Final date used in the countdown',
+      type: 'string',
+      default: null,
+   },
  },
}

All set! Now you can change the text content through Site Editor. Go ahead to the Site Editor and click on Countdown on the side menu, this will open an edit menu, like the shown bellow:

image

Now, in the field below the title, type the date in the format AAAA-MM-DD and see the change, that will then show the text you've typed!

image

Modifying the countdown block to have configurable styles

Modifying the countdown block to have configurable styles

Introduction

Now that we have implemented the countdown, how about adding a little customization? In this step, you will learn basic concepts about CSS handles and Tachyons to customize the style of your app.

CSS Handles

CSS handles are used to customize your store's components through CSS classes in the theme code. All settings are defined through the app vtex.css-handles, responsible for declaring all the customization points of your block.

By defining the names of your handles and adding them to their respective HTML elements, it is possible to give the theme's user customization points that allow them to create flexible layouts.

Tachyons

Tachyons is a framework for functional CSS. Unlike other known frameworks, like Bootstrap, it does not have "pre-built" UI components. In fact, its purpose is, precisely, separate the CSS rules into small, reusable parts. This type of strategy is commonly known as Subatomic Design System and, if you are interested, you can find a reference in this link. This strategy makes frameworks like Tachyons very flexible, scalable and fast.

A lot of the Tachyons' definitions can be changed, so that your store will have a more customized style. To do this, just define a JSON file in the styles / configs folder; this information can be found in more detail at: Build a store using VTEX IO - Customizing styles.

Activity

  1. Import the useCssHandles hook. To do so, return to Countdown.tsx and do the import:

    // react/Countdown.tsx
    import { useCssHandles } from "vtex.css-handles"
  2. Besides, define in a Array all necessary handles (in this case, only 'countdown' will be used):

    // react/Countdown.tsx
    const CSS_HANDLES = ["countdown"]
  3. Use the useCssHandles in the component Countdown to define the countdown handle:

    // react/Countdown.tsx
    const Countdown: StorefrontFunctionComponent<CountdownProps> = ({ targetDate = DEFAULT_TARGET_DATE }) => {
      const [timeRemaining, setTime] = useState<TimeSplit>({
        hours: '00',
        minutes: '00',
        seconds: '00'
      })
    
    + const handles = useCssHandles(CSS_HANDLES)
    
      tick(targetDate, setTime)
    
      return (
        <div>
          <h1>
            { `${timeRemaining.hours}:${timeRemaining.minutes}:${timeRemaining.seconds}` }
          </h1>
        </div>
      )
    }
  4. At last, it is needed to use the handle in the component to see the customization. For this, use the prop className with the classes to be used and the Tachyons classes, for global styles.

    // react/Countdown.tsx
    import React from 'react'
    ...
    
    const Countdown: StorefrontFunctionComponent<CountdownProps> = ({ targetDate = DEFAULT_TARGET_DATE }) => {
      const [timeRemaining, setTime] = useState<TimeSplit>({
        hours: '00',
        minutes: '00',
        seconds: '00'
      })
    
      const handles = useCssHandles(CSS_HANDLES)
    
      tick(targetDate, setTime)
    
      return (
    +   <div className={`${handles.countdown} t-heading-2 fw3 w-100 c-muted-1 db tc`}>
          {`${timeRemaining.hours}:${timeRemaining.minutes}:${timeRemaining.seconds}`}
        </div>
      )
    }

Let's see the result?

image

Getting to know an app on VTEX IO

Getting to know an app on VTEX IO

Introduction

Before we start, it's necessary to remind some important concepts of the logical for a better understanding of the logical workflow when developing an app.

manifest.json

vendor

It defines the name of the VTEX account that is developing the app. This account is responsible for its maintenance and distribution (the app can be installed in other accounts or only in its own)

The vtex vendor is used for native apps

name

It identifies the name of the application. It should not contain any special characters (except from -) or uppercase characters.

version

It identifies the current app version. We use the Semantic Versioning 2.0.0 specification for versioning. The format is well defined, divided in patch, minor and major releases.

You can find bellow a summary of the specification:

  • Patches: Should be used for bug fixes that are backwards compatible
  • Minors: Should be used to add a new backwards compatible feature
  • Majors: Should be used when API incompatible changes are made (breaking changes)

For example: If an API is at version 2.3.2 and it adds a new non breaking change feature, it can then be updated to version 2.4.0.

At the moment the deployment is made, there is a worker called housekeeper which is responsible for updating automatically the new version for every account. It will, therefore, update all new minor and patch releases because of its backwards compatibility. It will not, however, automatically update major versions since it might come with dependency changes.

dependencies

An app might depend on other applications. This field lists all of the necessary dependencies for the correct app functioning.

Example

In the example of the manifest.json structure below, it's possible to see characteristics pointed out above. In particular, the app version is 0.0.1 and these numbers correspond respectively to its major, minor and patch.

{
  "vendor": "vtex",
  "name": "countdown",
  "version": "0.0.1",
  "title": "Countdown",
  "description": "Countdown component",
  "defaultLocale": "pt-BR",
  "builders": {
    "messages": "1.x",
    "store": "0.x",
    "react": "3.x"
  },
  "mustUpdateAt": "2019-04-02",
  "scripts": {
    "postreleasy": "vtex publish --verbose"
  },
  "dependencies": {
    "vtex.styleguide": "9.x",
    "vtex.css-handles": "0.x"
  },
  "$schema": "https://raw.githubusercontent.com/vtex/node-vtex-a pi/master/gen/manifest.schema"
}

Internationalization practices in VTEX IO

Internationalization practices in VTEX IO

Introduction

With the customized block in the store, we need to learn to internationalize the content presented.

It is important to remember that blocks must always follow good localization practices, and must not show hardcoded strings, but ones that are sensitive to the language that the store operates.

Don't worry, you won't need to add translations of all texts for the various languages in which the Store Framework is used. Therefore, in this stage, will be presented concepts about the internationalization of apps and how to do it.

The Messages

The concept of messages makes it easy to add new languages ​​to the theme. The Messages centralize all translation services on the platform. Given a text to be translated, Messages will first check the user-defined context, then check the translations of the apps and, finally, go through the automatic translation system.

In the directory structure, you can see that there is a folder called messages, which has three main files: pt.json, en.json andes.json, each responsible for the translations: Portuguese, English and Spanish, respectively. In addition, in order to provide better automatic translations, the context.json file is used, which is responsible for avoiding ambiguities.

To use such definitions, the translation files mentioned above are JSON, whose keys are messages and values ​​are translations.

The context.json file is necessary and must contain all messages, besides offering automatic translations in exceptional cases.

Activity

You must have learned how to use our builder messages, and it will be through it that internationalized strings will be added to the components.

  1. To do so, in the directory /messages, add now a message for the title of the component:

    messages/pt.json

    {
      ...,
    +	"countdown.title": "Contagem Regressiva"
    }

    messages/en.json

    {
      ...,
    +	"countdown.title": "Countdown"
    }

    messages/es.json

    {
      ...,
    +	"countdown.title": "Cuenta Regresiva"
    }

    messages/context.json

    {
      ...,
    +	"countdown.title": "Countdown"
    }
  2. After that, to render the title the component FormattedMessage of the lib react-intl must be used.

    The lib react-intl supports many ways of configuration and internationalization, it is worth checking it out.

  3. Add the lib using yarn add react-intl in the react directory

  4. In your component's code, Countdown.tsx, import the FormattedMessage

    //react/Countdown.tsx
    import { FormattedMessage } from 'react-intl'
  5. Add a new prop to the interface CountdownProps:

    interface CountdownProps {
    + title: string
      targetDate: string
    }
  6. Add a const that will be your title:

    //react/Countdown.tsx
    const titleText = title || <FormattedMessage id="countdown.title" />
  7. Now, join the title to the countdown to render. To do so, define a container outside. Besides, the text for the title will be passes using the prop title:

    //react/Countdown.tsx
    const Countdown: StorefrontFunctionComponent<CountdownProps> = ({
      title,
      targetDate,
    }) => {
      const [timeRemaining, setTime] = useState<TimeSplit>({
        hours: '00',
        minutes: '00',
        seconds: '00',
      })
    
      const titleText = title || <FormattedMessage id="countdown.title" />
      const handles = useCssHandles(CSS_HANDLES)
    
      tick(targetDate, setTime)
    
      return (
        <div className={`${handles.container} t-heading-2 fw3 w-100 c-muted-1`}>
          <div className={`${handles.title} db tc`}>{titleText}</div>
          <div className={`${handles.countdown} db tc`}>
            {`${timeRemaining.hours}:${timeRemaining.minutes}:${timeRemaining.seconds}`}
          </div>
        </div>
      )
    }

    Note that three new handles are used: container, countdown and title. Therefore, remember to declare them in the const CSS_HANDLES, seen in the previous step:

    const CSS_HANDLES = ["container", "countdown", "title"]
  8. At last, it is needed to add the title prop in the schema:

    //react/Countdown.tsx
    Countdown.schema = {
      title: 'editor.countdown.title',
      description: 'editor.countdown.description',
      type: 'object',
      properties: {
    +   title: {
    +     title: 'I am a title',
    +     type: 'string',
    +     default: null,
    +   },
        targetDate: {
          title: 'Final date',
          description: 'Final date used in the countdown',
          type: 'string',
          default: null,
        },
      },
    }

Done! Now, to try out your store in another languages, you just need to add the query string /?cultureInfo=pt-br or /?cultureInfo=es-ar on the URL, for example. By using the first URL, the expected result is this one:

image

Componentizing the countdown block

Componentizing the countdown block

Introduction

In this step, the app has two main elements: the title and the countdown. However, in order to obtain greater positioning and customization flexibility, it is interesting that they are separated into two distinct blocks. For this, it is necessary to briefly introduce the concept of interfaces, and then a new Title component will be developed. An example of customization in terms of positioning, which will be covered in this step, is:

What if I wanted the title to be under or beside the counter?

Interface

An interface works like a contract, with well-defined restrictions on how the blocks will work together. It then defines a mapping that creates a Store Framework block, from a React component. It is important to highlight that the use of interfaces, in order to separate an app in several interfaces, makes the customization power much greater.

When defining an app in the interface, the component property is responsible for defining the React component that will be used. It is important to note that the name of component must be the same as the file name of the component inside the react/ folder.

interfaces.json examples:

{
  "countdown": {
    "component": "Countdown"
  }
}

Activity

In this activity, the title will be separated and added to the store below the countdown.

Altering the Countdown component

  1. Remove the imports, the title from the interface and change the CSS handles const, CSS_HANDLES:

    //react/Countdown.tsx
    import React, { useState } from 'react'
    import { TimeSplit } from './typings/global'
    import { tick } from './utils/time'
    import { useCssHandles } from 'vtex.css-handles'
    -import { FormattedMessage } from 'react-intl'
    
    interface CountdownProps {
      targetDate: string,
    -  title: string
    }
    
    const DEFAULT_TARGET_DATE = (new Date('2020-03-02')).toISOString()
    -const CSS_HANDLES = ['container', 'countdown', 'title']
    +const CSS_HANDLES = ['countdown']
  2. Now, in the component itself, remove the title as a prop given and also the title text constant, which changes what is being rendered:

    //react/Countdown.tsx
    const Countdown: StorefrontFunctionComponent<CountdownProps> = ({
    - title,
      targetDate = DEFAULT_TARGET_DATE,
    }) => {
      const [
        timeRemaining,
        setTime
      ] = useState<TimeSplit>({
        hours: '00',
        minutes: '00',
        seconds: '00'
      })
    
    - const titleText = title || <FormattedMessage id="countdown.title" />
      const handles = useCssHandles(CSS_HANDLES)
    
      tick(targetDate, setTime)
    
      return (
    -   <div className={`${handles.container} t-heading-2 fw3 w-100 pt7 pb6 c-muted-1 db tc`}>
    -     <div className={`${handles.title} db tc`}>
    -       { titleText }
    -     </div>
          <div className={`${handles.countdown} db tc`}>
            {`${timeRemaining.hours}:${timeRemaining.minutes}:${timeRemaining.seconds}`}
          </div>
    -   </div>
      )
    }
  3. At last, remove the title from the schema:

    //react/Countdown.tsx
    Countdown.schema = {
      title: 'editor.countdown.title',
      description: 'editor.countdown.description',
      type: 'object',
      properties: {
    -   title: {
    -     title: 'I am a title',
    -     type: 'string',
    -     default: null,
    -   },
        targetDate: {
          title: 'Final date',
          description: 'Final date used in the countdown',
          type: 'string',
          default: null,
        },
      },
    }

Creating a new component

  1. Create a new file in the /react directory, named Title.tsx, it will be the new title component. In it, some imports are needed. The basic structure of the code is very similar to the Countdown component's.

  2. Add the imports needed and the CSS handles constant:

    //react/Title.tsx
    import React from "react"
    import { FormattedMessage } from "react-intl"
    import { useCssHandles } from "vtex.css-handles"
    
    const CSS_HANDLES = ["title"] as const
  3. Change the component's function:

    //react/Title.tsx
    const Title: StorefrontFunctionComponent<TitleProps> = ({ title }) => {
      const handles = useCssHandles(CSS_HANDLES)
      const titleText = title || <FormattedMessage id="countdown.title" />
    
      return (
        <div
          className={`${handles.title} t-heading-2 fw3 w-100 c-muted-1 db tc`}
        >
          {titleText}
        </div>
      )
    }
  4. Add the interface, the schema and the export:

    //react/Title.tsx
    interface TitleProps {
      title: string
    }
    
    Title.schema = {
      title: "editor.countdown-title.title",
      description: "editor.countdown-title.description",
      type: "object",
      properties: {
        title: {
          title: "I am a title",
          type: "string",
          default: null,
        },
      },
    }
    
    export default Title

Changing the interfaces.json file

By now, there are two components in the app: the title and the countdown. However, it is necessary to change the interfaces.json file, which is in store folder. It is needed to declare each one separately. At first, our interface only contained the Countdown. It is needed to add the other component:

{
  "countdown": {
    "component": "Countdown"
  },
+   "countdown.title": {
+     "component": "Title"
+   }
}

Adding internationalization

It is also needed to add to the Messages the translations whose keys are the strings of the schema that we included in the Title.tsx file above. As seen in the Messages step, go to the /messages folder and add the necessary translations to each file (pt.json, es.json and en.json). Below is an example for the case of the en.json file:

 {
   "countdown.title": "Countdown",
   "editor.countdown.title": "Countdown",
   "editor.countdown.description": "Countdown component",
+  "editor.countdown-title.title": "Countdown title",
+  "editor.countdown-title.description": "Title component",
 }

Adding the new block to the store home

Finally, to see the changes, go back to the theme to change it to include the new block. To do so, simply add the title to home! Same as the countdown, it is necessary to add countdown.title as a block in the theme of your store, in the store-theme file home.jsonc.

//home.jsonc
 {
   "store.home": {
     "blocks": [
       "countdown",
+      "countdown.title",
       ...
     ]
   },
   ...
 }

Done! Now let's see how the result should look like:
image

Linking an app and using it on a store's theme

Linking an app and using it on a store's theme

Introduction

To develop a store front block, like the ones provided natively in Store Framework, we use the UI development library React.js.

A little about the tool

React's basic development unit is a component, in which should be implemented all-in-one the logical operation, visual interface and data retrieval of an UI element. Following the most recent recommendation, we will focus our usage in the Hook API, not using class definition for component building.

In VTEX IO, we adopt Typescript as default language for frontend programming. Despite the complexity of learning new syntaxes, the effort is quickly rewarded! Using Typescript, the bug anticipation is enhanced, because of its static typing. Besides that, with the right IDEs, it's possible to increase the development speed with a smarter code completion of the code objects.

In this course, we'll use Typescript exclusively. If you're not familiar with the language, it will be a great chance to give it a try!

Step objective

Since you're already familiar to Store Framework, you know that we use blocks, like shelf and sku-selector, to create a VTEX IO store. In this step you're going to create a block that is going to be used in your store's home page theme.

Setting up our test bot

It's important for you to have out test bot installed in this course repository so as for us to see your progress, even though it does not contains any tests or evaluation on each step. So as to install it, follow the steps below:

  1. Open our test bot installation page and click on Configure;

  2. Select the Only selected repositories option, then click on Select repositories and type in store-block;

  3. Click on juaresba/store-block and then on Install.

Activity

  1. In the local template cloned, open up the Countdown.tsx file:

    //react/Countdown.tsx
    import React from 'react'
    
    interface CountdownProps {}
    
    const Countdown: StorefrontFunctionComponent<CountdownProps> = ({}) => {
      return <div></div>
    }
    
    Countdown.schema = {
      title: 'editor.countdown.title',
      description: 'editor.countdown.description',
      type: 'object',
      properties: {},
    }
    
    export default Countdown
  2. Add an h1 tag inside the component and link it in your terminal, using the command vtex link.

    const Countdown: StorefrontFunctionComponent<CountdownProps> = ({}) => {
    -   return <div></div>
    +   return (
    +     <div>
    +       <h1>Countdown Test</h1>
    +     </div>
    +   )
    }

    IMPORTANT: In order to the component that you've just linked to be seen in a functional store, you need to declare the block that the app defines in a theme. For that, hereby, we need to first have a theme to add the app to. In this course, we'll use the Store Theme. To clone the repository just run a:

    git clone https://github.com/vtex-apps/store-theme.git
    
  3. To avoid conflicts, go to your terminal and unlink any theme or apps you have linked. To do that, head just run the following command:

    vtex unlink --all
    
  4. With the repository cloned, go to its folder (cd store-theme) and link the theme on your workspace:

    vtex link
    

    IMPORTANT: At this point, you need to have two terminals opened and running vtex link. The first one contains the link of the custom block that you're creating and the second one refers to the store-theme, the theme you're using to insert your custom block on.

  5. Now, with both links active (theme and custom block), in order to use the app on the theme, we have to add it to the theme's dependencies, which, is in the manifest.json. Therefore, head to the theme's manifest in the store-theme folder and add vtex.countdown as a dependency. Its version is defined in its manifest (0.0.1). The manifest will then have one extra line like it is defined below:

    {
        ...
        "dependencies": {
            ...
    +        "vtex.countdown": "0.x",
            ...
        },
        ...
    }
  6. Lastly, we need to add the block to the store. Inside the file store-theme/store/blocks/home/home.jsonc, declare countdown block:

    {
        "store.home": {
            "blocks": [
                "countdown",
                ...
            ]
            ...
        }
        ...
    }
    

The expected result is to find a h1 in the top of the store, you can see it below:

image

Creating the countdown block feature

Creating the countdown block feature

Introduction

Now we covered the component's basics, it's time to implement the countdown effectively. For that, we need to use a React hook called useState.

The useState hook

It is called within the functional component to update and consume the component state. The state represents the component's current state.

The useState returns a pair: the current state value and a function to update it.

Seeing the example provided the previous step we can understand these concepts:

const [count, setCount] = useState(0)

In the above code piece, you might observe three things:

  • In the count variables, it's possible to get the current state;
  • setCount is a function used for updating it;
  • 0 is its initial state;
const [timeRemaining, setTime] = useState<TimeSplit>({
  hours: '00', 
  minutes: '00', 
  seconds: '00'
})

Activity

  1. We need to import a few functions and types to continue:

    //react/Countdown.tsx
    import React, { useState } from 'react'
    import { TimeSplit } from './typings/global'
    import { tick } from './utils/time'
  2. Add the state update hook (useState):

    //react/Countdown.tsx
    const Countdown: StorefrontFunctionComponent<CountdownProps> = ({ targetDate }) => {
    +   const [timeRemaining, setTime] = useState<TimeSplit>({
    +     hours: '00',
    +     minutes: '00',
    +     seconds: '00'
    +   })
    
        return (
          <div>
            { targetDate }
          </div>
        ) 
    }
  3. Add a default constant targetDate for the edge case where the prop is not defined:

    //react/Countdown.tsx
    const DEFAULT_TARGET_DATE = (new Date('2020-06-25')).toISOString()
  4. Use the tick function and the DEFAULT_TARGET_DATE constant to make the countdown work:

    //react/Countdown.tsx
    const Countdown: StorefrontFunctionComponent<CountdownProps> = ({ targetDate = DEFAULT_TARGET_DATE }) => {
      const [timeRemaining, setTime] = useState<TimeSplit>({
        hours: '00',
        minutes: '00',
        seconds: '00'
    })
    
    + tick(targetDate, setTime)
    
      return (
        <div>
          { targetDate }
        </div>
      ) 
    }
  5. Change the h1 so that it shows the countdown that we've created. For that, we need to use the timeRemaining current state:

    //react/Countdown.tsx
    const Countdown: StorefrontFunctionComponent<CountdownProps> = ({ targetDate = DEFAULT_TARGET_DATE }) => {
      const [timeRemaining, setTime] = useState<TimeSplit>({
        hours: '00',
        minutes: '00',
        seconds: '00'
      })
    
      tick(targetDate, setTime)
    
      return (
        <div>   
    -     <h1>{ targetDate }</h1>
    +     <h1>{ `${timeRemaining.hours}:${timeRemaining.minutes}:${timeRemaining.seconds}` }</h1>
        </div>
      ) 
    }

    The countdown string formatting is in a HH:MM:SS format, made through an hours, minutes and seconds splitting.

Therefore, with these changes, we'll see a real time update of the countdown! The result in the homepage is this:

image

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.