8 |
9 | Blazor Graph API Example: Welcome to an example of using the Microsoft Graph API from Blazor.
10 | View the source on Github to see how it works.
11 |
12 |
13 |
14 |
15 |
28 |
29 |
30 |
31 |
32 |
33 | @code {
34 |
35 | protected override void OnInitialized()
36 | {
37 | state.LoginStatusChanged += async () =>
38 | {
39 | await LoadUserAsync();
40 |
41 | StateHasChanged();
42 | };
43 | }
44 |
45 | protected async Task LoadUserAsync()
46 | {
47 | if (state.LoginStatus == LoginStatus.LoggedIn)
48 | {
49 | var user = await graphService.GetMeAsync(state.AccountId);
50 | state.SetUser(user);
51 | }
52 | else
53 | state.SetUser(null);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/BlazorGraphExample/Pages/_Imports.razor:
--------------------------------------------------------------------------------
1 | @layout MainLayout
2 |
--------------------------------------------------------------------------------
/BlazorGraphExample/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Blazor.Hosting;
2 |
3 | namespace BlazorGraphExample
4 | {
5 | public class Program
6 | {
7 | public static void Main(string[] args) =>
8 | CreateHostBuilder(args).Build().Run();
9 |
10 | public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) =>
11 | BlazorWebAssemblyHost.CreateDefaultBuilder()
12 | .UseBlazorStartup();
13 |
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/BlazorGraphExample/Properties/PublishProfiles/FolderProfile.pubxml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 | FileSystem
9 | FileSystem
10 | Release
11 | Any CPU
12 |
13 | True
14 | False
15 | d5aec440-6134-4869-a3fc-023474b2ba54
16 | bin\Release\netstandard2.0\publish\
17 | True
18 | netstandard2.0
19 |
20 |
--------------------------------------------------------------------------------
/BlazorGraphExample/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "https://localhost:44395/",
7 | "sslPort": 44395
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "BlazorGraphExample": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "environmentVariables": {
22 | "ASPNETCORE_ENVIRONMENT": "Development"
23 | },
24 | "applicationUrl": "http://localhost:51495/"
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/BlazorGraphExample/Services/AppState.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using W8lessLabs.GraphAPI;
4 |
5 | namespace BlazorGraphExample.Services
6 | {
7 | public class AppState : IPagingState
8 | {
9 | private Dictionary _pageTokens;
10 | private Stack _folders;
11 |
12 | public AppState()
13 | {
14 | _pageTokens = new Dictionary();
15 | _folders = new Stack();
16 | SelectedFolderChanged += _ResetPaging;
17 | }
18 |
19 | public LoginStatus LoginStatus { get; private set; } = LoginStatus.Undetermined;
20 | public string AccountId { get; set; }
21 | public GraphUser User { get; private set; }
22 | public IReadOnlyList DriveItems { get; private set; }
23 | public DriveItem SelectedFile { get; private set; }
24 | public DriveItem SelectedFolder { get; private set; }
25 | public int PageSize { get; private set; } = 15;
26 | public int PageCount { get; private set; } = 1;
27 | public int CurrentPage { get; private set; } = 1;
28 | public string Path { get; private set; }
29 | public bool InProgress { get; private set; }
30 |
31 | public event Action LoginStatusChanged;
32 | public event Action AccountIdChanged;
33 | public event Action UserChanged;
34 | public event Action DriveItemsChanged;
35 | public event Action SelectedFileChanged;
36 | public event Action SelectedFolderChanged;
37 | public event Action PageSizeChanged;
38 | public event Action PageCountChanged;
39 | public event Action<(int oldPage, int newPage)> CurrentPageChanged;
40 | //public event Action PathChanged;
41 | public event Action InProgressChanged;
42 |
43 | public event Action LoadProgressChanged;
44 |
45 | public void SetLoginStatus(LoginStatus loginStatus) =>
46 | _Set(LoginStatus, loginStatus, LoginStatusChanged, val => LoginStatus = val);
47 |
48 | public void SetAccountId(string accountId) =>
49 | _Set(AccountId, accountId, AccountIdChanged, val => AccountId = val);
50 |
51 | public void SetUser(GraphUser user) =>
52 | _Set(User, user, UserChanged, val => User = val);
53 |
54 | public void SetDriveItems(IReadOnlyList driveItems) =>
55 | _Set>(DriveItems, driveItems, DriveItemsChanged, val => DriveItems = val);
56 |
57 | public void SetSelectedDriveItem(DriveItem driveItem) =>
58 | _Set(SelectedFile, driveItem, SelectedFileChanged, val => SelectedFile = val);
59 |
60 | public void SetPageSize(int newPageSize) =>
61 | _Set(PageSize, newPageSize, PageSizeChanged, val => PageSize = val);
62 |
63 | public void SetPageCount(int newPageCount) =>
64 | _Set(PageCount, newPageCount, PageCountChanged, val => PageCount = val);
65 |
66 | public void SetCurrentPage(int newCurrentPage)
67 | {
68 | if (newCurrentPage != CurrentPage)
69 | {
70 | int oldPage = CurrentPage;
71 | CurrentPage = newCurrentPage;
72 | CurrentPageChanged?.Invoke((oldPage, newCurrentPage));
73 | }
74 | }
75 |
76 | public void SetPath(string path) =>
77 | _Set(Path, path, null, val => Path = val);
78 |
79 | public void SetInProgress(bool inProgress) =>
80 | _Set(InProgress, inProgress, InProgressChanged, val => InProgress = val);
81 |
82 | public void FireLoadProgressChanged(int count) =>
83 | LoadProgressChanged?.Invoke(count);
84 |
85 | public void PushFolder(DriveItem folder)
86 | {
87 | if(folder?.IsFolder() == true && (_folders.Count == 0 || !_folders.Contains(folder)))
88 | {
89 | _folders.Push(folder);
90 |
91 | string newPath = Path;
92 | string folderName = folder.Name;
93 |
94 | if (IsRootFolder)
95 | newPath = string.Empty;
96 | else
97 | newPath += "/" + folderName;
98 |
99 | SetPath(newPath);
100 |
101 | _Set(SelectedFolder, folder, SelectedFolderChanged, val => SelectedFolder = val);
102 | }
103 | }
104 |
105 | public void PopFolder()
106 | {
107 | if (_folders.Count > 1)
108 | {
109 | _folders.Pop();
110 |
111 | if (!string.IsNullOrEmpty(Path) && Path != "/")
112 | {
113 | int index = Path.LastIndexOf('/');
114 | if (index == 0)
115 | SetPath(string.Empty);
116 | if (index != -1)
117 | SetPath(Path.Substring(0, index));
118 | }
119 |
120 | _Set(SelectedFolder, _folders.Peek(), SelectedFolderChanged, val => SelectedFolder = val);
121 | }
122 | }
123 |
124 | public bool IsRootFolder => _folders.Count < 2;
125 |
126 | public void SelectFile(DriveItem item)
127 | {
128 | _Set(SelectedFile, item, SelectedFileChanged, val => SelectedFile = val);
129 | }
130 |
131 | private void _ResetPaging()
132 | {
133 | _pageTokens.Clear();
134 | SetCurrentPage(1);
135 | SetPageCount(1);
136 | }
137 |
138 | public void SetPageCount(int totalItemCount, int pageSize)
139 | {
140 | if (totalItemCount > 1 && pageSize > 0)
141 | SetPageCount((int)Math.Ceiling((double)totalItemCount / pageSize));
142 | else
143 | SetPageCount(1);
144 | }
145 |
146 | public void PreviousPage()
147 | {
148 | if (CurrentPage > 1)
149 | SetCurrentPage(CurrentPage - 1);
150 | }
151 |
152 | public void NextPage()
153 | {
154 | if (CurrentPage < PageCount)
155 | SetCurrentPage(CurrentPage + 1);
156 | }
157 |
158 | public void SetPageToken(int pageNumber, string skipToken) =>
159 | _pageTokens[pageNumber] = skipToken;
160 |
161 | public bool TryGetPageToken(int pageNumber, out string skipToken) =>
162 | _pageTokens.TryGetValue(pageNumber, out skipToken);
163 |
164 | public bool HasPages() => PageCount > 1;
165 |
166 | private bool _Set(T existing, T updated, Action changeEvent, Action setter)
167 | {
168 | if (!EqualityComparer.Default.Equals(existing, updated))
169 | {
170 | setter((T)updated);
171 | changeEvent?.Invoke();
172 | return true;
173 | }
174 | return false;
175 | }
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/BlazorGraphExample/Services/AuthService.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.JSInterop;
2 | using System;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using W8lessLabs.GraphAPI;
6 |
7 | namespace BlazorGraphExample.Services
8 | {
9 | public class AuthService : IAuthTokenProvider
10 | {
11 | private class MSALAuthConfig
12 | {
13 | public string ClientId { get; set; }
14 | public string[] Scopes { get; set; }
15 | }
16 |
17 | private readonly MSALAuthConfig _config;
18 | private IJSInProcessRuntime _jsRuntime;
19 |
20 | public AuthService(AuthConfig config, IJSRuntime jsRuntime)
21 | {
22 | _config = new MSALAuthConfig()
23 | {
24 | ClientId = config.ClientId,
25 | Scopes = config.Scopes.ToArray()
26 | };
27 | _jsRuntime = (IJSInProcessRuntime)jsRuntime;
28 | }
29 |
30 | public async Task GetUserAccountAsync() =>
31 | await _jsRuntime.InvokeAsync("getUserAccount", _config);
32 |
33 | public bool IsLoggedIn(GraphAccount account) =>
34 | (account != null && account.Expires > DateTime.Now);
35 |
36 | public async Task<(GraphTokenResult token, GraphAccount account)> LoginAsync()
37 | {
38 | var tokenResult = await GetTokenAsync();
39 | return (tokenResult, await GetUserAccountAsync());
40 | }
41 |
42 | public async Task LogoutAsync() =>
43 | await _jsRuntime.InvokeAsync("logout", _config);
44 |
45 | public async Task GetTokenAsync(string accountId = null, bool forceRefresh = false)
46 | {
47 | try
48 | {
49 | var result = await _jsRuntime.InvokeAsync("getTokenAsync", _config);
50 | return new GraphTokenResult(result?.IdToken != null, result.IdToken, result.Expires);
51 | }
52 | catch (Exception)
53 | {
54 | return GraphTokenResult.Failed;
55 | }
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/BlazorGraphExample/Services/GraphAccount.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace BlazorGraphExample.Services
4 | {
5 | public class GraphAccount
6 | {
7 | public GraphAccount() { }
8 |
9 | public GraphAccount(
10 | string accountId,
11 | string accountName,
12 | DateTime expires,
13 | string tenantId,
14 | string identityProvider,
15 | string azureADObjectId)
16 | {
17 | AccountId = accountId;
18 | AccountName = accountName;
19 | Expires = expires;
20 | TenantId = tenantId;
21 | IdentityProvider = identityProvider;
22 | AzureADObjectId = azureADObjectId;
23 | }
24 |
25 |
26 | public string AccountId { get; set; }
27 | public string AccountName { get; set; }
28 | public DateTime Expires { get; set; }
29 | public string TenantId { get; set; }
30 | public string IdentityProvider { get; set; }
31 | public string AzureADObjectId { get; set; }
32 |
33 | public void Deconstruct(
34 | out string accountId,
35 | out string accountName,
36 | out DateTime expires,
37 | out string tenantId,
38 | out string identityProvider,
39 | out string azureADObjectId)
40 | {
41 | accountId = AccountId;
42 | accountName = AccountName;
43 | expires = Expires;
44 | tenantId = TenantId;
45 | identityProvider = IdentityProvider;
46 | azureADObjectId = AzureADObjectId;
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/BlazorGraphExample/Services/IPagingState.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace BlazorGraphExample.Services
4 | {
5 | public interface IPagingState
6 | {
7 | event Action PageCountChanged;
8 | event Action<(int oldPage, int newPage)> CurrentPageChanged;
9 |
10 | bool HasPages();
11 | int CurrentPage { get; }
12 | int PageCount { get; }
13 | void NextPage();
14 | void PreviousPage();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/BlazorGraphExample/Services/Json/CamelCase.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 |
6 | namespace Microsoft.JSInterop
7 | {
8 | internal static class CamelCase
9 | {
10 | public static string MemberNameToCamelCase(string value)
11 | {
12 | if (string.IsNullOrEmpty(value))
13 | {
14 | throw new ArgumentException(
15 | $"The value '{value ?? "null"}' is not a valid member name.",
16 | nameof(value));
17 | }
18 |
19 | // If we don't need to modify the value, bail out without creating a char array
20 | if (!char.IsUpper(value[0]))
21 | {
22 | return value;
23 | }
24 |
25 | // We have to modify at least one character
26 | var chars = value.ToCharArray();
27 |
28 | var length = chars.Length;
29 | if (length < 2 || !char.IsUpper(chars[1]))
30 | {
31 | // Only the first character needs to be modified
32 | // Note that this branch is functionally necessary, because the 'else' branch below
33 | // never looks at char[1]. It's always looking at the n+2 character.
34 | chars[0] = char.ToLowerInvariant(chars[0]);
35 | }
36 | else
37 | {
38 | // If chars[0] and chars[1] are both upper, then we'll lowercase the first char plus
39 | // any consecutive uppercase ones, stopping if we find any char that is followed by a
40 | // non-uppercase one
41 | var i = 0;
42 | while (i < length)
43 | {
44 | chars[i] = char.ToLowerInvariant(chars[i]);
45 |
46 | i++;
47 |
48 | // If the next-plus-one char isn't also uppercase, then we're now on the last uppercase, so stop
49 | if (i < length - 1 && !char.IsUpper(chars[i + 1]))
50 | {
51 | break;
52 | }
53 | }
54 | }
55 |
56 | return new string(chars);
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/BlazorGraphExample/Services/Json/JsonSerializer.cs:
--------------------------------------------------------------------------------
1 | using W8lessLabs.GraphAPI;
2 |
3 | namespace BlazorGraphExample.Services
4 | {
5 | public class JsonSerializer : IJsonSerializer
6 | {
7 | static SimpleJson.IJsonSerializerStrategy _Strategy = new SimpleJson.DataContractJsonSerializerStrategy();
8 |
9 | public T Deserialize(string value) => SimpleJson.SimpleJson.DeserializeObject(value, _Strategy);
10 | public string Serialize(T value) => SimpleJson.SimpleJson.SerializeObject(value, _Strategy);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/BlazorGraphExample/Services/Json/README.txt:
--------------------------------------------------------------------------------
1 | SimpleJson is from https://github.com/facebook-csharp-sdk/simple-json
2 | Copied from Blazor project at: https://github.com/aspnet/Blazor/blob/e1bbf087b57db5f1ef59ebd78c10795979441d62/src/Microsoft.JSInterop/Json/SimpleJson/SimpleJson.cs
3 |
4 | CHANGES MADE
5 | ============
6 | * Better handling of System.DateTime serialized by Json.NET
7 | as suggested in https://github.com/facebook-csharp-sdk/simple-json/issues/78
8 |
9 | LICENSE (from https://github.com/facebook-csharp-sdk/simple-json/blob/08b6871e8f63e866810d25e7a03c48502c9a234b/LICENSE.txt):
10 | =====
11 | Copyright (c) 2011, The Outercurve Foundation
12 |
13 | Permission is hereby granted, free of charge, to any person obtaining
14 | a copy of this software and associated documentation files (the
15 | "Software"), to deal in the Software without restriction, including
16 | without limitation the rights to use, copy, modify, merge, publish,
17 | distribute, sublicense, and/or sell copies of the Software, and to
18 | permit persons to whom the Software is furnished to do so, subject to
19 | the following conditions:
20 |
21 | The above copyright notice and this permission notice shall be
22 | included in all copies or substantial portions of the Software.
23 |
24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 |
32 |
33 | CamelCase.cs is from https://raw.githubusercontent.com/aspnet/Blazor/e1bbf087b57db5f1ef59ebd78c10795979441d62/src/Microsoft.JSInterop/Json/CamelCase.cs
34 |
35 | NO CHANGES MADE
36 | ============
37 |
38 | LICENSE (from https://github.com/aspnet/Blazor/blob/a51a3e60bf15ce5d92bbf392091c68398e978b02/LICENSE.txt)
39 | ============
40 |
41 | Copyright (c) .NET Foundation and Contributors
42 |
43 | All rights reserved.
44 |
45 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
46 | this file except in compliance with the License. You may obtain a copy of the
47 | License at
48 |
49 | http://www.apache.org/licenses/LICENSE-2.0
50 |
51 | Unless required by applicable law or agreed to in writing, software distributed
52 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
53 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
54 | specific language governing permissions and limitations under the License.
--------------------------------------------------------------------------------
/BlazorGraphExample/Services/LoginStatus.cs:
--------------------------------------------------------------------------------
1 | namespace BlazorGraphExample.Services
2 | {
3 | public enum LoginStatus
4 | {
5 | Undetermined = 0,
6 | LoggedOut = 1,
7 | LoggedIn = 2
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/BlazorGraphExample/Services/PageChangedEvent.cs:
--------------------------------------------------------------------------------
1 | namespace BlazorGraphExample.Services
2 | {
3 | public struct PageChangedEvent
4 | {
5 | public int OldPage;
6 | public int NewPage;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/BlazorGraphExample/Services/TokenResult.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace BlazorGraphExample.Services
4 | {
5 | public class TokenResult
6 | {
7 | public string IdToken { get; set; }
8 | public DateTime Expires { get; set; }
9 | public string AccountId { get; set; }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/BlazorGraphExample/Shared/Format.cs:
--------------------------------------------------------------------------------
1 | using ByteSizeLib;
2 |
3 | namespace BlazorGraphExample
4 | {
5 | public static class Format
6 | {
7 | public static string FormatFileSize(long size)
8 | {
9 | var byteSize = ByteSize.FromBytes(size);
10 | if (size > 1_000_000)
11 | return byteSize.ToString("MB");
12 | else
13 | return byteSize.ToString("KB");
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/BlazorGraphExample/Shared/MainLayout.razor:
--------------------------------------------------------------------------------
1 | @inherits LayoutComponentBase
2 |
3 |
4 |
5 | @Body
6 |
7 |
8 |
--------------------------------------------------------------------------------
/BlazorGraphExample/Startup.cs:
--------------------------------------------------------------------------------
1 | using BlazorGraphExample.Services;
2 | using Microsoft.AspNetCore.Components.Builder;
3 | using Microsoft.Extensions.DependencyInjection;
4 | using W8lessLabs.GraphAPI;
5 |
6 | namespace BlazorGraphExample
7 | {
8 |
9 | public class Startup
10 | {
11 | public void ConfigureServices(IServiceCollection services)
12 | {
13 | var appState = new AppState();
14 | services.AddSingleton(appState);
15 | services.AddSingleton(appState);
16 |
17 | var authConfig = new AuthConfig(
18 | clientId: "CLIENT ID HERE",
19 | scopes: new[] { "https://graph.microsoft.com/user.read https://graph.microsoft.com/files.read" }
20 | );
21 | services.AddSingleton(authConfig);
22 | services.AddSingleton(); // Used by HttpService
23 | services.AddSingleton(); // Used by GraphService
24 | services.AddSingleton();
25 | services.AddSingleton(); // Used by GraphService
26 | services.AddSingleton();
27 | }
28 |
29 | public void Configure(IComponentsApplicationBuilder app)
30 | {
31 | app.AddComponent("app");
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/BlazorGraphExample/_Imports.razor:
--------------------------------------------------------------------------------
1 | @using System.Net.Http
2 | @using System.Linq
3 | @using Microsoft.AspNetCore.Components.Routing
4 | @using BlazorGraphExample
5 | @using BlazorGraphExample.Components
6 | @using BlazorGraphExample.Shared
7 | @using BlazorGraphExample.Services
8 | @using W8lessLabs.GraphAPI
--------------------------------------------------------------------------------
/BlazorGraphExample/bundleconfig.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "outputFileName": "wwwroot/css/bulma/bulma.min.css",
4 | "inputFiles": [
5 | "node_modules/bulma/css/bulma.min.css",
6 | "node_modules/bulma-pageloader/dist/css/bulma-pageloader.min.css",
7 | "node_modules/bulma-tooltip/dist/css/bulma-tooltip.min.css"
8 | ]
9 | },
10 | //{
11 | // "outputFileName": "wwwroot/css/open-iconic/font/css/open-iconic.min.css",
12 | // "inputFiles": [
13 | // "node_modules/open-iconic/font/css/open-iconic.min.css"
14 | // ],
15 | // "minify": { "enabled": false }
16 | //},
17 | {
18 | "outputFileName": "wwwroot/scripts/msal/msal.min.js",
19 | "inputFiles": [
20 | "node_modules/msal/dist/msal.min.js"
21 | ]
22 | }
23 | ]
--------------------------------------------------------------------------------
/BlazorGraphExample/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "myproject",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "bulma": {
8 | "version": "0.7.5",
9 | "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.7.5.tgz",
10 | "integrity": "sha512-cX98TIn0I6sKba/DhW0FBjtaDpxTelU166pf7ICXpCCuplHWyu6C9LYZmL5PEsnePIeJaiorsTEzzNk3Tsm1hw==",
11 | "dev": true
12 | },
13 | "bulma-pageloader": {
14 | "version": "2.1.0",
15 | "resolved": "https://registry.npmjs.org/bulma-pageloader/-/bulma-pageloader-2.1.0.tgz",
16 | "integrity": "sha512-yI1SBxeGfj57BYtN8tIcvaGlfQgxylPwHHaDNSYLhF+1EVwUjWz97Ufga+8VOv9PZuhhnD05rb8nZ+p0isWw9A==",
17 | "dev": true
18 | },
19 | "bulma-tooltip": {
20 | "version": "2.0.2",
21 | "resolved": "https://registry.npmjs.org/bulma-tooltip/-/bulma-tooltip-2.0.2.tgz",
22 | "integrity": "sha512-xsqWeWV7tsUn3uH04SqJeP7/CyC1RaDVIyVzr4/sIO3friIIOi7L6jc5g7qUwDxuBQl72yH/yRPuefpXoQ4hWg==",
23 | "dev": true
24 | },
25 | "msal": {
26 | "version": "1.1.1",
27 | "resolved": "https://registry.npmjs.org/msal/-/msal-1.1.1.tgz",
28 | "integrity": "sha512-vPyMqFChZU3MDYrrbeKaI9xQe+LOdH2RhK2STi38vX5jVNefIiotNGbjrsyOqmrE8AWSTAP1mr8FZwEeJ6JIhg==",
29 | "dev": true,
30 | "requires": {
31 | "tslib": "^1.9.3",
32 | "uuid": "^3.3.2"
33 | }
34 | },
35 | "open-iconic": {
36 | "version": "1.1.1",
37 | "resolved": "https://registry.npmjs.org/open-iconic/-/open-iconic-1.1.1.tgz",
38 | "integrity": "sha1-nc/Ix808Yc20ojaxo0eJTJetwMY=",
39 | "dev": true
40 | },
41 | "tslib": {
42 | "version": "1.10.0",
43 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
44 | "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==",
45 | "dev": true
46 | },
47 | "uuid": {
48 | "version": "3.3.2",
49 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
50 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
51 | "dev": true
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/BlazorGraphExample/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "myproject",
3 | "version": "1.0.0",
4 | "devDependencies": {
5 | "bulma": "^0.7.5",
6 | "bulma-pageloader": "2.1.0",
7 | "bulma-tooltip": "2.0.2",
8 | "msal": "1.1.1",
9 | "open-iconic": "^1.1.1"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/BlazorGraphExample/wwwroot/css/open-iconic/FONT-LICENSE:
--------------------------------------------------------------------------------
1 | SIL OPEN FONT LICENSE Version 1.1
2 |
3 | Copyright (c) 2014 Waybury
4 |
5 | PREAMBLE
6 | The goals of the Open Font License (OFL) are to stimulate worldwide
7 | development of collaborative font projects, to support the font creation
8 | efforts of academic and linguistic communities, and to provide a free and
9 | open framework in which fonts may be shared and improved in partnership
10 | with others.
11 |
12 | The OFL allows the licensed fonts to be used, studied, modified and
13 | redistributed freely as long as they are not sold by themselves. The
14 | fonts, including any derivative works, can be bundled, embedded,
15 | redistributed and/or sold with any software provided that any reserved
16 | names are not used by derivative works. The fonts and derivatives,
17 | however, cannot be released under any other type of license. The
18 | requirement for fonts to remain under this license does not apply
19 | to any document created using the fonts or their derivatives.
20 |
21 | DEFINITIONS
22 | "Font Software" refers to the set of files released by the Copyright
23 | Holder(s) under this license and clearly marked as such. This may
24 | include source files, build scripts and documentation.
25 |
26 | "Reserved Font Name" refers to any names specified as such after the
27 | copyright statement(s).
28 |
29 | "Original Version" refers to the collection of Font Software components as
30 | distributed by the Copyright Holder(s).
31 |
32 | "Modified Version" refers to any derivative made by adding to, deleting,
33 | or substituting -- in part or in whole -- any of the components of the
34 | Original Version, by changing formats or by porting the Font Software to a
35 | new environment.
36 |
37 | "Author" refers to any designer, engineer, programmer, technical
38 | writer or other person who contributed to the Font Software.
39 |
40 | PERMISSION & CONDITIONS
41 | Permission is hereby granted, free of charge, to any person obtaining
42 | a copy of the Font Software, to use, study, copy, merge, embed, modify,
43 | redistribute, and sell modified and unmodified copies of the Font
44 | Software, subject to the following conditions:
45 |
46 | 1) Neither the Font Software nor any of its individual components,
47 | in Original or Modified Versions, may be sold by itself.
48 |
49 | 2) Original or Modified Versions of the Font Software may be bundled,
50 | redistributed and/or sold with any software, provided that each copy
51 | contains the above copyright notice and this license. These can be
52 | included either as stand-alone text files, human-readable headers or
53 | in the appropriate machine-readable metadata fields within text or
54 | binary files as long as those fields can be easily viewed by the user.
55 |
56 | 3) No Modified Version of the Font Software may use the Reserved Font
57 | Name(s) unless explicit written permission is granted by the corresponding
58 | Copyright Holder. This restriction only applies to the primary font name as
59 | presented to the users.
60 |
61 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
62 | Software shall not be used to promote, endorse or advertise any
63 | Modified Version, except to acknowledge the contribution(s) of the
64 | Copyright Holder(s) and the Author(s) or with their explicit written
65 | permission.
66 |
67 | 5) The Font Software, modified or unmodified, in part or in whole,
68 | must be distributed entirely under this license, and must not be
69 | distributed under any other license. The requirement for fonts to
70 | remain under this license does not apply to any document created
71 | using the Font Software.
72 |
73 | TERMINATION
74 | This license becomes null and void if any of the above conditions are
75 | not met.
76 |
77 | DISCLAIMER
78 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
79 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
80 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
81 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
82 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
83 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
84 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
85 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
86 | OTHER DEALINGS IN THE FONT SOFTWARE.
87 |
--------------------------------------------------------------------------------
/BlazorGraphExample/wwwroot/css/open-iconic/ICON-LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Waybury
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
--------------------------------------------------------------------------------
/BlazorGraphExample/wwwroot/css/open-iconic/README.md:
--------------------------------------------------------------------------------
1 | [Open Iconic v1.1.1](http://useiconic.com/open)
2 | ===========
3 |
4 | ### Open Iconic is the open source sibling of [Iconic](http://useiconic.com). It is a hyper-legible collection of 223 icons with a tiny footprint—ready to use with Bootstrap and Foundation. [View the collection](http://useiconic.com/open#icons)
5 |
6 |
7 |
8 | ## What's in Open Iconic?
9 |
10 | * 223 icons designed to be legible down to 8 pixels
11 | * Super-light SVG files - 61.8 for the entire set
12 | * SVG sprite—the modern replacement for icon fonts
13 | * Webfont (EOT, OTF, SVG, TTF, WOFF), PNG and WebP formats
14 | * Webfont stylesheets (including versions for Bootstrap and Foundation) in CSS, LESS, SCSS and Stylus formats
15 | * PNG and WebP raster images in 8px, 16px, 24px, 32px, 48px and 64px.
16 |
17 |
18 | ## Getting Started
19 |
20 | #### For code samples and everything else you need to get started with Open Iconic, check out our [Icons](http://useiconic.com/open#icons) and [Reference](http://useiconic.com/open#reference) sections.
21 |
22 | ### General Usage
23 |
24 | #### Using Open Iconic's SVGs
25 |
26 | We like SVGs and we think they're the way to display icons on the web. Since Open Iconic are just basic SVGs, we suggest you display them like you would any other image (don't forget the `alt` attribute).
27 |
28 | ```
29 |
30 | ```
31 |
32 | #### Using Open Iconic's SVG Sprite
33 |
34 | Open Iconic also comes in a SVG sprite which allows you to display all the icons in the set with a single request. It's like an icon font, without being a hack.
35 |
36 | Adding an icon from an SVG sprite is a little different than what you're used to, but it's still a piece of cake. *Tip: To make your icons easily style able, we suggest adding a general class to the* `