More development

This commit is contained in:
thepra committed 2020-05-02 18:57:42 +02:00
1 parent c1f5f82329
commit 29cde263d3
14 files changed
+181 -43

No files matched your search

+5 -4
View File
@@ -6,18 +6,19 @@ namespace Seenginx.Models
{
public class ConfigFile
{
public string FullPath { get; set; }
public string Folder { get; set; }
public string Name { get; set; }
public bool HasDraft => !string.IsNullOrEmpty(DraftName);
public string DraftName { get; set; }
public string OriginalBody { get; set; }
public string Body { get; set; }
public string DraftBody { get; set; }
public string Permissions { get; set; }
public DateTime LastUpdated { get; set; }
public string[] Owners { get; set; }
public string Permissions { get; set; }
public bool CanBeDeleted { get; set; } = true;
public string IsVisible { get; set; } = string.Empty;
public string IsSelected { get; set; } = string.Empty;
public bool HasDraft => !string.IsNullOrEmpty(DraftName);
public bool CanBeDeleted { get; set; } = true;
public void Hide() { IsVisible = "is-hidden"; }
public void Unhide() { IsVisible = string.Empty; }
+6
View File
@@ -11,6 +11,12 @@ namespace Seenginx.Models
public Exception Exception { get; private set; } = null;
public D Data { get; private set; }
public Result() { }
public Result(D data)
{
Data = data;
}
public Result<D> Invalidate(string errorMessage, Exception exception = null)
{
AllOk = false;
-15
View File
@@ -1,15 +0,0 @@
using System;
namespace Seenginx.Models
{
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string Summary { get; set; }
}
}
+8 -8
View File
@@ -12,7 +12,7 @@
</div>
<div class="control has-icons-left">
<div class="select is-small is-rounded">
<select class="neoInput" @onchange="e => OnFilterClick(e.Value.ToString())">
<select class="neoBtnSmall" @onchange="e => OnFilterClick(e.Value.ToString())">
@foreach (var filter in Filters)
{
<option value="@filter">@filter</option>
@@ -37,7 +37,7 @@
@onchange="e => SelectedFile.DraftName = e.Value.ToString()">
</div>
<div class="control">
<button class="button is-small is-rounded neoBtn" @onclick="OnFileCloseClick">
<button class="button is-small is-rounded neoBtnSmall" @onclick="OnFileCloseClick">
<span class="icon is-medium">
<i class="mdi mdi-close"></i>
</span>
@@ -75,13 +75,13 @@
<div class="filesActions">
<div class="buttons is-centered">
<button class="button is-rounded neoBtn is-small noBottomMargin" @onclick="OnAddDialog">
<button class="button is-rounded neoBtnSmall is-small noBottomMargin" @onclick="OnAddDialog">
<span class="icon is-small has-text-success">
<i class="mdi mdi-plus-box-outline"></i>
</span>
<span>Add</span>
</button>
<button class="button is-rounded neoBtn is-small noBottomMargin @IsSelectedFileDeletable" @onclick="OnDeleteDialog">
<button class="button is-rounded neoBtnSmall is-small noBottomMargin @IsSelectedFileDeletable" @onclick="OnDeleteDialog">
<span class="icon is-small has-text-danger">
<i class="mdi mdi-minus-box-outline"></i>
</span>
@@ -94,10 +94,10 @@
@if (IsAnyFileSelected)
{
<div class="buttons is-centered">
<button @onclick="OnSaveDraft" class="button is-rounded neoBtn is-small has-icon-left noBottomMargin"><span class="icon is-left has-text-light"><i class="mdi mdi-content-save-outline"></i></span> <span>Save draft</span></button>
<button @onclick="OnUndoChanges" class="button is-rounded neoBtn is-small has-icon-left noBottomMargin"><span class="icon is-left has-text-dark"><i class="mdi mdi-undo-variant"></i></span> <span>Undo changes</span></button>
<button @onclick="OnSave" class="button is-rounded neoBtn is-small has-icon-left noBottomMargin"><span class="icon is-left has-text-success"><i class="mdi mdi-content-save-all-outline"></i></span> <span>Save</span></button>
<button @onclick="OnTest" class="button is-rounded neoBtn is-small has-icon-left noBottomMargin"><span class="icon is-left has-text-danger"><i class="mdi mdi-alert-outline"></i></span> <span>Test</span></button>
<button @onclick="OnSaveDraft" class="button is-rounded neoBtnSmall is-small has-icon-left noBottomMargin"><span class="icon is-left has-text-light"><i class="mdi mdi-content-save-outline"></i></span> <span>Save draft</span></button>
<button @onclick="OnUndoChanges" class="button is-rounded neoBtnSmall is-small has-icon-left noBottomMargin"><span class="icon is-left has-text-dark"><i class="mdi mdi-undo-variant"></i></span> <span>Undo changes</span></button>
<button @onclick="OnSave" class="button is-rounded neoBtnSmall is-small has-icon-left noBottomMargin"><span class="icon is-left has-text-success"><i class="mdi mdi-content-save-all-outline"></i></span> <span>Save</span></button>
<button @onclick="OnTest" class="button is-rounded neoBtnSmall is-small has-icon-left noBottomMargin"><span class="icon is-left has-text-danger"><i class="mdi mdi-alert-outline"></i></span> <span>Test</span></button>
</div>
}
else
+6 -6
View File
@@ -29,7 +29,7 @@ namespace Seenginx.Components
[Parameter]
public EventCallback<CFile> UpdateFile { get; set; }
[Parameter]
public EventCallback<CFile> DeleteFile { get; set; }
public EventCallback DeleteFile { get; set; }
[Parameter]
public RenderFragment<CFile> Editor { get; set; } = null;
@@ -134,7 +134,7 @@ namespace Seenginx.Components
{
Files.ForEach(f => f.Deselect());
file.Select();
await JsRuntime.InvokeVoidAsync("UpdateEditor", file.OriginalBody);
await JsRuntime.InvokeVoidAsync("UpdateEditor", file.Body);
await SelectedFileChanged.InvokeAsync(file);
}
@@ -152,13 +152,13 @@ namespace Seenginx.Components
}
protected async Task OnUndoChanges(MouseEventArgs e)
{
SelectedFile.DraftBody = SelectedFile.OriginalBody;
await JsRuntime.InvokeVoidAsync("UpdateEditor", SelectedFile.OriginalBody);
SelectedFile.DraftBody = SelectedFile.Body;
await JsRuntime.InvokeVoidAsync("UpdateEditor", SelectedFile.Body);
}
protected async Task OnSave(MouseEventArgs e)
{
var draftCode = await JsRuntime.InvokeAsync<string>("GetEditorCode");
SelectedFile.OriginalBody = draftCode;
SelectedFile.Body = draftCode;
}
protected async Task OnTest(MouseEventArgs e)
{
@@ -170,7 +170,7 @@ namespace Seenginx.Components
}
protected async Task OnDeleteDialog()
{
await UpdateFile.InvokeAsync(SelectedFile);
await DeleteFile.InvokeAsync(null);
}
}
}
+2 -1
View File
@@ -1,10 +1,11 @@
@inherits NginxBase
@page "/nginx"
<p>ciao</p>
<FilesWithEditor CFile="ConfigFile" Filters="Filters" Files="ConfigFiles" FilterFolder="FilterFolder"
SelectedFile="SelectedFile" SelectedFileChanged="SelectedFileChanged"
AddFile="AddFile" UpdateFile="UpdateFile" DeleteFile="DeleteFile">
AddFile="AddFile" DeleteFile="DeleteFile">
</FilesWithEditor>
<Modal @ref="ModalRef">
<ModalBackdrop />
+12 -4
View File
@@ -14,6 +14,8 @@ namespace Seenginx.Pages
{
[Inject]
public INginxService NginxService { get; set; }
[Inject]
public IFileManager FileService { get; set; }
public string InputSearch { get; set; }
@@ -57,11 +59,17 @@ namespace Seenginx.Pages
{
ShowModal();
}
public async Task UpdateFile(ConfigFile configFile)
{
}
public async Task DeleteFile(ConfigFile configFile)
public async Task<Result<ConfigFile>> SaveDraftFileAsync() =>
await FileService.SaveUpdateDraftFileAsync(SelectedFile);
public async Task<Result<ConfigFile>> SaveFileAsync() =>
await FileService.SaveUpdateFileAsync(SelectedFile);
public Result<bool> DeleteFile(EventArgs eventArgs)
{
return FileService.DeleteFile(SelectedFile);
}
}
}
+20
View File
@@ -85,6 +85,26 @@
border: none !important;
transform: scale(1.1);
}
&Small {
box-shadow: -2px -2px 4px rgba($light-shadow, .5), 2px 2px 4px rgba($dark-shadow, .5);
background: none !important;
border: none !important;
transition: all .2s linear;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
&:focus {
box-shadow: -2px -2px 4px rgba($light-shadow, .5), 2px 2px 4px rgba($dark-shadow, .5) !important;
}
&:hover {
box-shadow: -4px -4px 8px rgba($light-shadow, .5), 4px 4px 8px rgba($dark-shadow, .5);
background: none !important;
border: none !important;
transform: scale(1.1);
}
}
}
&File {
+83
View File
@@ -0,0 +1,83 @@
using Seenginx.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace Seenginx.Services
{
public class FileManager : IFileManager
{
public async Task<Result<ConfigFile>> SaveUpdateFileAsync(ConfigFile configFile)
{
var result = new Result<ConfigFile>(configFile);
try
{
var validationResult = ValidForUpdate(configFile);
if (!validationResult.AllOk)
return result.Invalidate($"Failed validation for: {validationResult.ErrorMessage}");
await File.WriteAllTextAsync(configFile.FullPath, configFile.Body);
return result;
}
catch (Exception ex)
{
return result.Invalidate($"Exception at {nameof(SaveUpdateFileAsync)}(), with {nameof(ConfigFile.Name)}=[{nameof(configFile.Name)}]", ex);
}
}
public async Task<Result<ConfigFile>> SaveUpdateDraftFileAsync(ConfigFile configFile)
{
var result = new Result<ConfigFile>(configFile);
try
{
var validationResult = ValidForUpdate(configFile);
if (!validationResult.AllOk)
return result.Invalidate($"Failed validation for: {validationResult.ErrorMessage}");
await File.WriteAllTextAsync($"{configFile.FullPath}.draft", configFile.DraftBody);
return result;
}
catch (Exception ex)
{
return result.Invalidate($"Exception at {nameof(SaveUpdateDraftFileAsync)}(), with {nameof(ConfigFile.Name)}=[{nameof(configFile.Name)}]", ex);
}
}
public Result<bool> DeleteFile(ConfigFile configFile)
{
var result = new Result<bool>();
try
{
var validationResult = ValidForUpdate(configFile);
if (!validationResult.AllOk)
return result.Invalidate($"Failed validation for: {validationResult.ErrorMessage}");
File.Delete(configFile.FullPath);
if (File.Exists($"{configFile.FullPath}.draft"))
File.Delete($"{configFile.FullPath}.draft");
return result;
}
catch (Exception ex)
{
return result.Invalidate($"Exception at {nameof(DeleteFile)}(), with {nameof(ConfigFile.Name)}=[{nameof(configFile.Name)}]", ex);
}
}
private Result<string> ValidForUpdate(ConfigFile configFile)
{
var result = new Result<string>();
if (!Directory.Exists(Directory.GetDirectoryRoot(configFile.FullPath)))
return result.Invalidate($"Directory '{Directory.GetDirectoryRoot(configFile.FullPath)}' doesn't exist.");
if (!File.Exists(configFile.FullPath))
return result.Invalidate($"File '{configFile.FullPath}' doesn't exist.");
return result;
}
}
}
+15
View File
@@ -0,0 +1,15 @@
using Seenginx.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Seenginx.Services
{
public interface IFileManager
{
Task<Result<ConfigFile>> SaveUpdateFileAsync(ConfigFile configFile);
Task<Result<ConfigFile>> SaveUpdateDraftFileAsync(ConfigFile configFile);
Result<bool> DeleteFile(ConfigFile configFile);
}
}
+8 -4
View File
@@ -33,7 +33,8 @@ namespace Seenginx.Services
configFile.Folder = "/";
configFile.LastUpdated = File.GetLastWriteTime(fp);
configFile.Name = fileName;
configFile.OriginalBody = File.ReadAllText(fp);
configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Folder, configFile.Name);
configFile.Body = File.ReadAllText(fp);
return configFile;
});
var confdConfigFiles = confdConfigs.Select(fp =>
@@ -44,7 +45,8 @@ namespace Seenginx.Services
configFile.Folder = "/conf.d";
configFile.LastUpdated = File.GetLastWriteTime(fp);
configFile.Name = fileName;
configFile.OriginalBody = File.ReadAllText(fp);
configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Folder, configFile.Name);
configFile.Body = File.ReadAllText(fp);
return configFile;
});
var sitesAvailableConfigFiles = sitesAvailableConfigs.Select(fp =>
@@ -55,7 +57,8 @@ namespace Seenginx.Services
configFile.Folder = "/sites-available";
configFile.LastUpdated = File.GetLastWriteTime(fp);
configFile.Name = fileName;
configFile.OriginalBody = File.ReadAllText(fp);
configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Folder, configFile.Name);
configFile.Body = File.ReadAllText(fp);
return configFile;
});
var sitesEnabledConfigFiles = sitesEnabledConfigs.Select(fp =>
@@ -66,7 +69,8 @@ namespace Seenginx.Services
configFile.Folder = "/sites-enabled";
configFile.LastUpdated = File.GetLastWriteTime(fp);
configFile.Name = fileName;
configFile.OriginalBody = File.ReadAllText(fp);
configFile.FullPath = Path.Combine(ConfigPaths.NginxPath, configFile.Folder, configFile.Name);
configFile.Body = File.ReadAllText(fp);
return configFile;
});
var finalList = new List<ConfigFile>();
+1
View File
@@ -48,6 +48,7 @@ namespace Seenginx
services.AddTransient<IDmesgService, DmesgService>();
services.AddTransient<INginxService, NginxService>();
services.AddTransient<ISystemDService, SystemDService>();
services.AddTransient<IFileManager, FileManager>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+14
View File
@@ -90,6 +90,20 @@ html {
background: none !important;
border: none !important;
transform: scale(1.1); }
.neoBtnSmall {
box-shadow: -2px -2px 4px rgba(251, 238, 208, 0.5), 2px 2px 4px rgba(241, 185, 65, 0.5);
background: none !important;
border: none !important;
transition: all .2s linear;
-webkit-backface-visibility: hidden;
backface-visibility: hidden; }
.neoBtnSmall:focus {
box-shadow: -2px -2px 4px rgba(251, 238, 208, 0.5), 2px 2px 4px rgba(241, 185, 65, 0.5) !important; }
.neoBtnSmall:hover {
box-shadow: -4px -4px 8px rgba(251, 238, 208, 0.5), 4px 4px 8px rgba(241, 185, 65, 0.5);
background: none !important;
border: none !important;
transform: scale(1.1); }
.neoFile {
box-shadow: 0px 0px 0px rgba(251, 238, 208, 0.5), 0px 0px 0px rgba(241, 185, 65, 0.5) !important;
+1 -1
View File
@@ -1 +1 @@
#blazor-error-ui{background:#ffffe0;bottom:0;box-shadow:0 -1px 2px rgba(0,0,0,.2);display:none;left:0;padding:.6rem 1.25rem .7rem 1.25rem;position:fixed;width:100%;z-index:1000;}#blazor-error-ui .dismiss{cursor:pointer;position:absolute;right:.75rem;top:.5rem;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;}html{scrollbar-color:#f1b941 #fbeed0;scrollbar-width:thin;scrollbar-arrow-color:#fbeed0;scrollbar-base-color:#f6d287;scrollbar-darkshadow-color:#f1b941;}*{scrollbar-width:inherit;}.isHidden{display:none;}@media only screen and (max-width:37.5em){.isHiddenMobile{display:none;}}.petiteCaps{font-variant:petite-caps;}.flexCenter{display:flex;align-content:center;align-items:center;}.noBottomMargin{margin-bottom:0 !important;}.isNoWrap{white-space:nowrap;}.isFinger{cursor:pointer;}.neomorph{box-shadow:-8px -8px 16px rgba(251,238,208,.5),8px 8px 16px rgba(241,185,65,.5);}.neomorphSmall{box-shadow:-6px -6px 12px rgba(251,238,208,.5),6px 6px 12px rgba(241,185,65,.5);}.neomorphXSmall{box-shadow:-3px -3px 6px rgba(251,238,208,.5),3px 3px 6px rgba(241,185,65,.5);}.neomorphBottom{filter:drop-shadow(8px 8px 14px #f1b941);}.neomorphInset{box-shadow:inset 8px 8px 16px rgba(241,185,65,.5),inset -8px -8px 16px rgba(251,238,208,.5);}.neomorphInsetSmall{box-shadow:inset 6px 6px 12px rgba(241,185,65,.5),inset -6px -6px 12px rgba(251,238,208,.5);}.neomorphInsetXSmall{box-shadow:inset 3px 3px 6px rgba(241,185,65,.5),inset -3px -3px 6px rgba(251,238,208,.5);}.neoBtn{box-shadow:-3px -3px 6px rgba(251,238,208,.5),3px 3px 6px rgba(241,185,65,.5);background:none !important;border:none !important;transition:all .2s linear;-webkit-backface-visibility:hidden;backface-visibility:hidden;}.neoBtn:focus{box-shadow:-3px -3px 6px rgba(251,238,208,.5),3px 3px 6px rgba(241,185,65,.5) !important;}.neoBtn:hover{box-shadow:-6px -6px 12px rgba(251,238,208,.5),6px 6px 12px rgba(241,185,65,.5);background:none !important;border:none !important;transform:scale(1.1);}.neoFile{box-shadow:0 0 0 rgba(251,238,208,.5),0 0 0 rgba(241,185,65,.5) !important;transition:all .2s linear;-webkit-backface-visibility:hidden !important;backface-visibility:hidden !important;background:#f6d287 !important;}.neoFile:hover{box-shadow:-3px -3px 6px rgba(251,238,208,.5),3px 3px 6px rgba(241,185,65,.5) !important;}.neoFile.isSelected{box-shadow:inset 3px 3px 6px rgba(241,185,65,.5),inset -3px -3px 6px rgba(251,238,208,.5) !important;}.neoFile.is-active,.neoFile.active{box-shadow:inset 3px 3px 6px rgba(241,185,65,.5),inset -3px -3px 6px rgba(251,238,208,.5) !important;color:#181515 !important;}.neoInput{box-shadow:inset 2px 2px 4px rgba(241,185,65,.5),inset -2px -2px 4px rgba(251,238,208,.5) !important;background:#f6d287 !important;border:none !important;}.neoInput:focus{border:none !important;}.gradientBackground{background:linear-gradient(to right bottom,#f7d794,#f5cd79);}.borderR{border-radius:14px;}.borderRSmall{border-radius:7px !important;}.borderRBig{border-radius:28px;}.bg{background:#f6d287;}.sameMarginBottom{margin-bottom:1rem !important;}.ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}@font-face{font-family:'Ubuntu';src:url(/fonts/ubuntu-light-webfont.woff2) format("woff2");font-weight:300;font-style:normal;}@font-face{font-family:'Ubuntu-Mono';src:url(/fonts/ubuntumono-regular-webfont.woff2) format("woff2");font-style:normal;}html{font-family:Ubuntu,sans-serif;}.menu-list li a{font-family:Ubuntu-Mono,'Noto Mono';}#editor{position:absolute;top:0;right:0;bottom:0;left:0;}.select:not(.is-multiple):not(.is-loading)::after{border-color:#f1b941;}.select:not(.is-multiple):not(.is-loading):hover::after{border-color:#be860e;}.ace-solarized-light{background:#f6d287;}.ace-solarized-light .ace_gutter{background:#f5cd79;}.ace-solarized-light .ace_gutter-active-line{border-radius:50px 0 0 50px;}.ace-solarized-light .ace_marker-layer .ace_active-line{border-radius:0 50px 50px 0;}:root{--stripe-size:200px;--color1:#f6d287;--color2:#f1b941;--duration:10s;}.stripe{position:relative;display:flex;justify-content:center;align-items:center;justify-items:center;width:100%;height:100%;overflow:hidden;}.stripe_inner{position:relative;display:flex;justify-content:center;align-items:center;width:100%;height:100%;font-size:8rem;text-align:center;font-family:'Anton',sans-serif;color:rgba(255,255,255,0);background:repeating-linear-gradient(45deg,var(--color1) 25%,var(--color1) 50%,var(--color2) 50%,var(--color2) 75%);background-size:var(--stripe-size) var(--stripe-size);background-clip:text;animation:stripeBackgroundPosition var(--duration) linear infinite;}.stripe::before{content:'';position:absolute;top:0;left:0;width:calc(100% + var(--stripe-size));height:100%;background:repeating-linear-gradient(45deg,var(--color2) 25%,var(--color2) 50%,var(--color1) 50%,var(--color1) 75%);background-size:var(--stripe-size) var(--stripe-size);animation:stripeTransform var(--duration) linear infinite;}.stripe::after{content:'';position:absolute;width:100%;height:100%;}@kLine truncated
#blazor-error-ui{background:#ffffe0;bottom:0;box-shadow:0 -1px 2px rgba(0,0,0,.2);display:none;left:0;padding:.6rem 1.25rem .7rem 1.25rem;position:fixed;width:100%;z-index:1000;}#blazor-error-ui .dismiss{cursor:pointer;position:absolute;right:.75rem;top:.5rem;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;}html{scrollbar-color:#f1b941 #fbeed0;scrollbar-width:thin;scrollbar-arrow-color:#fbeed0;scrollbar-base-color:#f6d287;scrollbar-darkshadow-color:#f1b941;}*{scrollbar-width:inherit;}.isHidden{display:none;}@media only screen and (max-width:37.5em){.isHiddenMobile{display:none;}}.petiteCaps{font-variant:petite-caps;}.flexCenter{display:flex;align-content:center;align-items:center;}.noBottomMargin{margin-bottom:0 !important;}.isNoWrap{white-space:nowrap;}.isFinger{cursor:pointer;}.neomorph{box-shadow:-8px -8px 16px rgba(251,238,208,.5),8px 8px 16px rgba(241,185,65,.5);}.neomorphSmall{box-shadow:-6px -6px 12px rgba(251,238,208,.5),6px 6px 12px rgba(241,185,65,.5);}.neomorphXSmall{box-shadow:-3px -3px 6px rgba(251,238,208,.5),3px 3px 6px rgba(241,185,65,.5);}.neomorphBottom{filter:drop-shadow(8px 8px 14px #f1b941);}.neomorphInset{box-shadow:inset 8px 8px 16px rgba(241,185,65,.5),inset -8px -8px 16px rgba(251,238,208,.5);}.neomorphInsetSmall{box-shadow:inset 6px 6px 12px rgba(241,185,65,.5),inset -6px -6px 12px rgba(251,238,208,.5);}.neomorphInsetXSmall{box-shadow:inset 3px 3px 6px rgba(241,185,65,.5),inset -3px -3px 6px rgba(251,238,208,.5);}.neoBtn{box-shadow:-3px -3px 6px rgba(251,238,208,.5),3px 3px 6px rgba(241,185,65,.5);background:none !important;border:none !important;transition:all .2s linear;-webkit-backface-visibility:hidden;backface-visibility:hidden;}.neoBtn:focus{box-shadow:-3px -3px 6px rgba(251,238,208,.5),3px 3px 6px rgba(241,185,65,.5) !important;}.neoBtn:hover{box-shadow:-6px -6px 12px rgba(251,238,208,.5),6px 6px 12px rgba(241,185,65,.5);background:none !important;border:none !important;transform:scale(1.1);}.neoBtnSmall{box-shadow:-2px -2px 4px rgba(251,238,208,.5),2px 2px 4px rgba(241,185,65,.5);background:none !important;border:none !important;transition:all .2s linear;-webkit-backface-visibility:hidden;backface-visibility:hidden;}.neoBtnSmall:focus{box-shadow:-2px -2px 4px rgba(251,238,208,.5),2px 2px 4px rgba(241,185,65,.5) !important;}.neoBtnSmall:hover{box-shadow:-4px -4px 8px rgba(251,238,208,.5),4px 4px 8px rgba(241,185,65,.5);background:none !important;border:none !important;transform:scale(1.1);}.neoFile{box-shadow:0 0 0 rgba(251,238,208,.5),0 0 0 rgba(241,185,65,.5) !important;transition:all .2s linear;-webkit-backface-visibility:hidden !important;backface-visibility:hidden !important;background:#f6d287 !important;}.neoFile:hover{box-shadow:-3px -3px 6px rgba(251,238,208,.5),3px 3px 6px rgba(241,185,65,.5) !important;}.neoFile.isSelected{box-shadow:inset 3px 3px 6px rgba(241,185,65,.5),inset -3px -3px 6px rgba(251,238,208,.5) !important;}.neoFile.is-active,.neoFile.active{box-shadow:inset 3px 3px 6px rgba(241,185,65,.5),inset -3px -3px 6px rgba(251,238,208,.5) !important;color:#181515 !important;}.neoInput{box-shadow:inset 2px 2px 4px rgba(241,185,65,.5),inset -2px -2px 4px rgba(251,238,208,.5) !important;background:#f6d287 !important;border:none !important;}.neoInput:focus{border:none !important;}.gradientBackground{background:linear-gradient(to right bottom,#f7d794,#f5cd79);}.borderR{border-radius:14px;}.borderRSmall{border-radius:7px !important;}.borderRBig{border-radius:28px;}.bg{background:#f6d287;}.sameMarginBottom{margin-bottom:1rem !important;}.ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}@font-face{font-family:'Ubuntu';src:url(/fonts/ubuntu-light-webfont.woff2) format("woff2");font-weight:300;font-style:normal;}@font-face{font-family:'Ubuntu-Mono';src:url(/fonts/ubuntumono-regular-webfont.woff2) format("woff2");font-style:normal;}html{font-family:Ubuntu,sans-serif;}.menu-list li a{font-family:Ubuntu-Mono,'Noto Mono';}#editor{position:absolute;top:0;right:0;bottom:0;left:0;}.select:not(.is-multiple):not(.is-loading)::after{border-color:#f1b941;}.select:not(.is-multiple):not(.is-loading):hover::after{border-color:#be860e;}.ace-solarized-light{background:#f6d287;}.ace-solarized-light .ace_gutter{background:#f5cd79;}.ace-solarized-light .ace_gutter-active-line{border-radius:50px 0 0 50px;}.ace-solarized-light .ace_marker-layer .ace_active-line{border-radius:0 50px 50px 0;}:root{--stripe-size:200px;--color1:#f6d287;--color2:#f1b941;--duration:10s;}.stripe{position:relative;display:flex;justify-content:center;align-items:center;justify-items:center;width:100%;height:100%;overflow:hidden;}.stripe_inner{position:relative;display:flex;justify-content:center;align-items:center;width:100%;height:100%;font-size:8rem;text-align:center;font-family:'Anton',sans-serif;color:rgba(255,255,255,0);background:repeating-linear-gradient(45deg,var(--color1) 25%,var(--color1) 50%,var(--color2) 50%,var(--color2) 75%);background-size:var(--stripe-size) var(--sLine truncated