Coder Social home page Coder Social logo

cordova-plugin-contacts-phone-numbers's Introduction

ContactsPhoneNumbers

Cross-platform plugin for Cordova / PhoneGap to list all the contacts with at least a phone number.

Installing the plugin

cordova plugin add cordova-plugin-contacts-phonenumbers

or use this repository (unstable)

cordova plugin add https://github.com/dbaq/cordova-plugin-contacts-phone-numbers.git

iOS Quirks

Since iOS 10 it's mandatory to provide an usage description in the info.plist if trying to access privacy-sensitive data. When the system prompts the user to allow access, this usage description string will displayed as part of the permission dialog box, but if you didn't provide the usage description, the app will crash before showing the dialog. Also, Apple will reject apps that access private data but don't provide an usage description.

This plugins requires the following usage description:

  • NSContactsUsageDescription describes the reason that the app accesses the user's contacts.

To add this entry into the info.plist, you can use the edit-config tag in the config.xml like this:

<edit-config target="NSContactsUsageDescription" file="*-Info.plist" mode="merge">
    <string>need contacts access to search friends</string>
</edit-config>

Using the plugin

The plugin creates the object navigator.contactsPhoneNumbers with the methods

list(success, fail)

Usage in typescript file

declare let navigator: any;

A full example could be:

   //
   //
   // after deviceready
   //
   //
   navigator.contactsPhoneNumbers.list(function(contacts) {
      console.log(contacts.length + ' contacts found');
      for(var i = 0; i < contacts.length; i++) {
         console.log(contacts[i].id + " - " + contacts[i].displayName);
         for(var j = 0; j < contacts[i].phoneNumbers.length; j++) {
            var phone = contacts[i].phoneNumbers[j];
            console.log("===> " + phone.type + "  " + phone.number + " (" + phone.normalizedNumber+ ")");
         }
      }
   }, function(error) {
      console.error(error);
   });

JSON Response format

The success callback function contains an array of contacts.

Each entry contains:

  • the unique contact id
  • the name of the contact (first name, last name, display name)
  • an array containing the number, the normalizedNumber and the type of the number (WORK, MOBILE, HOME or OTHER)

Here is a sample of what you can get:

    [{
        "id": "1",
        "firstName": "Kate",
        "middleName": "",
        "lastName": "Bell",
        "displayName": "Kate Bell",
        "thumbnail": null,
        "phoneNumbers": [{
            "number": "(555) 564-8583",
            "normalizedNumber": "(555) 564-8583",
            "type": "MOBILE"
        }, {
            "number": "(415) 555-3695",
            "normalizedNumber": "(415) 555-3695",
            "type": "OTHER"
        }]
    }, {
        "id": "2",
        "firstName": "Daniel",
        "middleName": "",
        "lastName": "Higgins",
        "displayName": "Daniel Higgins",
        "thumbnail": null,
        "phoneNumbers": [{
            "number": "555-478-7672",
            "normalizedNumber": "555-478-7672",
            "type": "HOME"
        }, {
            "number": "(408) 555-5270",
            "normalizedNumber": "(408) 555-5270",
            "type": "MOBILE"
        }, {
            "number": "(408) 555-3514",
            "normalizedNumber": "(408) 555-3514",
            "type": "OTHER"
        }]
    }, {
        "id": "3",
        "firstName": "John",
        "middleName": "Paul",
        "lastName": "Appleseed",
        "displayName": "John Paul Appleseed",
        "thumbnail": "content://com.android.contacts/contacts/49/photo",
        "phoneNumbers": [{
            "number": "888-555-5512",
            "normalizedNumber": "888-555-5512",
            "type": "MOBILE"
        }, {
            "number": "888-555-1212",
            "normalizedNumber": "888-555-1212",
            "type": "HOME"
        }]
    }]

Behaviour

The plugin retrieves ONLY the contacts containing one or more phone numbers. It does not allow to modify them (use the official cordova contacts plugin for that).

