Giter Club home page Giter Club logo

code-editor's Introduction

@ngstack/code-editor

Code editor component for Angular applications.

Based on the Monaco editor that powers VS Code.

Buy Me A Coffee

Installing

npm install @ngstack/code-editor

Integrating with Angular CLI project

Import CodeEditorModule into your main application module:

import { CodeEditorModule } from '@ngstack/code-editor';

@NgModule({
  imports: [CodeEditorModule.forRoot()]
})
export class AppModule {}

If you want to use a specific version of the Monaco editor, use editorVersion parameter. If not provided, the component is always going to use the latest version.

For a full list of Monaco versions and changes, please refer to the official CHANGELOG.md file

@NgModule({
  imports: [
    CodeEditorModule.forRoot({
      editorVersion: '0.44.0'
    })
  ]
})
export class AppModule {}

Update template to use the ngs-code-editor:

<ngs-code-editor [theme]="theme" [codeModel]="model" [options]="options" (valueChanged)="onCodeChanged($event)"></ngs-code-editor>

Update component controller class and provide corresponding properties and events:

export class AppComponent {
  theme = 'vs-dark';

  model: CodeModel = {
    language: 'json',
    uri: 'main.json',
    value: '{}'
  };

  options = {
    contextmenu: true,
    minimap: {
      enabled: true
    }
  };

  onCodeChanged(value) {
    console.log('CODE', value);
  }
}

Input Properties

Name Type Default Value Description
theme string vs Editor theme. Supported values: vs, vs-dark or hc-black.
options Object {...} Editor options.
readOnly boolean false Toggles readonly state of the editor.
codeModel CodeModel Source code model.

The codeModel property holds the value that implements the CodeModel interface:

export interface CodeModel {
  language: string;
  value: string;
  uri: string;

  dependencies?: Array<string>;
  schemas?: Array<{
    uri: string;
    schema: Object;
  }>;
}

Editor Options

For available options see IEditorConstructionOptions docs.

The following options are used by default when Editor Component gets created:

{
  "lineNumbers": true,
  "contextmenu": false,
  "minimap": {
    "enabled": false
  }
}

Output Events

Name Argument Type Description
loaded Raised when editor finished loading all its components.
valueChanged string An event emitted when the text content of the model have changed.
modelContentChanged IModelContentChangedEvent An event emitted when the contents of the underlying editor model have changed
codeModelChanged CodeModelChangedEvent An event emitted when the code model value is changed.

Component API

Name Description
editor returns the instance of the underlying Monaco ICodeEditor
runAction(id, args) runs the editor actions, for example editor.action.formatDocument
formatDocument() shortcut function to format the document

Editor Service

The component comes with a separate CodeEditorService service that provides additional APIs for the underlying monaco editor:

Name Description
monaco get the global monaco instance
typingsLoaded An event emitted when code typings are loaded
loaded An event emitted when the monaco instance is loaded
setTheme(themeName) Switches to a theme

Typings

The editor is able to resolve typing libraries when set to the Typescript or Javascript language.

Use dependencies property to provide a list of libraries to resolve

<ngs-code-editor [codeModel]="model" ...> </ngs-code-editor>

And in the controller class:

export class MyEditorComponent {
  codeModel: CodeModel = {
    language: 'typescript',
    uri: 'main.ts',
    value: '',
    dependencies: ['@types/node', '@ngstack/translate', '@ngstack/code-editor']
  };
}

Run your application, it may take a few seconds to resolve dependencies. It is performed in the background (web worker), so you can type your code.

Try pasting the following snippet at runtime:

import { TranslateModule, TranslateService } from '@ngstack/translate';
import { CodeEditorModule } from '@ngstack/code-editor';
import * as fs from 'fs';

export class MyClass {
  constructor(translate: TranslateService) {}
}

You should have all the types resolved and auto-completion working.

JSON schemas

You can associate multiple schemas when working with JSON files.

<ngs-code-editor [codeModel]="model" ...> </ngs-code-editor>

Provide the required schemas like in the example below.

export class MyEditorComponent {
  codeModel: CodeModel = {
    language: 'json',
    uri: 'main.json',
    value: '{ "test": true }',
    schemas: [
      {
        uri: 'http://custom/schema.json',
        schema: {
          type: 'object',
          properties: {
            type: {
              enum: ['button', 'textbox']
            }
          }
        }
      }
    ]
  };
}

The schemas get automatically installed and associated with the corresponding file.

Accessing Code Editor Instance

