Git Product home page Git Product logo

leaflet.offline's People

Contributors

allartk avatar bmcbride avatar brotkiste avatar dependabot[bot] avatar fil avatar firefishy avatar harry-73 avatar helgasoft avatar robertomlsoares avatar sallesma avatar slurmulon 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

leaflet.offline's Issues

Manual installation instructions

This library looks extremely promising but I cannot seem to follow the instructions in the read-me on how install it. There is no file 'dist/leaflet.offline.min.js'. I am by no means experienced in the Javascript world so I would be grateful for some advice. Thanks in advance!
At the same place there is mention of localforage which I suspect should instead be idb as mentioned under the features in version 2.

Move to a more permissive License

To be honest, the GPL seems like an odd choice considering the rest of the Leaflet environment mostly uses MIT / Appache Licenses. Many companies also do not consider using GPL licenses due to legal uncertainties. Any chance you would consider changing the license?

saveTile is not a function

Hi there,

I get the following error when I try to call the saveTile function:

core.js:1449 ERROR Error: Uncaught (in promise): TypeError: WEBPACK_IMPORTED_MODULE_2_leaflet_offline.saveTile is not a function
TypeError: WEBPACK_IMPORTED_MODULE_2_leaflet_offline.saveTile is not a function

it's ionic-angular project.

I imported the modules correctly, since getStorageInfo function works fine without any errors...

help please

Scale tiles when missing?

Hi just wondering if it's possible when you're offline to replace any missing tiles with scaled versions of the closest zoom level available. I've seen a phone app that does this and it works pretty good.

TileManager.js Missing from NPM Package

Is TileManager supposed to be included in the package? It's in the source on the master branch and its methods are referenced in the github pages example but it doesn't actually show up in the NPM package.

Steps to replicate the issue:

Install the library and inspect the src files and bundle.js.

And/Or:

Inspect the npm tarball itself using a tool such as list-npm-contents.

This is the list of all the files in the latest package version:
package.json
.eslintrc.js
.travis.yml
documentation.yml
index.html
karma.conf.js
LICENSE
README.md
rollup.config.js
dist/bundle.js
docs/api.md
src/ControlSaveTiles.js
src/images/save.png
src/index.js
src/localforage.js
src/TileLayerOffline.js
test/SaveTilesTest.js
test/TileLayerTest.js

Downloadbutton outside of map

Hi,
your plugin looks great :)
I'm planning to integrate it in my leaflet application, but I'd prefer to have the download/delete button in the layercontrol next to the layer selector.
Something like this (not tested):

var control = L.control.savetiles(offlineLayer, {
            ...
        });

var baseMaps = {
    "OfflineLayer <button onclick="control._saveTiles()">...</button>": offlineLayer
};

Do you think this could be supported by the plugin or do you know a nicer way to do this?

Thanks :)

CORS issue

Hi. This is the first time I've posted an issue so apologies if its a silly one. I've been attempting to integrate the plugin into my website maps, however I seem to encounter a CORS issue at the GET tiles step. My data is stored in an AWS bucket, which has a CORS * policy, allowing access. The JS loads the tiles correctly for viewing however when saving I get the following error:
Access to XMLHttpRequest at 'FILE PATH' from origin 'https://bathymaps.com.au' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. My website htaccess file allows CORS, so I'm assuming its something to do with the way the JS requests to GET the tiles from the bucket? Any help would be great.

npm 1.0.4 needs to be rebuilt

Hi there, I think the bundle.js that's currently in the npm 1.0.4 package does not have the latest changes in it. The src is all current, so I think you just need to run npm build and then npm publish to get the dist/bundle.js up to date.

I ended up forking the package to add an option that limits the maximum number of tiles that's stored locally, but I also had to rebuild before that just to get the latest commit.

Thanks for this awesome library! Let me know if you have any questions about my issue.

Save zoom based on what you see and deeper.