With the official plugin, it is difficult and inefficient[1] to retrieve the list of all the contacts with at least a phone number (for Android at least). I needed a fastest way to retrieve a simple list containing just the name and the list of phone numbers.

If you need more fields like the email address or if you also need to retrieve the contacts without email address, we can add an option, open an issue and I'll see what I can do.

[1] When I say difficult and inefficient, it is because on Android, all your Gmail contacts are returned as a contact. See this issue on stackoverflow. With the official plugin you have to retrieve all the contacts and then iterate over the result to filter out what you want.

I executed a small benchmark on my Nexus 5 with Lollipop. The code calls both plugins and displays the result in the console. On this phone I have 1028 contacts but only 71 contacts have at least a phone number. Of course the performances depends on the number of contacts with phone numbers.

cordova-plugin-contacts

*  1 call:
    try 1: 2.527s
    try 2: 2.581s
    try 3: 2.221s

    => average of 2.443s

* 10 calls:
    try 1: 6.048s
    try 2: 9.196s
    try 3: 8.981s

    => average of 8.075s for 10 calls

cordova-plugin-contacts-phone-numbers

*  1 call
    try 1: 0.145s
    try 2: 0.185s
    try 3: 0.286s

    => average of 0.205s

* 10 calls:
    try 1: 1.195s
    try 2: 1.211s
    try 3: 1.351s

    => average of 1.252s for 10 calls

iOS and Android

The plugin works with iOS and Android.

iOS does not provide a normalized number like Android. So number === normalizedNumber for iOS.

The thumbnail is not returned on iOS, if you want iOS support, feel free to open a PR.

The Android code is heavily inspired from the official plugin with some tweaks to improve the perfomances.

Donations

If your app is successful or if you are working for a company, please consider donating some beer money ๐Ÿบ:

paypal

Keep in mind that I am maintaining this repository on my free time so thank you for considering a donation. ๐Ÿ‘

Contributing

Thanks for considering contributing to this project.

Finding something to do

Ask, or pick an issue and comment on it announcing your desire to work on it. Ideally wait until we assign it to you to minimize work duplication.

Reporting an issue

  • Search existing issues before raising a new one.

  • Include as much detail as possible.

Pull requests

  • Make it clear in the issue tracker what you are working on, so that someone else doesn't duplicate the work.

  • Use a feature branch, not master.

  • Rebase your feature branch onto origin/master before raising the PR.

  • Keep up to date with changes in master so your PR is easy to merge.

  • Be descriptive in your PR message: what is it for, why is it needed, etc.

  • Make sure the tests pass

  • Squash related commits as much as possible.

Coding style

  • Try to match the existing indent style.

  • Don't mix platform-specific stuff into the main code.

Licence

The MIT License

Copyright (c) 2013 Didier Baquier

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

cordova-plugin-contacts-phone-numbers's People

Contributors

dbaq avatar kodeine avatar lomski avatar mihirpatel avatar peterchibunna avatar scorobogaci avatar stefanomagrassi avatar uriva avatar vicatcu 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

cordova-plugin-contacts-phone-numbers's Issues

ngCordova

I think your plugin is brilliant. I have started using it with Ionic and the ngCordova module.

I have included a basic interface for this plugin in my ngCordova fork. I will be submitting a pull request to ngCordova once I have added some testing. I have also created a mock definition in ngCordovaMocks which I have found really useful during development.

If you feel it is useful then please include this in your README.md. My fork of ngCordova can be installed for the moment using

bower install https://github.com/miskinh/ng-cordova.git#contacts-phone-numbers --save

Happy coding,
Henry

Expose device data to application

Hi,

