Giter Site home page Giter Site logo

lastaapps / menza Goto Github PK

View Code? Open in Web Editor NEW
40.0 3.0 3.0 11.42 MB

This Android app shows dish menus for CTU cafeterias from agata.suz.cvut.cz web in much more pleasant and usable way for phones. It shows today and week menu, opening hours, contacts, announcements and address for all the canteens. It supports dark mode and Material You including Android 12 dynamic theming.

License: GNU General Public License v3.0

Kotlin 86.44% HTML 13.51% Ruby 0.05%
ctu ctu-fit android-app kotlin-android jetpack kotlin android material-ui

menza's Introduction

CTU Menza

GitHub release (latest by date)F-Droid

This Android app shows dish menus for CTU cafeterias from the agata.suz.cvut.cz and studentcatering.cz websites in a much more pleasant and usable way for phones. It shows today's and this week's menu, opening hours, contacts, announcements and addresses for all canteens.

Core parts are written in Kotlin Multiplatform, support for JVM target can be added right away. Other targets require more work (non-JVM web scraping library required), but it still may be manageable for somebody to port this codebase to native or js platforms.

See contributing below.

What does 'Menza' mean?

Menza is the Czech word for school cafeteria.

Now on Google PlayGet it on F-Droid

Related projects

Libraries

  • AndroidX (Compose, ...)
  • ArrowKt
  • Decompose
  • SQLDelight
  • Koin
  • Coil-kt
  • Ktor
  • And more

The core of the all in written in Kotlin Multiplatform!

Features

  • Today's menu + dish details
  • This week's menu
  • Menza opening hours, contacts, announcements and addresses

User experience

  • Dark theme
  • Many themes along with support for Android 12 Material You dynamic theming
  • Images download switch on metered networks (~0.7 MB per image)
  • Image caching
  • No private data collection
  • Proper landscape mode and large screen device support

Screenshots

today dish menutoday dish menu darkdish detaildish detail dark

week dish menu darkweek dish menuinfo page darkinfo page

Contributing and project structure

Feel free to contribute, but contact me before please, so we don't do the same thing twice. If you are new to Kotlin/Android, you can write the code yourself, and I'll adjust it to the rules below. So it's fine to write it wrong (different), but don't be surprised when I rewrite it.

Most of the modules are multiplatform, and you should respect it. That means write as much code as possible into the common code and if there is no (nice) way to implement feature in a multiplatform manner, this is the time when you can use platform specific package. Even in that case put at least an interface into the common code and tie it using DI (preferred over expected/actual keywords).

The whole app tries to respect clean architecture principles and MVVM architecture. There is also domain layer presented (use cases). The whole app is tied together using DI.

Structure
  • api/core - core classes for network communication, store, synchronization, ...
  • api/agata, api/buffet - implementation for individual canteen provider
  • api/main - packs all the providers into one interface, contains related business logic
  • app - only UI related code, purely Android (for now)
    • features - stores all the UI code
      • root - decides if the user is already logged in
      • starting - stores setup related code
      • main - holds main user interface (after login), drawer, top/bottom bar, core navigation
      • today - the main screen, shows today canteen offering
      • week - shows week canteen offering
      • info - shows canteen info
      • panels - panels for the today screen (rate us, report a crash, what's new, ...)
      • settings - self-explanatory, includes about screen
      • others - privacy policy, library notices, ošťurák, ...
  • core - holds main shared domain logic and templates
    • Outcome - like Rust's Result, success or DomainError. all the functions that can fail should return Outcome.
    • UseCase - base usecase class
    • BaseViewmodel - parent of all the ViewModels
  • lastaapps - my legacy common shared code (+ crash reporting)
Other modules are deprecated and should not be used/edited

Namely, modules entity, html-parser, scraping and storage. They were used by the first version of menza and are kept for future in case I lost access to the API.

Data sources

Most of the data is obtained from the official Agata API, see the documentation here. To get your API key, please contact the IT center and don't steal mine, they will be more than happy to give you one.

To get FS and FEL buffet data I do scrape their webpages/hardcode info.

License

Menza is licensed under the GNU GPL v3.0 license.

menza's People

Contributors

lastaapps avatar marekkon5 avatar radian-fi 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

Watchers

 avatar  avatar  avatar

menza's Issues

Nelze načíst dnešní jídelníček studentské menzy

Android version: 31
App version name: 1.2.2
App version code: 1020200
Phone model: moto g(60)
Phone manufacturer: motorola
Date and Time: 2022-11-04T10:26:32.387+01:00[Europe/Prague]
Screen size: 1080 x 2285 px

"Internal app problem"
2022-11-04T10:26:32.388
empty String
java.lang.NumberFormatException: empty String
at jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
at jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:543)
at g8.o1.a(SourceFile:39)
at g8.j1.V(SourceFile:229)
at c0.c.q(SourceFile:31)
at c0.c.X(SourceFile:10)
at g8.m1$a.V(SourceFile:87)
at z.w0.S(SourceFile:233)
at g8.m1.e(Unknown Source:7)
at i8.n1$b.j(SourceFile:192)
at da.a.u(SourceFile:9)
at xa.n0.run(SourceFile:107)
at cb.f.run(SourceFile:13)
at db.j.run(SourceFile:3)
at db.a$a.run(SourceFile:82)