Hi!
So, the way it is now, the tiles are saved based on the zoomLevels parameter that you pass for the control. I would like to do it more dynamic instead of hardcoding the zoom levels. For example, the user goes to the place and zooms out and clicks save. Then the layer would save the zoom that he is at at the moment + deeper zooms based on a maxZoom parameter (or a max one that we determine if maxZoom is not provided).
Do you want a pull request for that also? Or should I leave that feature only in my fork? I'm not sure if I like the idea of passing the zoomLevels array to determine what you're gonna save because it's not really what the user sees.

load event fired to often

I've recently started to make our maps work offline and this plugin has been a huge help.
But I've noticed a small Problem. We use the 'load' event in the Tilelayer that is supposed to fire when all the tiles in view are loaded.

Before switching to your plugin the event was fired exactly once on loading the map before any zooming or panning happens. Now after the switch the event fires about 30 times.

I've seen that this plugin has a 'loadend' event but as far as I can tell this only fires when downloading tiles with the SaveTiles control.

permanent cache for tiles

hi,

i tested the demo and found that when closing the browser all downloaded tiles are gone

how can i download tiles and keep them in browser local storage between sessions (permanent until refreshed by the user)

Downloading tiles on Google Chrome net::ERR_INSUFFICIENT_RESOURCES

Hi,

When saving about 3000 tiles, it just gives net::ERR_INSUFFICIENT_RESOURCES in chrome error.

I do understand that it would be an issue downloading like 20k+ tiles, but I would expect it to be possible do download about 3k?

This is without any subdomains. Which my tileLayer does not have.

Error importing library

When installed via npm and imported in my main.js file I get the following error upon compiling the project:

Error Failed to compile with 1 errors
This dependency was not found:
* leaflet.offline in ./src/main.js
To install it, you can run: npm install --save leaflet.offline

Steps to duplicate:

  • Set up a new Vue project with Vue Cli: vue create NEW_PROJ
  • Choose manual configuration and add PWA support
  • Install dependencies: npm install leaflet idb
  • Install library: npm install leaflet.offline
  • Verify installed modules are present in node_modules
  • Import library in main.js: import 'leaflet.offline'
  • Compile project with npm run serve

A few questions

Trying out this plugin for the first time, I have a few questions (maybe for the README?):

  • How many tiles can the browser download before reaching the limits of IndexedDB storage, and how do we manage (detect, purge older tiles etc) when they have been reached?

  • More generally how would you recommend to remove older tiles?

  • How to connect an action from my own interface (i.e. not the offline controls) to the "download all the visible region" function?

thanks!

Error saving tiles to tileStore using API calls

Trying to write code to download and save tiles using API calls instead of L.control from the example. Any insights?

` const bounds = map.getBounds();
const zoom = map.getZoom();
const crs = map.options.crs;

const p1 = crs.latLngToPoint(bounds.getNorthEast(), zoom).floor();
const p2 = crs.latLngToPoint(bounds.getSouthWest(), zoom).floor();
const tiles = LeafletOffline.getTileUrls(baseLayer, L.bounds(p1, p2), zoom);

for (i = 0; i < tiles.length; i++) {
LeafletOffline.downloadTile(tiles[i].url).then(blob => LeafletOffline.saveTile(tiles[i], blob));
}`

This is the error I'm getting when it's calling saveTile:
Failed to execute 'put' on 'IDBObjectStore': Evaluating the object store's key path did not yield a value.

Tiles being saved as undefined

Hi,

I believe I'm using leaflet.offline correctly but I'm getting weird results. I copy/pasted from the example into my own project. Now all of the functionality appears to work. I can monitor the download progress, see how many tiles are currently saved etc. However, when trying to load the tiles with no internet connection they never load.

I dug into the chrome application tab under developer tools and think I found the reason. (note, the example suffers from the same problem)

The forage section under IndexedDB appears empty, and all the tile entries have undefined in the Value column.
image
image