I need some help with accessing the data... I am trying to expose the data retrieved from the device to my application but without success. I am using the following code which executes fine; writing a list of the normalized numbers and then on completion of this writing an array of these number to the console.

        var success = function(contacts) {
          var numbersList = [];
          for(var i = 0; i < contacts.length; i++) {
            for(var j = 0; j < contacts[i].phoneNumbers.length; j++) {
              var phone = contacts[i].phoneNumbers[j];
              if (phone.type === 'MOBILE' && contacts[i].displayName != null){
                console.log("=> " + phone.normalizedNumber);
                numbersList.push(phone.normalizedNumber);
              }
            }
          }
          console.log(numbersList);
        }
        var failure = function() {
          console.log('error');
        }
        navigator.contactsPhoneNumbers.list(success, failure);

What i need is to pass this array to my application however it is not visible form outside of the success function. likewise if i try and pass a predefined variable (numberList:any = [];) into the success function and try to populate it there ( this.numbersList.push(phone.normalizedNumber); ) I get the error.

TypeError: Cannot read property 'numbersList' of null

Any help would be greatly appreciated.

Cheers.

got error with last version of cordova-plugin-contacts

typescript: plugins/com.dbaq.cordova.contactsPhoneNumbers/www/ContactsPhoneNumbers.d.ts, line: 18
Interface 'Contact' incorrectly extends interface 'ContactProperties'. Types of property 'phoneNumbers' are
incompatible. Type 'ContactPhoneNumber[]' is not assignable to type 'ContactField[]'. Type
'ContactPhoneNumber' is not assignable to type 'ContactField'. Property 'type' is optional in type
'ContactPhoneNumber' but required in type 'ContactField'.

  L18:  interface Contact {
  L19:      /** A globally unique identifier. */

[16:33:40] typescript: plugins/cordova-plugin-contacts/types/index.d.ts, line: 140
Subsequent variable declarations must have the same type. Variable 'Contact' must be of type 'new (id?:
string, firstName?: string, LastName?: string, displayName?: string, phoneNumbers?: Con...', but here has
type 'new (id?: string, displayName?: string, name?: ContactName, nickname?: string, phoneNumbers?: Con...'.

 L139:  emails?: ContactField[],
 L140:  addresses?: ContactAddress[],
 L141:  ims?: ContactField[],

Benchmark was performed with hasPhoneNumber?

I was wondering if you performed the benchmark with hasPhoneNumber on true in the official plugin? Or was this option not available at that time?

Wondering if I still need to combine both the plugins or if it was fixed with hasPhoneNumber in the official plugin.

Contact Photo

Firstly I would like to say thank you so much for your work here. I have been struggling for a while with stupidly long load times on my app, and trading out the official contacts plugin for your's has dropped my loading time from 10 seconds to less than 1, it's unbelievable, well done.

Secondly, I apologise as this question has been discussed already in issue #11 , so I would just like to know if you will be including thumbnail URL's for Android and iOS in the future?

Regards

cordova plugin add cordova-plugin-contacts-phonenumbers

Trying to add your plugin leads to the following error:

Error: Failed to fetch plugin git+https://github.com/dbaq/cordova-plugin-contacts-phone-numbers.git via registry.
Probably this is either a connection problem, or plugin spec is incorrect.
Check your connection and plugin name/version/URL.
Failed to get absolute path to installed module

Discovered plugin "com.dbaq.cordova.contactsPhoneNumbers" in config.xml. Adding it to the project

Failed to restore plugin "com.dbaq.cordova.contactsPhoneNumbers" from config.xml. You might need to try adding it again. Error: Failed to fetch plugin com.dbaq.cordova.contactsPhoneNumbers@git+https://github.com/dbaq/cordova-plugin-contacts-phone-numbers.git via registry.
Probably this is either a connection problem, or plugin spec is incorrect.
Check your connection and plugin name/version/URL.
Failed to get absolute path to installed module

build on cordova-ios 4.0.1 failed

I am using phonegapbuild and wanted to update to ios cordova version 4.0.1

The Build log shows this error:

The following build commands failed:
    CompileC build/Jabbit.build/Release-iphoneos/Jabbit.build/Objects-normal/armv7/CDVContactsPhoneNumbers.o Jabbit/Plugins/com.dbaq.cordova.contactsPhoneNumbers/CDVContactsPhoneNumbers.m normal armv7 objective-c com.apple.compilers.llvm.clang.1_0.compiler

retrieving email

"If you need more fields like the email address or if you also need to retrieve the contacts without email address, we can add an option, open an issue and I'll see what I can do."

I really would appreciate the option for additional email information :)