Could not find element "span"

Android version: 33
App version name: 1.2.4
App version code: 1020400
Phone model: Pixel 4a (5G)
Phone manufacturer: Google
Date and Time: 2023-03-29T11:29:45.656+02:00[Europe/Prague]
Screen size: 1080 x 2141 px

"Internal app problem"
2023-03-29T11:29:45.658
Could not find element "span"
s9.i: Could not find element "span"
at s9.h.k(SourceFile:194)
at c0.b.s(SourceFile:6)
at n8.a1.e0(SourceFile:262)
at c0.b.s(SourceFile:31)
at c0.b.V(SourceFile:10)
at n8.d1$a.e0(SourceFile:89)
at a1.c.t0(SourceFile:229)
at n8.d1.e(Unknown Source:7)
at p8.l1$b.m(SourceFile:192)
at z9.a.p(SourceFile:9)
at sa.m0.run(SourceFile:107)
at xa.f.run(SourceFile:13)
at ya.j.run(SourceFile:3)
at ya.a$a.run(SourceFile:82)

No Data Available in Technická menza

Android version: 29
App version name: 1.1.0
App version code: 1010000
Phone model: Nokia 5.1
Phone manufacturer: HMD Global
Date and Time: 2022-04-12T11:05:28.69+02:00[Europe/Prague]
Screen size: 1080 x 2034 px

java.lang.IllegalArgumentException: Dish name is blank
at u6.a.(SourceFile:14)
at t7.e1.V(SourceFile:30)
at a3.m.h(SourceFile:4)
at a3.m.l(SourceFile:2)
at t7.i1$a.V(SourceFile:8)
at h0.n.h(SourceFile:64)
at t7.i1.e(SourceFile:1)
at v7.h0$b.k(SourceFile:31)
at aa.a.x(SourceFile:4)
at ra.p0.run(SourceFile:18)
at wa.f.run(SourceFile:2)
at xa.l.run(SourceFile:1)
at xa.a.R(SourceFile:1)
at xa.a$a.run(SourceFile:10)

Can't refresh without touch input

Zdravím, já jenom okomentuju moji recenzi na GP.
Když mám aplikaci na telefonu, tak input je samozřejmě jako dotyk a pull gesto funguje jak má. To samé se děje, když se k telefonu připojím z počítače pomocí scrcpy, protože to simuluje dotyk. Problém, který já komentuju, pak nastává určitě pod waydroidem na počítači, protože to používá nativní myš a myš logicky nepodporuje pull gesto. To samé chování očekávám i při připojení myši k telefonu, ale přímo jsem to nezkoušel.
Jakože upřímně je to takový edgecase, že se s tím asi nemá cenu zabývat. To proč jsem to zkoušel, tak to proto, že jsem na tu aplikaci zvyklý z telefonu a když se mi nechtělo vytahovat telefon, tak toto byla rychlejší volba.
Ostatní aplikace to upřímně moc neřeší, nebo spíš jsem na to moc nenarazil. Třeba takový aplikace ViMusic se chová strašně divně při hoveru (je to hodně zbastlené).
Je to prostě primárně mobilní aplikace a na desktopu se prostě může chovat trochu divně no. Možná by šlo nějak získat, že je připojená myš a vyrenderovat tam refresh tlačítko, ale to asi nemá smysl.

Menza Strahov not working

Zde prosím popište váš problém více

Chtěl jsem se kouknout na menzu Strahov a this. Ostatní menzy fungují v pohodě a na webu taky je jídelníček v pořádku

Android version: 30
App version name: 1.2.0
App version code: 1020000
Phone model: RMX2155
Phone manufacturer: realme
Date and Time: 2022-09-29T14:13:13.61+02:00[Europe/Prague]
Screen size: 1080 x 2153 px