Any help would be appreciated, thanks :)

Webworker enable

I love how this has been implemented but I've found one thing that prevents me from using it. It is unusable for downloading anything more than a couple thousand tiles at a time - it essentially brings the browser to a halt.

I've been learning npm and more advanced javascript stuff and trying to understand in detail how all this works and believe that implementing a webworker to do the tile downloading and saving to idb would resolve this issue.

Any thoughts on that approach?

savetiles without L.control

well done for all this work.
I would like to be able to save the tiles without button directly when opening the map, without clicking (without L.control).
it's possible ?
Thank you.

Saving WMS or ESRI tiles

We use Leaflet to display a base map using Here Map tiles and then display our customer's own map data as overlays. That data is either WMS or ESRI which we display using the ESRI Leaflet plugin. Is it possible to save these tiles for offline display along with the base map tiles?

Safari?

Hi,

thanks for your efforts with this project!

Just wanted to ask if you ever tested Safari (8.x) with your code? Seems like the indexDB stuff is failing...looks like Safari cannot store blobs like old chrome...

Error uncatched: [Error] DataCloneError: DOM IDBDatabase Exception 25: The data being stored could not be cloned by the internal structured cloning algorithm.
Error message catched exception: DataCloneError: DOM IDBDatabase Exception 25

Loads 'undefined' when added to map. Multiple baselayer support?

When using tilelayer.offline and adding it to a map. The leaflet offline script will make a call to load "/undefined" resource.
This can be tested by loading the example site and seeing the network request for http://allartk.github.io/leaflet.offline/undefined.

Should there be anything at this path?

Also, when I save some tiles on a base layer and recreate the Save/Remove controls for a new base layer with L.control.savetiles(baseLayer, {...}), a JS error saying the function is not a callback is thrown. Is there an additional step to working with multiple base layers? Thanks.

Update idb

  • #117 should be direct dep
  • Allow 6 & 7 if there are no regressions.

_getStorageKey is mangling URLs

I reviewed the code but can't find the specific.

using cartodb's basemap url:

https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png

The plugin appears to come up with:

https://a.rtodb-basemaps-a.global.ssl.fastly.net/light_all/6/56/28.png

Not sure how it's doing the mangling.

Example is broken in firefox

De cors headers are not present anymore requesting tiles from openstreetmap, according to my local firefox. Cannot be replicated in chromium
Cross-Origin-aanvraag geblokkeerd: de Same Origin Policy staat het lezen van de externe bron op http://a.tile.openstreetmap.org/13/4209/2706.png niet toe. (Reden: CORS-header ‘Access-Control-Allow-Origin’ ontbreekt).

Importing TileManager

Hello,

I'm using version 2.0.0-beta.4, and I'm trying to use the static functions from TileManager.
I am using React with TypeScript and Electron.

The important as written in the docs
import * from 'leaflet.offline/TileManager';
doesn't work for me, it says I have to use 'as', such as:
import * as Offline from 'leaflet.offline/TileManager';
than I get:
Module not found: Error: Can't resolve 'leaflet.offline/TileManager'

I tried to see what auto completion has to offer, and the only way I can get it to work is as follows:
import * as Offline from 'leaflet.offline/src/TileManager';

I saw that inside the bundle.js file all of those functions exists, I just can't get to them. On a similar issue, Inside the module, I saw that the index.js is exporting only part of the functions (getStorageInfo, getTileUrls, getStorageLength, truncate, getStoredTilesAsJson, removeTile), is there a reason for it?

Thanks a lot!

Saving tiles and share

Hi,

First of all this is a great project and it works as advertise, the question is can you save specific tiles on specific zoom then save it then distribute this as part of the application? I'm planning to create hybrid up and wrap it with cordova (Offline Map Navigation)?

Setting bounds on saveTiles

One more question :)
I'm thinking about manually setting the bounds of the downloaded area to the scope off my app. E.g. via options.
This way you only have to download once and you have covered the whole service area of my mountain rescue department.
What do you think about that?
I think I could do a pull-request within next week