nice plugin!

Error when compiling

I get this error when i try compiling my app

=> Errors executing Cordova commands:                                              

   While building Cordova app for platform Android:
   Error: /Users/user121007/thepeoplemap/.meteor/local/cordova-build/platforms/android/cordova/build: Command failed with exit code 8 Error output:
   /Users/user121007/thepeoplemap/.meteor/local/cordova-build/platforms/android/src/com/dbaq/cordova/contactsPhoneNumbers/ContactsManager.java:51: error: cannot
   find symbol
   if (cordova.hasPermission(android.Manifest.permission.READ_CONTACTS)) {
   ^
   symbol:   method hasPermission(String)
   location: variable cordova of type CordovaInterface
   /Users/user121007/thepeoplemap/.meteor/local/cordova-build/platforms/android/src/com/dbaq/cordova/contactsPhoneNumbers/ContactsManager.java:54: error: cannot
   find symbol
   cordova.requestPermission(this, READ_CONTACTS_REQ_CODE, android.Manifest.permission.READ_CONTACTS);
   ^
   symbol:   method requestPermission(ContactsManager,int,String)
   location: variable cordova of type CordovaInterface
   Note: Some input files use or override a deprecated API.
   Note: Recompile with -Xlint:deprecation for details.
   Note: Some input files use unchecked or unsafe operations.
   Note: Recompile with -Xlint:unchecked for details.
   2 errors

   FAILURE: Build failed with an exception.

   * What went wrong:
   Execution failed for task ':compileReleaseJava'.
   > Compilation failed; see the compiler error output for details.

How to use this plugin in iOnic2 ?

I am new to iOnic 2. I have followed your instruction & trying to use this plugin in my project but not succeeded. Facing below two errors.

If use import {ContactsPhoneNumbers, Contact} from 'com.dbaq.cordova.contactsPhoneNumbers'

  1. Cannot find module "com.dbaq.cordova.contactsPhoneNumbers"

if use declare var contactsPhoneNumbers:any;
2) Uncaught (in promise): ReferenceError: contactsPhoneNumbers is not defined

request you to please guide me for the same. If you can provide sample project its really appreciate...

Thanks in Advance....

How to use this plugin ?

Respected sir,

How do I use this plugin on PhoneGap ? I have installed the plugin in phonegap. Do I need to define .js file ? And where should I write this code? Here is my code :

document.addEventListener("deviceready", onDeviceReady, false);

    function onDeviceReady()
    {
        navigator.contactsPhoneNumbers.list(function(contacts) {
          alert(contacts.length + ' contacts found');
          for(var i = 0; i < contacts.length; i++) {
             console.log(contacts[i].id + " - " + contacts[i].displayName);
             for(var j = 0; j < contacts[i].phoneNumbers.length; j++) {
                var phone = contacts[i].phoneNumbers[j];
                console.log("===> " + phone.type + "  " + phone.number + " (" + phone.normalizedNumber+ ")"); 
             }
          }
       }, function(error) {
          console.error(error);
       });
    }

Is this correct ? Thanks!

Display name in iOS

Hi ,

display name returned a space when it's empty , and i don't want to remove the empty space to some function because may i have a contact with one character name .

thanks,
rana

iOS Phone Type not correct

Hi ,

There is a problem in this plugin for iOS platform , it's returned wrong phone type .
can you fix that .