"Internal app problem"
2022-09-29T14:13:13.612
For input string: "3.9.10"
java.lang.NumberFormatException: For input string: "3.9.10"
at java.lang.Integer.parseInt(Integer.java:615)
at java.lang.Integer.parseInt(Integer.java:650)
at h8.v0.T(SourceFile:12)
at androidx.activity.result.d.q(Unknown Source:9)
at h8.q0.A(SourceFile:2)
at h8.x0.T(SourceFile:13)
at h8.q0.h(SourceFile:4)
at h8.q0.z(SourceFile:2)
at h8.b1$a.T(SourceFile:9)
at androidx.window.layout.e.p(SourceFile:64)
at h8.b1.d(Unknown Source:7)
at j8.h0$b.i(SourceFile:31)
at ma.a.K(SourceFile:3)
at db.l0.run(SourceFile:18)
at ib.h.run(SourceFile:2)
at jb.j.run(SourceFile:1)
at jb.a$a.run(SourceFile:14)

Low balance popup always shows

Prý mi pořád dochází penízky i když mám přes 500 Kč. (Podle kódu se mi zdá, že by to mělo mít threshold na 256)

empty String error report

Aplikace hází empty String error při pokusu o zobrazení jídel ze Studentského Domu.

Android version: 31
App version name: 1.2.2
App version code: 1020200
Date and Time: 2022-11-11T12:04:14.16+01:00[Europe/Prague]
Screen size: 1080 x 2069 px

"Internal app problem"
2022-11-11T12:04:14.162
empty String
java.lang.NumberFormatException: empty String
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at g8.o1.a(SourceFile:39)
at g8.j1.V(SourceFile:229)
at c0.c.q(SourceFile:31)
at c0.c.X(SourceFile:10)
at g8.m1$a.V(SourceFile:87)
at z.w0.S(SourceFile:233)
at g8.m1.e(Unknown Source:7)
at i8.n1$b.j(SourceFile:192)
at da.a.u(SourceFile:9)
at xa.n0.run(SourceFile:107)
at cb.f.run(SourceFile:13)
at db.j.run(SourceFile:3)
at db.a$a.run(SourceFile:82)

The application crashes after an interaction with the Menza at startup option

Appka spadne po kliknutí na "Menza po spouštění" (defaultně nastavené na "Vždy se zeptat") v "Nastavení."

Android version: 34
App version name: 1.3.0
App version code: 1030000
Phone model: Pixel 6
Phone manufacturer: Google
Date and Time: 2024-01-23T18:35:28.718+01:00[Europe/Prague]
Screen size: 1080 x 2209 px