You can access the Code Editor component instance API from other components when using with the @ViewChild:

  private _codeEditor: CodeEditorComponent;

  @ViewChild(CodeEditorComponent, { static: false })
  set codeEditor(value: CodeEditorComponent) {
    this._codeEditor = value;
  }

  get codeEditor(): CodeEditorComponent {
    return this._codeEditor;
  }

The code above allows you to use the code editor within the *ngIf, for example:

<ng-container *ngIf="selectedModel">
  <ngs-code-editor [codeModel]="selectedModel"></ngs-code-editor>
</ng-container>

Other components can now have access to the editor instance:

<button mat-icon-button title="Format code" (click)="codeEditor?.formatDocument()">
  <mat-icon>format_align_left</mat-icon>
</button>

Example: auto-formatting on load

<ngs-code-editor [codeModel]="selectedModel" [options]="options" (codeModelChanged)="onCodeModelChanged($event)"></ngs-code-editor>
import { CodeModelChangedEvent } from '@ngstack/code-editor';

onCodeModelChanged(event: CodeModelChangedEvent) {
  setTimeout(() => {
    event.sender.formatDocument();
  }, 100);
}

Offline Setup

Editor

You can run the editor in the offline mode with your Angular CLI application using the following steps:

Install the monaco-editor:

npm install monaco-editor

Update the angular.json file and append the following asset rule:

{
  "glob": "**/*",
  "input": "../node_modules/monaco-editor/min",
  "output": "./assets/monaco"
}

Update the main application module and setup the service to use the custom baseUrl when application starts:

import { CodeEditorModule } from '@ngstack/code-editor';

@NgModule({
  imports: [
    CodeEditorModule.forRoot({
      baseUrl: 'assets/monaco'
    })
  ]
})
export class AppModule {}

Typings Worker

Update the angular.json file and append the following asset rule:

{
  "glob": "**/*.js",
  "input": "../node_modules/@ngstack/code-editor/workers",
  "output": "./assets/workers"
}

Then update the CodeEditorService configuration at the application startup:

@NgModule({
  imports: [
    CodeEditorModule.forRoot({
      typingsWorkerUrl: 'assets/workers/typings-worker.js'
    })
  ]
})
export class AppModule {}

Lazy Loading

To enable Lazy Loading use CodeEditorModule.forRoot() in the main application, and CodeEditorModule.forChild() in all lazy-loaded feature modules.

For more details please refer to Lazy Loading Feature Modules

code-editor's People

Contributors

aklen avatar bkrajendra avatar dave-c-vt avatar denysvuika avatar dependabot-preview[bot] avatar dependabot[bot] avatar marcus-goectau avatar mergify[bot] avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar

code-editor's Issues

Code window is blank until window resizes

Hi,

I am experiencing an issue similar to this:
#510

Basically the code window appears blank until the page resizes I believe by running the window:resize event.

  @HostListener('window:resize')
  onResize() {
    if (this._editor) {
      this._editor.layout();
    }
  }