and can you return the first name separated with last name .

Thanks
rana .

wrap plugin into angular -- specifically ngCordova

HI , need to expose your api ,thought angular service , am planning wrap it inside a promise , to be available the angular digest circle ,
also i see on issue , there is filter api exposed any documentation on that would be appreciate
i cant find the navigator.contact namespace , am using this on android , am thinking am missing a step

$ionicPlatform.ready()
    .then(function() {
        var q = $q.defer();
        var returnContacts = [];

        navigator.contactsPhoneNumbers.list(function(contacts) {
            console.log(contacts.length + ' contacts found');
            for (var i = 0; i < contacts.length; i++) {
                    returnContacts.push({
                    'name': contacts[i].displayName,
                    'FirstnumberOnly':contacts[i].phoneNumbers[0],
                });
            q.resolve(returnContacts);

            }
        }, function(error) {
            console.error(error);
            q.reject('plugin error' + error);
        });

        return q.promise;
    });

any advice would be appreciate very much

Contact Name

Hi ,

can you please return the first name, last name

thanks
rana,

Request for some filters for Fetching

Hi
Can we add one small flexibility of passing some few parameters further to filter the Contacts. (Something like DisplayName having some pattern or Ph Numbers have some ISD code etc)

Package dependencies issue

After I install the plugin everything fine.
But each time I run a Cordova command (e.g running on a device), it adds a new package to the dependencies: com.dbaq.cordova.contactsPhoneNumbers
So, I end with two dependencies related to this plugin:
cordova-plugin-contacts-phonenumbers and com.dbaq.cordova.contactsPhoneNumbers

To install some other stuff using npm, I had to remove com.dbaq.cordova.contactsPhoneNumbers directly from the file, so I won't get a 404 error.

Build error for ios - duplicate symbols

duplicate symbol OBJC_METACLASS$_CDVAddressBookHelper in:
Objects-normal/i386/CDVContactsPhoneNumbers.o
Objects-normal/i386/CDVContacts.o

ld: 2 duplicate symbols for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

** BUILD FAILED **

Version details:
echo "-> clang "; clang -v; echo "-> xcodebuild "; xcodebuild -version; echo "-> cordova " $(cordova -version); echo "-&gt; ionic " $(ionic -version);

-> clang
Apple LLVM version 7.0.0 (clang-700.0.72)
Target: x86_64-apple-darwin14.5.0
Thread model: posix
-> xcodebuild
Xcode 7.0.1
Build version 7A1001
-> cordova 5.3.3
-> ionic 1.7.6

unable to fetch this plugin during installation

Error - Plugin error (you probably need to remove plugin files from your app): Fetching plugin "com.dbaq.cordova.contactsPhoneNumbers" via npm Failed to fetch plugin com.dbaq.cordova.contactsPhoneNumbers via registry. Probably this is either a connection problem, or plugin spec is incorrect. Check your connection and plugin name/version/URL. Error: Not found : com.dbaq.cordova.contactsPhoneNumbers - You can fix this here
unable to fetch this plugin during installation on phonegap

Thumbnail photo

I know this is meant to be a light plugin, but we have not a way to retreive contact photos.
I will make this feature for my project, if you want, i can pull it.

Build error on android with cordova 5

Hi,
When building my project for android I get the following error:
cannot find symbol: cordova.hasPermission(string)
Anyone has a hint about this ?

IOS: Is NSContactsUsageDescription requirement applicable to this plugin?

The cordova-plugin-contacts repository has the section excerpted below in the README. Does it also apply to this plugin? if so, maybe it should be duplicated in the README. If not, it should probably also be stated why not. I suspect it does.

iOS Quirks
Since iOS 10 it's mandatory to provide an usage description in the info.plist if trying to access privacy-sensitive data. When the system prompts the user to allow access, this usage description string will displayed as part of the permission dialog box, but if you didn't provide the usage description, the app will crash before showing the dialog. Also, Apple will reject apps that access private data but don't provide an usage description.