App crashed
2024-01-23T17:34:28.504Z[UTC]
Vertically scrollable component was measured with an infinity maximum height constraints, which is disallowed. One of the common reasons is nesting layouts like LazyColumn and Column(Modifier.verticalScroll()). If you want to add a header before the list of items please add a header as a separate item() before the main items() inside the LazyColumn scope. There are could be other reasons for this to happen: your ComposeView was added into a LinearLayout with some weight, you applied Modifier.wrapContentSize(unbounded = true) or wrote a custom layout. Please try to remove the source of infinite constraints in the hierarchy above the scrolling container.
java.lang.IllegalStateException: Vertically scrollable component was measured with an infinity maximum height constraints, which is disallowed. One of the common reasons is nesting layouts like LazyColumn and Column(Modifier.verticalScroll()). If you want to add a header before the list of items please add a header as a separate item() before the main items() inside the LazyColumn scope. There are could be other reasons for this to happen: your ComposeView was added into a LinearLayout with some weight, you applied Modifier.wrapContentSize(unbounded = true) or wrote a custom layout. Please try to remove the source of infinite constraints in the hierarchy above the scrolling container.
at androidx.compose.foundation.a.d(SourceFile:23)
at x.v.m(SourceFile:47)
at t.p0.h(SourceFile:24)
at t.p0.m(SourceFile:639)
at v1.d0.c(SourceFile:74)
at x1.x.a(SourceFile:38)
at s.l.a(SourceFile:9)
at s.l.k(SourceFile:14)
at v1.x.g(SourceFile:8)
at x1.d0.a(SourceFile:11)
at s.l.a(SourceFile:39)
at s.l.k(SourceFile:27)
at v1.x.g(SourceFile:8)
at x1.d0.a(SourceFile:11)
at i1.q0.g(SourceFile:1)
at x1.d0.a(SourceFile:11)
at w.g0.g(SourceFile:99)
at x1.d0.a(SourceFile:11)
at r.l0.b(SourceFile:34)
at r.l0.c(SourceFile:14)
at a1.c.F(SourceFile:60)
at a1.a0.a(SourceFile:52)
at a1.b0.c(SourceFile:153)
at x1.s1.a(SourceFile:3)
at x1.m0.r0(SourceFile:109)
at x1.m0.a(SourceFile:96)
at w.g1.b(SourceFile:118)
at w.f1.c(SourceFile:32)
at x1.x.a(SourceFile:38)
at r.l0.b(SourceFile:34)
at r.l0.c(SourceFile:14)
at a1.c.F(SourceFile:60)
at a1.a0.a(SourceFile:52)
at a1.b0.c(SourceFile:153)
at x1.s1.a(SourceFile:3)
at x1.m0.r0(SourceFile:109)
at x1.m0.a(SourceFile:96)
at w.v.c(SourceFile:112)
at x1.x.a(SourceFile:38)
at s.b3.g(SourceFile:50)
at x1.d0.a(SourceFile:11)
at s.l.a(SourceFile:9)
at s.l.k(SourceFile:14)
at v1.x.g(SourceFile:8)
at x1.d0.a(SourceFile:11)
at s.l.a(SourceFile:39)
at s.l.k(SourceFile:27)
at v1.x.g(SourceFile:8)
at x1.d0.a(SourceFile:11)
at i1.q0.g(SourceFile:1)
at x1.d0.a(SourceFile:11)
at w.a1.g(SourceFile:33)
at x1.d0.a(SourceFile:11)
at r.l0.b(SourceFile:34)
at r.l0.c(SourceFile:14)
at a1.c.F(SourceFile:60)
at a1.a0.a(SourceFile:52)
at a1.b0.c(SourceFile:153)
at x1.s1.a(SourceFile:3)
at x1.m0.r0(SourceFile:109)
at x1.m0.a(SourceFile:96)
at w.v.c(SourceFile:112)
at x1.x.a(SourceFile:38)
at i1.q0.g(SourceFile:1)
at x1.d0.a(SourceFile:11)
at i1.q0.g(SourceFile:1)
at x1.d0.a(SourceFile:11)
at r.l0.b(SourceFile:34)
at r.l0.c(SourceFile:14)
at a1.c.F(SourceFile:60)
at a1.a0.a(SourceFile:52)
at a1.b0.c(SourceFile:153)
at x1.s1.a(SourceFile:3)
at x1.m0.r0(SourceFile:109)
at x1.m0.a(SourceFile:96)
at w.v.c(SourceFile:112)
at x1.x.a(SourceFile:38)
at w.g0.g(SourceFile:99)
at x1.d0.a(SourceFile:11)
at r.l0.b(SourceFile:34)
at r.l0.c(SourceFile:14)
at a1.c.F(SourceFile:60)
at a1.a0.a(SourceFile:52)
at a1.b0.c(SourceFile:153)
at x1.s1.a(SourceFile:3)
at x1.m0.r0(SourceFile:109)
at x1.m0.a(SourceFile:96)
at s2.e.c(SourceFile:150)
at x1.x.a(SourceFile:38)
at r.l0.b(SourceFile:34)
at r.l0.c(SourceFile:14)
at a1.c.F(SourceFile:60)
at a1.a0.a(SourceFile:52)
at a1.b0.c(SourceFile:153)
at x1.s1.a(SourceFile:3)
at x1.m0.r0(SourceFile:109)
at x1.m0.a(SourceFile:96)
at v1.d1.c(SourceFile:39)
at x1.x.a(SourceFile:38)
at r.l0.b(SourceFile:34)
at r.l0.c(SourceFile:14)
at a1.c.F(SourceFile:60)
at a1.a0.a(SourceFile:52)
at a1.b0.c(SourceFile:153)
at x1.s1.a(SourceFile:3)
at x1.m0.r0(SourceFile:109)
at x1.u0.c(SourceFile:18)
at x1.u0.m(SourceFile:18)
at x1.u0.j(SourceFile:59)
at y1.w.onMeasure(SourceFile:83)
at android.view.View.measure(View.java:27133)
at y1.a.e(SourceFile:64)
at s2.n.e(SourceFile:5)
at y1.a.onMeasure(SourceFile:4)
at android.view.View.measure(View.java:27133)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7011)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:27133)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7011)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:27133)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7011)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:750)
at android.view.View.measure(View.java:27133)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:4379)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:2913)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3270)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2650)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9526)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1343)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1352)
at android.view.Choreographer.doCallbacks(Choreographer.java:952)
at android.view.Choreographer.doFrame(Choreographer.java:882)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1326)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8248)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)