leaflet dependency vs peerDependency

I just tried updating leaflet to the new version 1.7.1 in one of my projects that also uses leaflet.offline and the project just stopped working because L.tileLayer.offline was undefined. After looking around for a bit I noticed, that while my project was now using leaflet 1.7.1, leaflet.offline was still importing a separate version of leaflet 1.6.0

I'm using yarn as a package manager (not sure if it also happens with npm) and I was finally able to resolve it by just throwing away my yarn.lock and doing a fresh install.

I don't have much experience with maintaining packages, but I think leaflet.offline being a plugin for leaflet would be a good case for leaflet being a peerDependency rather than a normal dependency of the package.

Or is there any reason why it needs to be a direct dependency?

iOS Safari indexedDB bug

Current iOS Safari seems to have a bug with indexedDB right now. It is already reported on the idb library:
jakearchibald/idb#227
jakearchibald/idb-keyval#120

So I'm not sure if we need a new version here right now. But in case any one else has this problem there is an easy workaround for now. As mentioned in the second issue putting window.indexedDB.open('test'); before using leaflet.offline fixes the problem.

Function confirming the removal of tiles.

Hi, I started using this lib for a project and some features would be easier to add in its source code instead of hacking my code so I don't need to alter the code from libraries. For example I need a confirmation that the user wants to delete all the tiles (it shouldn't be too hard). Is that something that interests you? I can send pull requests if you'd like help with it.

Can't pass in multiple params into data url

_getStorageKey doesn't allow for attributes such as accessToken or id to be passed into layer.
Use case:

var offlineLayer = L.tileLayer.offline('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
        id: 'mapbox.streets',
        accessToken: 'xyz'
      }).addTo(map);

Gives error:

"Error: No value provided for variable {id}"

_getStorageKey(coords) {
      return getTileUrl(this._url, {
        ...coords,
        s: this.options.subdomains['0'],
      });
    },

Should be something similar to this:

_getStorageKey(coords) {
      return getTileUrl(this._url, Object.assign({
        ...coords,
        s: this.options.subdomains['0'],
    }, this.options));

To allow different attributes to be passed in

ERROR Error: Request failed with status 200

Full diagnosis:

Error: Request failed with status 200
    at XMLHttpRequest.xhr.onreadystatechange [as __zone_symbol__ON_PROPERTYreadystatechange] (http://localhost:8100/build/vendor.js:174277:15)
    at XMLHttpRequest.H (http://localhost:8100/build/polyfills.js:3:23950)
    at t.invokeTask (http://localhost:8100/build/polyfills.js:3:15660)
    at Object.onInvokeTask (http://localhost:8100/build/vendor.js:5125:33)
    at t.invokeTask (http://localhost:8100/build/polyfills.js:3:15581)
    at r.runTask (http://localhost:8100/build/polyfills.js:3:10834)
    at e.invokeTask [as invoke] (http://localhost:8100/build/polyfills.js:3:16794)
    at p (http://localhost:8100/build/polyfills.js:2:27648)
    at XMLHttpRequest.v (http://localhost:8100/build/polyfills.js:2:27893)

I am using your script in Ionic Framework, installed through npm install leaflet.offline.

I have checked my storage, the script does seem to capture the tiles into db
screen shot 2018-07-28 at 3 50 30 am

Another problem is, type script won't recognise .offline and .saveTiles.
screen shot 2018-07-28 at 3 53 54 am

My compiler gives this error message:

[14:51:46]  typescript: src/pages/home-map-view2/home-map-view2.ts, line: 45 
            Property 'offline' does not exist on type 'typeof tileLayer'. 

[14:51:46]  typescript: src/pages/home-map-view2/home-map-view2.ts, line: 52 
      L44:  //offline baselayer, will use offline source if available
      L45:  var baseLayer = leaflet.tileLayer.offline('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      L46:      attribution: 'Map data {attribution.OpenStreetMap}',

            Property 'savetiles' does not exist on type 'typeof control'.

Please help. Thanks.

Multiple maps

Hey this project is really cool! Thanks for working on it!

I was wondering if it is possible to have a concept of multiple maps with this implementation.

What I mean by that is presume you have a hiking application with two different suggested hikes.

You save the map for 'hike A' and then save the map for 'hike B' then you could individually remove the tiles meant for 'hike A' or 'hike B' or else just prompt the storage to load only the tiles for 'hike A'.

I hope this makes sense.

Thanks

SaveWhatYouSee Only Saves Current Zoom Level

I am having an issue similar to #2, but on my own map not the example one. I am using a TMS style tile directory generated with gdal2tiles and serving it locally. The map loads just fine but If I set saveWhatYouSee to be true I only get correct URLs for the current zoom level, after that it requests tiles that don't exist and I get uncaught 404 request errors:
Uncaught Error: Request failed with status 404 at XMLHttpRequest.n.onreadystatechange

However, if I manually go to a lower zoom level (e.g. 16 -> 17) I can save the tiles at the new zoom level but not any deeper (17 will save but not 18).

The tile numbers almost looks like the TMS: true value isn't being propagated to the deeper zoom levels but am not sure if that makes sense or not.

I can share code but am not sure how much it will help as I'm using VueJS and Vue2Leaflet so the set up is quite different from the example. I don't expect you to be able to debug my code but am wondering if you are aware of any issues that could cause this behavior.

Here's my component code in case it's useful. The map is in a div in my index.html file.

<template>
  <div>
  <Observation/>
  <br>
  <b-container fluid>
    <b-row align-v="center">
      <b-col>
        <p>
          Progress: <span id="progress">0</span> / <span id="total">0</span>
          Current storage length:
          <span id="storage"></span> files
          <button
            class="btn btn-success"
            id="show_storage"
            data-toggle="modal"
            data-target="#storageModal"
          >
            Show storage info
          </button>
          <button class="btn btn-danger" id="remove_tiles">
            <i
              class="fa fa-trash"
              aria-hidden="true"
              title="Remove tiles"
            ></i>
          </button>
        </p>
      </b-col>
    </b-row>
    <b-row align-v="center">
      <b-col>
        <l-map class="centered" ref="myMap" style="height: 400px; width: 800px" :zoom=16 :center="emancipation" @click="openObservationForm">
          <v-locatecontrol/>
         </l-map>
      </b-col>
    </b-row>
  </b-container>
  <br/>
  <br/>
</div>
</template>

<script>
  import L from 'leaflet';
  import 'leaflet.offline'
  import Observation from "./Observation";

  export default {
    name: "ExampleMap",
    components: {
      Observation
    },
    mounted() {
      this.$nextTick(() => {
        var map = this.$refs.myMap.mapObject;
        this.baseLayer.addTo(map);
        this.control.addTo(map);
      })
    },
    data() {
      return {
        map: {},
        titleProvider: {
          name: 'ABR Peat Ponds',
          visible: true
        },
        // pondLocation: [64.910603, -147.940754],
        emancipation: [64.912736, -148.262492],
        // pondLocation: [48.858, 2.294],
        // location: [51.985, 5],
        baseLayer: L.tileLayer.offline('https://example_internal_server/emancipation_tiles/{z}/{x}/{y}.png', { tms: true, opacity: 1.0 }),
      }
    },
    computed: {
      control() {
        return L.control.savetiles(this.baseLayer, { 
          saveWhatYouSee: true,
          maxZoom: 18,
          // zoomlevels: [15, 16, 17, 18],
          confirm(layer, succescallback) {
            // eslint-disable-next-line no-alert
            if (window.confirm(`Save  ${layer._tilesforSave.length}?`)) {
              succescallback();
            }
          },
          confirmRemoval(layer, successCallback) {
            // eslint-disable-next-line no-alert
            if (window.confirm('Remove all the tiles?')) {
              successCallback();
            }
          },
          saveText: '<i class="fa fa-download" aria-hidden="true" title="Save tiles"></i>',
          rmText: '<i class="fa fa-trash" aria-hidden="true"  title="Remove tiles"></i>',
        })
      }
    },
    methods: {
      openObservationForm(event) {
       this.$bvModal.show('observation');
       // eslint-disable-next-line
       console.log(event.latlng);
       // this.$refs.myMap.mapObject.addMarker(event.latlng);
      },
    }
  }
</script>

<style scoped>
  @media (min-width: 768px) and (max-width: 1024px) {
    .mobile-map-size {
      width: 100% !important;
      height: 50% !important;
    }
  }
</style>

map not updated during saving

When we are saving tiles, the map does not update on a change of zoom, move.
The area being saved remains but the rest is grey.
The map updates when the saving is finished.

Non-200 tile URL response statuses cause _loadTile to interrupt

If a provided tile URL results with anything other than a 200 status code then the _loadTile method gets interrupted and stops processing the queue of tiles.

Right now the method only handles the case of a 200 response, and that's not a safe assumption to make. There's essentially no error handling and there's any number of ways in which the request could fail.

Our specific case has to do with Mapbox providing us some stale/invalid tile URLs and we do not have the resources right now to correct the problem at its source.

I am working on a fix for this in my own fork but I wanted to make note of it here as well.

Accessible controls

  • <a href="#"> controls should have role="button"
  • <a> controls themselves should have the title attributes, or at the very least remove aria-hidden="true" in (e.g.):

    saveText:
    '<i class="fa fa-download" aria-hidden="true" title="Save tiles"></i>',
    rmText:
    '<i class="fa fa-trash" aria-hidden="true" title="Remove tiles"></i>',

    (the titles are currently hidden from screen reader users, due to being placed on <i> which is aria-hidden="true")

Helpful resources:

Use in TypeScript Angular

I'm trying to use this library in ionic with Angular but I can't get it to work.
I install as follows

  • npm install leaflet --save
  • npm install @types/leaflet
  • npm install idb --save
  • npm install leaflet.offline --save

Inside my .ts file I import it
import { Map, latLng, tileLayer, Layer, marker, icon } from 'leaflet';
import { TileLayerOffline } from 'leaflet.offline';

@Component({
  selector: 'app-tab1',
  templateUrl: 'tab1.page.html',
  styleUrls: ['tab1.page.scss']
})
export class Tab1Page {
  mapL: L.Map;
  baseLayer: TileLayerOffline;
  constructor()
  { }
initLeaflet() {
     // In setView add latLng and zoom
    this.mapL = new Map('mapId');
    this.baseLayer = new TileLayerOffline('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: 'LOO ©',
    }).addTo(this.mapL);
}

saveWhatYouSee only current zoom level

Hi there, I'd like to know if there's a way to pass saveWhatYouSee option to save control, but instead of saving the current zoom level, plus deeper zoom leves, I'd like to save only the current zoom level, so if my view of the map is on a low zoom level, I won't start saving thounsands of tiles of the deeper levels, if I move my map zoom to a greather zoom level, let's say 9 -- > 10 I got save tiles from the view I got from level 9 zoom before zooming in, and tiles from level 10 zoom, but just my current bounds of level 10, I hope I made miself clear, and I hope you guys can help me out, thanks.

PD: Awesome plugin btw.

UPDATE: Hey I already accomplished what I was trying to do, I add another option to L.control.savetiles, naming it "saveCurrentZoom" then on _saveTiles function did this
zoomlevels.push(this._map.getZoom()); and add and zoomend event to my map, inside this event I call control._saveTiles() and that was it, pretty simple actually, thanks for this plugin and sorry for opening an issue for something that simple. Thank you.

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.