This plugins requires the following usage description:

NSContactsUsageDescription describes the reason that the app accesses the user's contacts.
To add this entry into the info.plist, you can use the edit-config tag in the config.xml like this:

<edit-config target="NSContactsUsageDescription" file="*-Info.plist" mode="merge">
   <string>need contacts access to search friends</string>
</edit-config>

Ionic 3

Can this plugin work with ionic 3 ? Any example ?

fetching contacts in batches

Hi @dbaq ,

Your plugin works great for me. However, I had one request - I noticed that it takes an average of 10 secs or more to pick an entire contacts list (ranging from 700 stored contacts to 1400 stored contacts). 10 seconds is too long a wait in my opinion so can you help me with - fetching contacts in batches, where your plugin fetches contacts in batches - either by no. of contacts (i.e., 100 at a time) or by alphabet (i.e, all contacts starting with โ€˜aโ€™ first, then starting with โ€˜bโ€™ and so on)

CDVContactsPhoneNumbers.m:22:9 'Cordova/NSArray+Comparisons.h' file not found

On xcode, archive build fails with error
CDVContactsPhoneNumbers.m:22:9 'Cordova/NSArray+Comparisons.h' file not found

Xcode version - Version 7.2.1 (7C1002)
Cordova-Ios - 4.1.0
Cordova version - 6.0.0
com.dbaq.cordova.contactsPhoneNumbers" spec="~0.0.6" ( installed via nam and direct git also)

Archive build succeeds, if i remove this plugin.

install error

$ cordova plugin add cordova-plugin-contacts-phonenumbers
Error: Failed to fetch plugin git+https://github.com/dbaq/cordova-plugin-contacts-phone-numbers.git via registry.
Probably this is either a connection problem, or plugin spec is incorrect.
Check your connection and plugin name/version/URL.
Failed to get absolute path to installed module

How can I access the value of 'contacts' outside of the navigator.contactsPhoneNumbers.list()?

Hello,
When I implement this code with DrupalGap, I want to access the value from the function in the navigator.contactsPhoneNumbers.list(), outside if it. I want to create a variable with the HTML table tags to the contact names and phone numbers of the contacts. The access the variable outside of the function.

contactCount ='';
navigator.contactsPhoneNumbers.list(function(contacts) {
contactCount = "

Total contacts :" + contacts.length + "

";
}, function(error) {
console.error(error);
});

alert(contactCount); // This does not shows any value.

fix for installation issue not released

I've encountered an issue while using the latest release version that is already fixed in #47
Would be great if a new release is made that supports this so we can use
cordova plugin add cordova-plugin-contacts-phonenumbers again without issues instead of having everyone using the unstable git version or forking.

Unable to use this plugin in Intel XDK

I am trying to add this plugin in Intel XDK thrid-party plugins. I have given plugin id at com.dbaq.cordova.contactsPhoneNumbers and Repo URl as https://github.com/dbaq/cordova-plugin-contacts-phone-numbers.git but even after bulding the whole project for android, when I use navigator.contactsPhoneNumbers.list after deviceReady event, I get "Cannot read property 'list' of undefined". Is there anything, I am missing. The Cordova CLI version is 4.1.2

Note that, I have tested the build on android phone but still no success.

How to know if contact have a photo?

I'm using this plugin (thanks) and can display photo of contact but, contacts without a photo... how I can to know if contact have a photo? Contacts without photo display a 404 image :-(

Cannot read phone contacts

I have noticed that the plugin only reads contacts available in the sim card and do not read phone contacts. Can i read from the phone contacts?.

Doesn't work with Iphone6.

Hi, when i attempt to pull all contacts no callback is ever called.

Do we have any idea what may be causing this?

Thanks an awesome plugin, the speed benchmarking is incredibly useful.

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.