Meal list margin

The meal list has an extra margin.
I think that the list should be padded from the inside in a way that the first and last items have the same padding on top and bottom respectively.

image

Application closes (do not crash, no error reported) after chosing particular "menza" currently

Aplikace mi aktuálně padá při vybraní "Výdejna Karlovo náměstí". Při nastavení "Menza po spuštění:
Pamatovat si poslední" aplikace padá hned po spuštění (při vybraní "Výdejna Karlovo náměstí").

Android version: 34
App version name: 1.3.5
App version code: 1030500
Phone model: Pixel 6
Phone manufacturer: Google
Date and Time: 2024-02-19T09:16:11.302+01:00[Europe/Prague]
Screen size: 1080 x 2209 px

"Internal app problem"
2024-02-19T09:16:11.303
Unknown error message

Allergen id is out of bound

Today's menu for Menza Strahov doesn't load.

Extra information below:

Android version: 32
App version name: 1.1.0
App version code: 1010000
Phone model: Mi 9T Pro
Phone manufacturer: Xiaomi
Date and Time: 2022-06-01T12:01:44.62+02:00[Europe/Prague]
Screen size: 1080 x 2300 px

java.lang.IllegalArgumentException: Allergen id is out of bound: 79
at s6.b.a(SourceFile:1)
at t7.c1.V(SourceFile:12)
at androidx.activity.result.d.q(SourceFile:1)
at a3.m.m(SourceFile:2)
at t7.e1.V(SourceFile:13)
at a3.m.h(SourceFile:4)
at a3.m.l(SourceFile:2)
at t7.i1$a.V(SourceFile:8)
at h0.n.h(SourceFile:64)
at t7.i1.e(SourceFile:1)
at v7.h0$b.k(SourceFile:31)
at aa.a.x(SourceFile:4)
at ra.p0.run(SourceFile:18)
at wa.f.run(SourceFile:2)
at xa.l.run(SourceFile:1)
at xa.a.R(SourceFile:1)
at xa.a$a.run(SourceFile:10)

Edit: Looking at it further, one of the foods has the following as allergens: "6,79,13". This is probably a mistake on SUZ's side, since it should say "6,7,9,13". However, I think it would still be best if you ignored all unknown allergen IDs, just like on the Agata website (the extended allergen list only includes 6 and 13 for this food).

Week button throws error when no menu is available

Clicking the week button currently causes this error. Probably because no data is available at this time.

Android version: 34
App version name: 1.2.7
App version code: 1020700
Phone model: Pixel 7 Pro
Phone manufacturer: Google
Date and Time: 2024-01-13T11:09:40.014+01:00[Europe/Prague]
Screen size: 1080 x 2169 px

"Internal app problem"
2024-01-13T11:09:40.015
Could not find element "#jidelnicek tbody tr"
s9.i: Could not find element "#jidelnicek tbody tr"
at s9.h.k(SourceFile:194)
at n8.f1$a.e0(SourceFile:82)
at a1.c.Z(SourceFile:229)
at n8.f1.e(Unknown Source:7)
at p8.n1$b.m(SourceFile:200)
at z9.a.p(SourceFile:9)
at sa.m0.run(SourceFile:107)
at xa.f.run(SourceFile:13)
at ya.j.run(SourceFile:3)
at ya.a$a.run(SourceFile:82)

Error updating the account balance

Chyba někdy (jen někdy) nastává při aktualizaci balance (peněz) na účtu (jak automatické, tak manuální).

Android version: 34
App version name: 1.3.7
App version code: 1030700
Phone model: Pixel 6
Phone manufacturer: Google
Date and Time: 2024-02-29T11:11:25.926+01:00[Europe/Prague]
Screen size: 1080 x 2209 px

"Internal app problem"
2024-02-29T11:11:25.929
Could not find element "h4 span.badge"
it.skrape.selects.ElementNotFoundException: Could not find element "h4 span.badge"
at tf.g.q(SourceFile:190)
at ea.a.E(SourceFile:3)
at ua.d.z(SourceFile:1521)
at cg.a.k(SourceFile:9)
at fj.n0.run(SourceFile:113)
at lj.a.run(SourceFile:96)

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.