The Angular Material Sidenav (https://material.angular.io/components/sidenav/overview) is closed when the editor component is created. The sideNav opens at some time later.

I think the onResize() function basically needs to be called when the sideNav opens If I remember correctly the width will start as 0 when created within a SideNav (or in the Mat-Tab example the other poster had)

Is there something to do to make this compatible and/or call onResize().

EDIT: After further investigation the issue seems to be triggered by putting the code to call the editor inside an which wraps the entire application and cannot be removed.

<amplify-authenticator>
       <ngs-code-editor
        [theme]="theme"
        [codeModel]="codeModel"
        [options]="options"
        (valueChanged)="onCodeChanged($event)"
      >
      </ngs-code-editor>
</amplify-authenticator>

Thanks

Request: support multiple editors on a single page

It would be great to support multiple editors on a single page for working with different files simultaneously.

Currently:
Currently, when adding two instances of ngs-code-editor to the page, only one successfully loads a monaco-editor.

Ideal
I would love to be able to add multiple ngs-code-editor component instances to the page.

TypeError: window.require.config is not a function

I'm getting the following error when trying to use code-editor version 0.4.8:

core.js:3872 ERROR Error: Uncaught (in promise): TypeError: window.require.config is not a function
TypeError: window.require.config is not a function
    at onGotAmdLoader (ngstack-code-editor.js:110)
    at ngstack-code-editor.js:144
    at new ZoneAwarePromise (zone.js:915)
    at CodeEditorService.push../node_modules/@ngstack/code-editor/__ivy_ngcc__/fesm5/ngstack-code-editor.js.CodeEditorService.loadEditor (ngstack-code-editor.js:99)
    at CodeEditorComponent.<anonymous> (ngstack-code-editor.js:777)
    at step (tslib.es6.js:100)
    at Object.next (tslib.es6.js:81)
    at tslib.es6.js:74
    at new ZoneAwarePromise (zone.js:915)
    at __awaiter (tslib.es6.js:70)
    at resolvePromise (zone.js:836)
    at zone.js:750
    at rejected (tslib.es6.js:72)
    at ZoneDelegate.invoke (zone.js:396)
    at Object.onInvoke (core.js:27800)
    at ZoneDelegate.invoke (zone.js:395)
    at Zone.run (zone.js:153)
    at zone.js:894
    at ZoneDelegate.invokeTask (zone.js:431)
    at Object.onInvokeTask (core.js:27788)

My ng version output:

Angular CLI: 9.0.6
Node: 12.14.0
OS: linux x64

Angular: 9.0.6
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router
Ivy Workspace: Yes

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.900.3
@angular-devkit/build-angular     0.900.6
@angular-devkit/build-optimizer   0.900.6
@angular-devkit/build-webpack     0.900.6
@angular-devkit/core              9.0.3
@angular-devkit/schematics        9.0.6
@ngtools/webpack                  9.0.6
@schematics/angular               9.0.6
@schematics/update                0.900.6
rxjs                              6.5.4
typescript                        3.7.5
webpack                           4.41.2

Diff editor ?

Is there any way to make a diff editor with this package ?

update README.md

Since angular v6, angular-cli.json is depreciate and renamed to angular.json. Can you update it to avoid confusion.

Cannot read property 'monaco' of null

Console errors

image

Likely because https://github.com/ngstack/code-editor/blob/master/projects/code-editor/src/lib/services/code-editor.service.ts#L33

the loaded BehaviourSubject is initially set to null. In the Default services the BehaviourSubject is subscribed to, and event.monaco is accessed but event is initially null.

image

Modifying the source in node_modules, setting initial value to {} does not give these console errors. Also changing it to Subject instead of BehaviourSubject works as well.

Not working on Angular 9

ERROR in node_modules/@ngstack/code-editor/lib/code-editor.module.d.ts:5:22 - error NG6002: Appears in the NgModule.imports of AppModule, but could not be resolved to an NgModule class.

This likely means that the library (@ngstack/code-editor) which declares CodeEditorModule has not been processed correctly by ngcc, or is not compatible with Angular Ivy. Check if a newer version of the library is available, and update if so. Also consider checking with the library's authors to see if the library is expected to be compatible with Ivy.

5 export declare class CodeEditorModule {
                       ~~~~~~~~~~~~~~~~

configuration:

"devDependencies": {
"@angular-devkit/build-angular": "~0.901.1",
"@angular/cli": "~9.1.1",
"@angular/compiler-cli": "~9.1.1",
"@angular/language-service": "~9.1.1",
"@types/node": "^12.11.1",
"@types/jasmine": "~3.5.0",
"@types/jasminewd2": "~2.0.3",
"codelyzer": "^5.1.2",
"jasmine-core": "~3.5.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~4.4.1",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~2.1.0",
"karma-jasmine": "~3.0.1",
"karma-jasmine-html-reporter": "^1.4.2",
"protractor": "~5.4.3",
"ts-node": "~8.3.0",
"tslint": "~6.1.0",
"typescript": "~3.8.3"

Please let me know is it compatible with angular 9? If no, then which editor do you suggest?

Support for reactive forms

Support for reactive forms would be nice. Right now, code-editor cannot be used inside reactive forms by binding formControlName.

Code editor not refreshing when updating the width

I pu the code editor into an split panel, where the useris able to drag it to make the window bigger. Sadly, the window doesn't refresh automatically.

Is there a way to force it to rerender?

Image with the editor on load:
grafik

Image of the editor when it got dragged around (Stayed at the same size):
grafik

can't use offline

Uncaught SyntaxError: Unexpected token '<'
core.js:6228 ERROR TypeError: Cannot read property 'config' of undefined
at HTMLScriptElement.onGotAmdLoader (ngstack-code-editor.js:54)
at ZoneDelegate.invokeTask (zone-evergreen.js:399)
at Object.onInvokeTask (core.js:41632)
at ZoneDelegate.invokeTask (zone-evergreen.js:398)
at Zone.runTask (zone-evergreen.js:167)
at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:480)
at invokeTask (zone-evergreen.js:1621)
at HTMLScriptElement.globalZoneAwareCallback (zone-evergreen.js:1647)

Multiple Editor issue

.core.mjs:7473 ERROR Error: ModelService: Cannot add model because it already exists!
I am using
Angular 17.2.1
"@ngstack/code-editor": "^7.2.0",
"monaco-editor": "^0.46.0",

Applied like
<ngs-code-editor
[theme]="theme"
[codeModel]="model"
[options]="options"
(valueChanged)="onCodeChanged($event)">

<ngs-code-editor
[theme]="theme"
[codeModel]="model1"
[options]="options"
(valueChanged)="onCodeChanged($event)">

Upgrade to Angular 13 and Ivy

After upgrading my project, to Angular 13, ng build suggests, I should encourage you to support an Ivy distribution 😃

Processing legacy "View Engine" libraries:
- @ngstack/code-editor [es2015/esm2015] (https://github.com/ngstack/code-editor.git)
Encourage the library authors to publish an Ivy distribution.

Lazy load of editor in module

When I add CodeEditorModule.forRoot() in my app.module.ts and CodeEditorModule.forChild() in my lazyload.module.ts, the editor is loaded after startup even if the lazy load module is not.

Editor files from content delivery network should loaded only if lazy loaded modul loaded

ReferenceError: monaco is not defined

angular 14, when i run the application get error

main.js:326591 ERROR Error: Uncaught (in promise): ReferenceError: monaco is not defined
ReferenceError: monaco is not defined
at CodeEditorComponent.setupEditor (907.js:3127:19)
at CodeEditorComponent. (907.js:3116:12)
at Generator.next ()
at main.js:259177:71
at new ZoneAwarePromise (polyfills.js:6619:23)
at __awaiter (main.js:259173:12)
at CodeEditorComponent.ngAfterViewInit (907.js:3115:60)
at callHook (main.js:321621:14)
at callHooks (main.js:321594:9)
at executeInitAndCheckHooks (main.js:321551:5)
at resolvePromise (polyfills.js:6538:21)
at new ZoneAwarePromise (polyfills.js:6621:11)
at __awaiter (main.js:259173:12)
at CodeEditorComponent.ngAfterViewInit (907.js:3115:60)
at callHook (main.js:321621:14)
at callHooks (main.js:321594:9)
at executeInitAndCheckHooks (main.js:321551:5)
at refreshView (main.js:330899:11)
at refreshComponent (main.js:331937:7)
at refreshChildComponents (main.js:330627:5)

Ivy Renderer issues on re-compile

I know the simple fix is to disable the new Ivy Renderer, but since Angular is moving forward with Ivy soon...

After a fresh ng serve, the code editor displays, but after one re-compile the code editor breaks.

ERROR Error: Template error: Can't bind to 'theme' since it isn't a known property of 'ngs-code-editor'.

Cannot read properties of undefined (reading 'languages') after v3.0.0

image

After upgrading from v3.0.0 to v3.1.0, subscriptions made to loaded of CodeEditorService seem no longer fire, leading to monaco not being set and staying undefined on the language defaults services. I believe the issue is caused by the change made as a result of #590. After changing loaded back to a BehaviorSubject, the package functions with no errors as it used to. BehaviorSubject is more appropriate here because the language defaults services appear to be subscribing to loaded after it emits a value for the first time.

'ngs-code-editor' is not a known element

using in a lazy loaded module work fine but there is this error
'ngs-code-editor' is not a known element:

  1. If 'ngs-code-editor' is an Angular component, then verify that it is part of this module.
  2. If 'ngs-code-editor' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.ng

Formatting code to json

Hello, thank you for your precedent answer on my issue.
However, your answer didn't help me because when I see your JSON format example, I notice that:

value: [
'{',
' "$schema": "http://custom/schema.json",',
' "type": "button"',
'}'
].join('\n'),

but if we remove the initial spaces before $schema and type like this:

value: [
'{',
' "$schema": "http://custom/schema.json",',
' "type": "button"',
'}'
].join('\n'),

the text's format is still good because we can type JSON. However, the code doesn't have a proper format. I want consistent indentation, similar to Prettier in our IDE.

Can you help me with this problem, please?

Code editor won't render until page resize

Angular version: 9
code-editor version: 2.1.1

In my application, I'm using a <mat-tab> that contains a custom component which itself contains the <ngs-code-editor>. For a reason I can't pinpoint, the code editor won't render until the page is resized by the user. To be exact, only a dark rectangle shows. This is the code for my custom component:

<ngs-code-editor
  [theme]="theme"
  [codeModel]="codeModel"
  [options]="options"
  (valueChanged)="onCodeChanged($event)">
</ngs-code-editor>
export class MyEditorComponent implements OnInit {
  @Input('form') mainForm: FormGroup;

  theme = 'vs-dark';
  options = {
    contextmenu: true,
    lineNumbers: true,
    minimap: {
      enabled: true,
    },
  };
  codeModel: CodeModel = {
    language: 'json',
    uri: 'main.json',
    value: '{}',
  };

  ngOnInit(): void {
    this.codeModel.value = this.mainForm.get('data').value;
  }

  onCodeChanged(evt: string): void {
    this.mainForm.get('data').setValue(evt);
  }
}

As a workaround, I've added an *ngIf="showEditor" on the editor, which I set to true in a setTimeout(..., 0) call from the ngOnInit. This somehow works. This could very well be a me problem more than a problem with this component, I'm fairly new to angular.

Dynamically update the code

Is there a way to dynamically update the code once the editor is loaded?

For instance, I want to be able to load code from a file after the editor is loaded.
Just changing the codeModel.value property doesn't seem to change on the editor.

Thanks!

Cannot find module 'monaco-editor'

I am upgrading this in my project from v5.1.0 (ng16) to v7.2.0 (ng17) and then I got this error when running my test.

Error: node_modules/@ngstack/code-editor/lib/code-editor/code-editor.component.d.ts:7:24 - error TS2307: Cannot find module 'monaco-editor' or its corresponding type declarations.

7 import { editor } from 'monaco-editor';
                         ~~~~~~~~~~~~~~~


Error: node_modules/@ngstack/code-editor/lib/services/code-editor.service.d.ts:4:24 - error TS2307: Cannot find module 'monaco-editor' or its corresponding type declarations.

4 import { editor } from 'monaco-editor';

I am not installing monaco-editor on my package.json since I don't need offline mode in my project.

Will install v7.1.0 for now since it seems the imports are added on v7.2.0, but I hope this can be resolved in a future version.

Updating value later on

The current system is fine if we know what the initial value is.
However when we get data from an api and wish to update the model's value this doesn't work.

I tried this.codeModel.value = "alert('This is the new code from the api');";

But this doesn't work, the editor still shows the original value. Please could this feature be added?

Support Standalone Components - Angular 17

New Angular CLI projects and generated Components default to standalone=true now.

NgModules are no longer encouraged so it would be great for ngstack/code-editor to become standalone too. Or at least update your docs on how to get this library/component to work with a blank CLI created app with v17+.

Thanks for the great library wrapper!

Unable to Use JSON Schema

I was hoping to see what type of JSON schema support is included. However whenever I add a schemas list as shown in the documentation I receive a runtime error of:

core.mjs:6494 ERROR Error: Uncaught (in promise): TypeError: Cannot read properties of undefined (reading 'languages')
TypeError: Cannot read properties of undefined (reading 'languages')
    at JsonDefaultsService.addSchemas (ngstack-code-editor.mjs:311:38)
    at CodeEditorComponent.setupDependencies (ngstack-code-editor.mjs:465:43)
    at CodeEditorComponent.setupEditor (ngstack-code-editor.mjs:443:14)
    at CodeEditorComponent.<anonymous> (ngstack-code-editor.mjs:422:18)
    at Generator.next (<anonymous>)
    at tslib.es6.js:76:1
    at new ZoneAwarePromise (zone.js:1429:1)
    at __awaiter (tslib.es6.js:72:1)
    at CodeEditorComponent.ngAfterViewInit (ngstack-code-editor.mjs:421:25)
    at callHook (core.mjs:2551:1)
    at resolvePromise (zone.js:1211:1)
    at new ZoneAwarePromise (zone.js:1432:1)
    at __awaiter (tslib.es6.js:72:1)
    at CodeEditorComponent.ngAfterViewInit (ngstack-code-editor.mjs:421:25)
    at callHook (core.mjs:2551:1)
    at callHooks (core.mjs:2520:1)
    at executeInitAndCheckHooks (core.mjs:2471:1)
    at refreshView (core.mjs:9566:1)
    at refreshComponent (core.mjs:10692:1)
    at refreshChildComponents (core.mjs:9291:1)

Going a level deeper, it looks like this.monaco is undefined:

addSchemas(id, definitions = []) {
        const defaults = this.monaco.languages.json.jsonDefaults;
        ....

Anyone have advice?

Fix README

In README, replace

[codeModel]="model"

on

[codeModel]="codeModel"

Wrong version of monaco-editor is being downloaded from CDN

The library download the monaco-editor from the CDN but does not specify the version, therefor the library is downloading the latest. They released a new version of monaco-editor today and this library is downloading the new version which doesn't appear to be compatible with this library.

Our app have crashed in production because of this issue. I do not see any documentation that shows how to specify the version of monaco-editor we want to use.

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.