mirror of
https://github.com/BorysLevytskyi/BitwiseCmd.git
synced 2025-12-10 06:52:05 +01:00
Bladerunner (#67)
* Introduce bladerunner theme * Light neon glow * Fix build error * Different logo font and glow * Neon glow on hover * Make the theme to be easter egg * Toggle lights via header * Minor fixes * Fix lint errors
This commit is contained in:
21
AGENTS.md
Normal file
21
AGENTS.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
Agent Guidelines for This Repository
|
||||||
|
|
||||||
|
Scope
|
||||||
|
- These instructions apply to the entire repository.
|
||||||
|
|
||||||
|
Theme Styling Policy
|
||||||
|
- Centralize all theme-related CSS (e.g., `.light`, `.dark`, `.midnight`, `.bladerunner`, and future themes) in `src/index.css` only.
|
||||||
|
- Do NOT place theme-specific rules in component-scoped stylesheets (e.g., files under `src/shell/components/*.css`). Component CSS must remain theme-agnostic.
|
||||||
|
- If a component needs theme-dependent styling, add/adjust the selectors in `src/index.css` that target the component’s markup (e.g., `.app-root.<theme> .component-selector { ... }`).
|
||||||
|
- Prefer grouping theme rules together by theme block in `src/index.css` for readability and consistency.
|
||||||
|
|
||||||
|
Layout Rules
|
||||||
|
- Global layout modifiers that affect multiple views (e.g., centered vs. stretched layout) should also live in `src/index.css`.
|
||||||
|
|
||||||
|
Examples
|
||||||
|
- Good: `src/index.css` — `.bladerunner .top-links button { color: #ff7fb0 }`
|
||||||
|
- Avoid: `src/shell/components/TopLinks.css` — `.bladerunner .top-links button { ... }`
|
||||||
|
|
||||||
|
Testing
|
||||||
|
- After changing theme styles, verify all themes (Light/Dark/Midnight/Bladerunner) render legibly and that component CSS contains no theme-specific selectors.
|
||||||
|
|
||||||
90
TEMP_whats.tsx
Normal file
90
TEMP_whats.tsx
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import CommandLink from '../../core/components/CommandLink';
|
||||||
|
import './WhatsNewResultView.css';
|
||||||
|
|
||||||
|
function WhatsnewResultView() {
|
||||||
|
|
||||||
|
return <div className="changelog">
|
||||||
|
<h3>Changelog</h3>
|
||||||
|
<div className='item item-new'>
|
||||||
|
<p>
|
||||||
|
<span className="soft date">Nov 6th, 2025</span> <br/>
|
||||||
|
<p>
|
||||||
|
Added a new <CommandLink text="bladerunner" /> theme inspired by neon cyberpunk aesthetics.
|
||||||
|
</p>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className='item item-new'>
|
||||||
|
<p>
|
||||||
|
<span className="soft date">May 10th, 2023</span> <br/>
|
||||||
|
<p>
|
||||||
|
Behold! After a long time of inactivity, BitwiseCmd is getting an update. Here is what changed:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>Browser's JavaScript engine is no longer used for the execution of bitwise operations.
|
||||||
|
BitwiseCmd has its own shiny custom-built bitwise calculator that supports operations integer of different sizes (8,16,32, and 64 bits) as well as their signed and unsigned versions. <CommandLink text='Check it out!' command='-1b 255ub -1 4294967295u -1l 18446744073709551615u' />.
|
||||||
|
This calculator tries to follow the same behavior of bitwise operations as implemented in C.
|
||||||
|
This includes shifting an integer by the number of bytes equal to its size (spoiler: you get the same number, this is undefined behavior in C. Don't believe me? Check this <a href="https://codeyarns.com/tech/2004-12-20-c-shift-operator-mayhem.html#gsc.tab=0">link</a>).</li>
|
||||||
|
<li>A slightly improved UI</li>
|
||||||
|
</ul>
|
||||||
|
<p>I'm sure there will be some bugs following such a big update. I will do my best to fix them as they are found.</p>
|
||||||
|
<p>Many thanks to all people that submitted issues on GitHub. Your feedback is greatly appreciated. </p>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className='item'>
|
||||||
|
<span className="soft date">May 5th, 2023</span> <br/>
|
||||||
|
<p>
|
||||||
|
Fixed <a href="https://github.com/BorysLevytskyi/BitwiseCmd/issues/13">bug</a> with incorrect binary representation of 64-bit numbers.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="item">
|
||||||
|
<p><span className="soft date">Jul 24th, 2021</span> <br/>
|
||||||
|
<ul>
|
||||||
|
<li>Added support of <code>vpc</code> command to see how VPC network address is divided between VPC, Subnets, and Hosts. Try it out: <CommandLink text="vpc 192.168.24.1/24" /></li>
|
||||||
|
<li>Added ability to remove individual results</li>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="item">
|
||||||
|
<span className="soft date">Jun 16th, 2021</span>
|
||||||
|
<p>
|
||||||
|
Added support of <code>subnet</code> command to display information about subnet IP address such. Try it out: <CommandLink text="subnet 192.168.24.1/14" />
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="item">
|
||||||
|
<span className="soft date">Jun 14th, 2021</span>
|
||||||
|
<p>
|
||||||
|
Added support of IP addresses and subnet mask notations. Try them out:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>A single IP address <CommandLink text="127.0.0.1" /></li>
|
||||||
|
<li>Multiple IP addresses and subnet mask notations <CommandLink text="127.0.0.1 192.168.0.0/24" /></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div className="item">
|
||||||
|
<span className="soft date">Jun 6th, 2017</span>
|
||||||
|
<p>
|
||||||
|
Added <code><CommandLink text="guid" /></code> command. Use it for generating v4 GUIDs </p>
|
||||||
|
</div>
|
||||||
|
<div className="item">
|
||||||
|
<span className="soft date">May 27th, 2017</span>
|
||||||
|
<p>
|
||||||
|
Added support of binary number notation (e.g. <code><CommandLink text="0b10101" /></code>). </p>
|
||||||
|
</div>
|
||||||
|
<div className="item">
|
||||||
|
<span className="soft">May 20th, 2017</span>
|
||||||
|
<p>
|
||||||
|
A new <CommandLink text="Midnight" /> theme was added.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="item">
|
||||||
|
<span className="soft">May 16th, 2017</span>
|
||||||
|
<p>
|
||||||
|
Complete rewrite using React. Please let me know if you have problems with this release by <a href="https://github.com/BorysLevytskyi/BitwiseCmd/issues">creating an issue</a> in Github Repo.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WhatsnewResultView;
|
||||||
19662
package-lock.json
generated
Normal file
19662
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -126,7 +126,7 @@ class ExpressionElementTableRow extends React.Component<ExpressionElementRowProp
|
|||||||
return <tr className={"row-with-bits " + css}>
|
return <tr className={"row-with-bits " + css}>
|
||||||
<td className="sign">{sign}</td>
|
<td className="sign">{sign}</td>
|
||||||
<td className="label">
|
<td className="label">
|
||||||
{this.getLabel()}
|
<span>{this.getLabel()}</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="bin">
|
<td className="bin">
|
||||||
<BinaryStringView
|
<BinaryStringView
|
||||||
|
|||||||
184
src/index.css
184
src/index.css
@@ -11,7 +11,26 @@ html { height: 100% }
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
code { font-size: 1.2em; font-weight: bold; }
|
/* Centered vs stretched layout */
|
||||||
|
.app-root.layout-centered { }
|
||||||
|
|
||||||
|
/* Constrain and center top-level sections while keeping full-width theme background */
|
||||||
|
.app-root.layout-centered > * {
|
||||||
|
max-width: clamp(70rem, 92vw, 100rem);
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Blade Runner theme overrides for Settings pane (centralized here per AGENTS.md) */
|
||||||
|
.app-root.bladerunner #settings button { color: #ffbf69 }
|
||||||
|
|
||||||
|
.app-root.layout-stretched {
|
||||||
|
max-width: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Theme-scoped code styling to avoid cross-theme overrides */
|
||||||
|
.light code, .dark code, .midnight code, .bladerunner code { font-size: 1.2em; font-weight: bold; }
|
||||||
|
|
||||||
.icon { margin-right: 5px; vertical-align: middle; }
|
.icon { margin-right: 5px; vertical-align: middle; }
|
||||||
.header-cmd { color: #c5c5c5 }
|
.header-cmd { color: #c5c5c5 }
|
||||||
@@ -30,8 +49,6 @@ code { font-size: 1.2em; font-weight: bold; }
|
|||||||
.button svg { margin: 0; margin-right: 5px; }
|
.button svg { margin: 0; margin-right: 5px; }
|
||||||
.button-large { padding: 10px; }
|
.button-large { padding: 10px; }
|
||||||
|
|
||||||
.button:hover { background: rgba(255, 255, 255, 0.2);}
|
|
||||||
|
|
||||||
.expressionInput {
|
.expressionInput {
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
outline: none;
|
outline: none;
|
||||||
@@ -98,6 +115,14 @@ button.link-button {text-decoration: underline;}
|
|||||||
margin-left: -20px;
|
margin-left: -20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* When Settings is active (no .soft), remove any button border/outline */
|
||||||
|
.settings-button button,
|
||||||
|
.settings-button .command-link {
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
.undo button {
|
.undo button {
|
||||||
opacity: 0.4;
|
opacity: 0.4;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@@ -123,7 +148,7 @@ button.link-button {text-decoration: underline;}
|
|||||||
.light .hashLink, .light .hashLink:visited { color: #aaa; }
|
.light .hashLink, .light .hashLink:visited { color: #aaa; }
|
||||||
.light .hashLink:hover { color: #888 }
|
.light .hashLink:hover { color: #888 }
|
||||||
.light ul.top-links li:hover { background: #ddd }
|
.light ul.top-links li:hover { background: #ddd }
|
||||||
.light .error { color: #da586d }
|
.light .error { color: #d83e8f }
|
||||||
.light button.btn { color: black}
|
.light button.btn { color: black}
|
||||||
.light button.btn:hover { background: #ddd}
|
.light button.btn:hover { background: #ddd}
|
||||||
.light button.btn:disabled { color: #888; background-color: inherit; }
|
.light button.btn:disabled { color: #888; background-color: inherit; }
|
||||||
@@ -133,6 +158,8 @@ button.link-button {text-decoration: underline;}
|
|||||||
.light .button:hover { background: rgba(0, 0, 0, 0.2);}
|
.light .button:hover { background: rgba(0, 0, 0, 0.2);}
|
||||||
.light .solid-border { border: solid 1px gray;}
|
.light .solid-border { border: solid 1px gray;}
|
||||||
.light .accent1-border { border-color:green}
|
.light .accent1-border { border-color:green}
|
||||||
|
.light .help code, .light .help code a { color:green}
|
||||||
|
.light .button:hover { background: rgba(255, 255, 255, 0.2);}
|
||||||
|
|
||||||
/* Dark */
|
/* Dark */
|
||||||
.dark { background: #121212; color: white;}
|
.dark { background: #121212; color: white;}
|
||||||
@@ -147,12 +174,14 @@ button.link-button {text-decoration: underline;}
|
|||||||
.dark .hashLink, .dark .hashLink:visited { color: #555 }
|
.dark .hashLink, .dark .hashLink:visited { color: #555 }
|
||||||
.dark .hashLink:hover { color: #999 }
|
.dark .hashLink:hover { color: #999 }
|
||||||
.dark ul.top-links li:hover { background: #333 }
|
.dark ul.top-links li:hover { background: #333 }
|
||||||
.dark .error { color: #da586d}
|
.dark .error { color: #d83e8f}
|
||||||
.dark button.btn { color: white}
|
.dark button.btn { color: white}
|
||||||
.dark button.btn:hover { background: #333}
|
.dark button.btn:hover { background: #333}
|
||||||
.dark button.btn:disabled { color: #999; background-color: inherit; }
|
.dark button.btn:disabled { color: #999; background-color: inherit; }
|
||||||
.dark .accent1 { color:mediumseagreen}
|
.dark .accent1 { color:mediumseagreen}
|
||||||
.dark .accent1-border { border-color:mediumseagreen}
|
.dark .accent1-border { border-color:mediumseagreen}
|
||||||
|
.dark .help code, .dark .help code a { color:mediumseagreen}
|
||||||
|
.dark .button:hover { background: rgba(255, 255, 255, 0.2);}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Midnight Theme
|
Midnight Theme
|
||||||
@@ -171,13 +200,139 @@ button.link-button {text-decoration: underline;}
|
|||||||
.midnight .hashLink, .midnight .hashLink:visited { color: #85a0ad }
|
.midnight .hashLink, .midnight .hashLink:visited { color: #85a0ad }
|
||||||
.midnight .hashLink:hover { color: #9FBAC7 }
|
.midnight .hashLink:hover { color: #9FBAC7 }
|
||||||
.midnight ul.top-links li:hover { background: #132537 }
|
.midnight ul.top-links li:hover { background: #132537 }
|
||||||
.midnight .error { color:#da586d}
|
.midnight .error { color:#d83e8f}
|
||||||
.midnight .changelog .item-new .date { font-weight: bold }
|
.midnight .changelog .item-new .date { font-weight: bold }
|
||||||
.midnight button.btn { color: white}
|
.midnight button.btn { color: white}
|
||||||
.midnight button.btn:hover { background: #132537}
|
.midnight button.btn:hover { background: #132537}
|
||||||
.midnight button.btn:disabled { color: #85a0ad; background-color: inherit; }
|
.midnight button.btn:disabled { color: #85a0ad; background-color: inherit; }
|
||||||
.midnight .accent1 { color:mediumseagreen}
|
.midnight .accent1 { color:mediumseagreen}
|
||||||
.midnight .accent1-border { border-color:mediumseagreen}
|
.midnight .accent1-border { border-color:mediumseagreen}
|
||||||
|
.midnight .help code, .midnight .help code a { color:mediumseagreen}
|
||||||
|
.midnight .button:hover { background: rgba(255, 255, 255, 0.2);}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Blade Runner Theme
|
||||||
|
*/
|
||||||
|
.bladerunner { background: #0b0f14; color: white }
|
||||||
|
.bladerunner .solid-background { background: #0b0f14; }
|
||||||
|
.bladerunner .header-cmd { color: #ff7fb0a8 !important; }
|
||||||
|
.bladerunner .lights-on .header-cmd { color: #ff7fb0 !important; }
|
||||||
|
/* Rule for element when it has both .header and .on */
|
||||||
|
.bladerunner .header.lights-on { text-shadow: 0 0 4px rgba(255, 127, 176, 0.35), 0 0 9px rgba(255, 127, 176, 0.22); }
|
||||||
|
.bladerunner .header h1 { text-transform: uppercase; color: #66d9e8a8; font-family: Impact, Verdana, sans-serif; cursor: pointer; position: relative; z-index: 1; letter-spacing: 0.02em; }
|
||||||
|
.bladerunner .header h1.lights-on { color: #66d9e8; text-shadow: 0 0 4px rgba(102, 217, 232, 0.35), 0 0 9px rgba(102, 217, 232, 0.22); }
|
||||||
|
.bladerunner .header h1.lights-on::after {
|
||||||
|
/* Neon-style halo: layered cyan + magenta radial glows */
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-30%, -50%);
|
||||||
|
width: 20%;
|
||||||
|
height: 120%;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
|
background:
|
||||||
|
radial-gradient(ellipse at center,
|
||||||
|
rgba(102, 217, 232, 0.70) 0%,
|
||||||
|
rgba(102, 217, 232, 0.45) 22%,
|
||||||
|
rgba(0, 0, 0, 0) 60%),
|
||||||
|
radial-gradient(ellipse at center,
|
||||||
|
rgba(255, 127, 176, 0.55) 0%,
|
||||||
|
rgba(255, 127, 176, 0.35) 35%,
|
||||||
|
rgba(0, 0, 0, 0) 72%);
|
||||||
|
filter: blur(35px);
|
||||||
|
}
|
||||||
|
.bladerunner {color: #e6f0ff;}
|
||||||
|
.bladerunner .expression { color: white; }
|
||||||
|
.bladerunner .expressionInput { color: white; }
|
||||||
|
.bladerunner a, .bladerunner a:visited { color: #00d1f2; }
|
||||||
|
.bladerunner button { color: #00eaff; }
|
||||||
|
.bladerunner .indicator { color: #0e6e7e; }
|
||||||
|
.bladerunner .on { color: white; }
|
||||||
|
.bladerunner .prefix { color: #00d1f2 }
|
||||||
|
.bladerunner .other { color: #6c8497}
|
||||||
|
.bladerunner .label { color: #7ac9d6 }
|
||||||
|
.bladerunner .accent-background { background-color: #131a22; }
|
||||||
|
.bladerunner .hashLink:hover { color: #33e1ff }
|
||||||
|
.bladerunner .error { color:#d83e8f }
|
||||||
|
.bladerunner .changelog .item-new .date { font-weight: bold }
|
||||||
|
.bladerunner button.btn { color: #00eaff }
|
||||||
|
.bladerunner button.btn:hover { background: #11222c }
|
||||||
|
.bladerunner button.btn:disabled { color: #0e6e7e; background-color: inherit; }
|
||||||
|
.bladerunner .accent1 { color: mediumseagreen }
|
||||||
|
.bladerunner .accent1-border { border-color: mediumseagreen }
|
||||||
|
.bladerunner .button { border-color: #00eaff }
|
||||||
|
.bladerunner code { color: #e3a600 }
|
||||||
|
.bladerunner code a, .bladerunner code a:visited { color: #e3a600 }
|
||||||
|
.bladerunner .command-link { color: #5fc2e9 }
|
||||||
|
.bladerunner .command-link:hover,
|
||||||
|
.bladerunner .command-link:focus {
|
||||||
|
/* very dim magenta glow */
|
||||||
|
text-shadow: 0 0 2px rgba(255, 127, 176, 0.5);
|
||||||
|
}
|
||||||
|
.bladerunner .soft { color: #aebed0 }
|
||||||
|
.bladerunner .solid-border { background-color: #0e161d; border-color: #1f3b4a;}
|
||||||
|
.bladerunner .expressionInput {border-color: #1f3b4a;}
|
||||||
|
.bladerunner .expressionInput::placeholder {color: #7e95a7;}
|
||||||
|
.bladerunner .zero {color: #b9cfe2; }
|
||||||
|
.bladerunner .expression {color: #e6f0ff;}
|
||||||
|
.bladerunner .settings-button button {color: #b9cfe2;}
|
||||||
|
.bladerunner button.hashLink, .bladerunner a.hashLink, .bladerunner a.hashLink:visited { color: #52687b; }
|
||||||
|
.bladerunner button.hashLink:hover, .bladerunner a.hashLink:hover {
|
||||||
|
/* subtle glow derived from current hover color */
|
||||||
|
--text-shadow: 0 0 2px currentColor;
|
||||||
|
text-shadow:0 0 2px rgb(229, 33, 0.5);
|
||||||
|
color: #5fc2e9;
|
||||||
|
}
|
||||||
|
.bladerunner .cur { color: #6c8497; }
|
||||||
|
|
||||||
|
/* Blade Runner: subtle glow for SVG icons inside hash links on hover/focus */
|
||||||
|
.bladerunner .hashLink:hover .icon,
|
||||||
|
.bladerunner .hashLink:focus .icon,
|
||||||
|
.bladerunner .hashLink:hover svg,
|
||||||
|
.bladerunner .hashLink:focus svg {
|
||||||
|
filter: drop-shadow(0 0 2px currentColor);
|
||||||
|
}
|
||||||
|
/* Blade Runner: neon hover glow for top-links controls */
|
||||||
|
.bladerunner .top-links a, .bladerunner .top-links a:visited { color: #dce7f5 }
|
||||||
|
.bladerunner .top-links button { color: #dce7f5 }
|
||||||
|
|
||||||
|
.bladerunner .top-links a:hover,
|
||||||
|
.bladerunner .top-links a:focus,
|
||||||
|
.bladerunner .top-links button:hover,
|
||||||
|
.bladerunner .top-links button:focus {
|
||||||
|
/* very dim magenta glow */
|
||||||
|
text-shadow:0 0 2px rgb(229, 33, 0.5);
|
||||||
|
color: #FFBF00;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Blade Runner: add matching glow to SVG icons inside top-links on hover/focus */
|
||||||
|
.bladerunner .top-links a:hover .icon,
|
||||||
|
.bladerunner .top-links a:focus .icon,
|
||||||
|
.bladerunner .top-links button:hover .icon,
|
||||||
|
.bladerunner .top-links button:focus .icon,
|
||||||
|
.bladerunner .top-links a:hover svg,
|
||||||
|
.bladerunner .top-links a:focus svg,
|
||||||
|
.bladerunner .top-links button:hover svg,
|
||||||
|
.bladerunner .top-links button:focus svg {
|
||||||
|
color: amber !important;
|
||||||
|
filter: drop-shadow(0 0 2px rgba(255, 127, 176, 0.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
.bladerunner .bladerunner-easter-egg {display: none;}
|
||||||
|
|
||||||
|
.bladerunner-easter-egg {
|
||||||
|
position: absolute;
|
||||||
|
right: 1em;
|
||||||
|
bottom: 1em;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bladerunner-easter-egg:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
button {
|
button {
|
||||||
border: none;
|
border: none;
|
||||||
@@ -185,8 +340,25 @@ button {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
button:focus {outline:0;}
|
button:focus {outline:0;}
|
||||||
|
|
||||||
|
/* Remove blue focus ring from the Blade Runner easter egg button */
|
||||||
|
.bladerunner-easter-egg button:focus,
|
||||||
|
.bladerunner-easter-egg button:focus-visible {
|
||||||
|
outline: none !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Anchor the Blade Runner easter egg to bottom-right regardless of scrolling */
|
||||||
|
.bladerunner-easter-egg {
|
||||||
|
position: fixed;
|
||||||
|
right: 20px;
|
||||||
|
bottom: 20px;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
/* Top Links Shrink */
|
/* Top Links Shrink */
|
||||||
@media (max-width: 800px) {
|
@media (max-width: 800px) {
|
||||||
.top-links .link-text { display: none }
|
.top-links .link-text { display: none }
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ export type PersistedAppData = {
|
|||||||
donationClicked: boolean;
|
donationClicked: boolean;
|
||||||
annotateTypes: boolean;
|
annotateTypes: boolean;
|
||||||
dimExtrBits: boolean;
|
dimExtrBits: boolean;
|
||||||
cookieDisclaimerHidden: boolean
|
cookieDisclaimerHidden: boolean,
|
||||||
|
centeredLayout?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CommandResultView = {
|
export type CommandResultView = {
|
||||||
@@ -41,6 +42,7 @@ export default class AppState {
|
|||||||
annotateTypes: boolean = false;
|
annotateTypes: boolean = false;
|
||||||
dimExtraBits: boolean = false;
|
dimExtraBits: boolean = false;
|
||||||
cookieDisclaimerHidden: boolean = false;
|
cookieDisclaimerHidden: boolean = false;
|
||||||
|
centeredLayout: boolean = true;
|
||||||
|
|
||||||
constructor(persistData: PersistedAppData, env: string) {
|
constructor(persistData: PersistedAppData, env: string) {
|
||||||
|
|
||||||
@@ -56,6 +58,7 @@ export default class AppState {
|
|||||||
this.annotateTypes = !!persistData.annotateTypes;
|
this.annotateTypes = !!persistData.annotateTypes;
|
||||||
this.dimExtraBits = !!persistData.dimExtrBits;
|
this.dimExtraBits = !!persistData.dimExtrBits;
|
||||||
this.cookieDisclaimerHidden = !!persistData.cookieDisclaimerHidden
|
this.cookieDisclaimerHidden = !!persistData.cookieDisclaimerHidden
|
||||||
|
this.centeredLayout = (persistData.centeredLayout === undefined) ? true : !!persistData.centeredLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
addCommandResult(input: string, view: ViewFactory) {
|
addCommandResult(input: string, view: ViewFactory) {
|
||||||
@@ -93,7 +96,7 @@ export default class AppState {
|
|||||||
|
|
||||||
setUiTheme(theme: string) {
|
setUiTheme(theme: string) {
|
||||||
this.uiTheme = theme;
|
this.uiTheme = theme;
|
||||||
this.triggerChanged();
|
this.triggerChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleDebugMode() {
|
toggleDebugMode() {
|
||||||
@@ -116,6 +119,11 @@ export default class AppState {
|
|||||||
this.triggerChanged();
|
this.triggerChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleCenteredLayout(value?: boolean) {
|
||||||
|
this.centeredLayout = value !== null && value !== undefined ? value : !this.centeredLayout;
|
||||||
|
this.triggerChanged();
|
||||||
|
}
|
||||||
|
|
||||||
registerVisit() {
|
registerVisit() {
|
||||||
this.pageVisitsCount++;
|
this.pageVisitsCount++;
|
||||||
this.triggerChanged();
|
this.triggerChanged();
|
||||||
@@ -144,11 +152,12 @@ export default class AppState {
|
|||||||
donationClicked: this.donationClicked,
|
donationClicked: this.donationClicked,
|
||||||
annotateTypes: this.annotateTypes,
|
annotateTypes: this.annotateTypes,
|
||||||
dimExtrBits: this.dimExtraBits,
|
dimExtrBits: this.dimExtraBits,
|
||||||
cookieDisclaimerHidden: this.cookieDisclaimerHidden
|
cookieDisclaimerHidden: this.cookieDisclaimerHidden,
|
||||||
|
centeredLayout: this.centeredLayout
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function generateKey(): number {
|
function generateKey(): number {
|
||||||
return Math.ceil(Math.random() * 10000000) ^ Date.now(); // Because why the hell not...
|
return Math.ceil(Math.random() * 10000000) ^ Date.now(); // Because why the hell not...
|
||||||
}
|
}
|
||||||
|
|||||||
80
src/shell/Bladerunner.ts
Normal file
80
src/shell/Bladerunner.ts
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
import AppState from "./AppState";
|
||||||
|
import log from 'loglevel';
|
||||||
|
|
||||||
|
const LIGHTS_ON_KEY = 'lightsOn';
|
||||||
|
const LIGHTS_ON_CLASS = 'lights-on';
|
||||||
|
|
||||||
|
const turnLightsOff = (): void => (getHeader()).classList.remove('lights-on')
|
||||||
|
const getLightIsOn = () : boolean => localStorage.getItem(LIGHTS_ON_KEY) !== 'false';
|
||||||
|
const setLightIsOn = (value: boolean) => localStorage.setItem(LIGHTS_ON_KEY, value.toString());
|
||||||
|
const getHeader = (): HTMLHeadElement => document.querySelector('.header h1')!;
|
||||||
|
|
||||||
|
const toggleLights = (): void => {
|
||||||
|
const header = getHeader();
|
||||||
|
|
||||||
|
const lightIsOn = header.classList.contains(LIGHTS_ON_CLASS);
|
||||||
|
|
||||||
|
setLightIsOn(!lightIsOn);
|
||||||
|
|
||||||
|
if (lightIsOn)
|
||||||
|
turnLightsOff();
|
||||||
|
else
|
||||||
|
turnLightsOnWithFlickering();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const turnLightsOnWithFlickering = (): void => {
|
||||||
|
const header = getHeader();
|
||||||
|
const flickers = [true, false, true, false, true, false, true];
|
||||||
|
|
||||||
|
log.info("Turning lights on with flickering");
|
||||||
|
|
||||||
|
flickers.forEach((flicker, index) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (flicker)
|
||||||
|
header.classList.add(LIGHTS_ON_CLASS);
|
||||||
|
else
|
||||||
|
header.classList.remove(LIGHTS_ON_CLASS);
|
||||||
|
}, index * 100);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const startLightsIfWereOnAfterDelay = (): void => {
|
||||||
|
if (getLightIsOn())
|
||||||
|
setTimeout(turnLightsOnWithFlickering, 500);
|
||||||
|
else
|
||||||
|
log.info("Lights are off by user preference");
|
||||||
|
};
|
||||||
|
|
||||||
|
const addStateListener = (appState: AppState) => {
|
||||||
|
|
||||||
|
var oldTheme = appState.uiTheme;
|
||||||
|
|
||||||
|
appState.onChange(() => {
|
||||||
|
|
||||||
|
log.info("App state changed, checking for lights theme. Current theme: " + appState.uiTheme + ", old theme: " + oldTheme);
|
||||||
|
|
||||||
|
if(appState.uiTheme === 'bladerunner' && oldTheme !== 'bladerunner') {
|
||||||
|
log.info("Starting lights because bladerunner theme is active");
|
||||||
|
startLightsIfWereOnAfterDelay();
|
||||||
|
}
|
||||||
|
else if(oldTheme === "bladerunner" && appState.uiTheme !== 'bladerunner') {
|
||||||
|
turnLightsOff();
|
||||||
|
}
|
||||||
|
|
||||||
|
oldTheme = appState.uiTheme;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const start = (appState: AppState): void => {
|
||||||
|
|
||||||
|
if(appState.uiTheme === 'bladerunner')
|
||||||
|
startLightsIfWereOnAfterDelay();
|
||||||
|
else
|
||||||
|
turnLightsOff();
|
||||||
|
|
||||||
|
addStateListener(appState);
|
||||||
|
};
|
||||||
|
|
||||||
|
const BladerunnerApi = { start, toggleLights };
|
||||||
|
export default BladerunnerApi;
|
||||||
@@ -11,7 +11,8 @@ const DEFAULT_DATA : PersistedAppData = {
|
|||||||
donationClicked: false,
|
donationClicked: false,
|
||||||
annotateTypes: false,
|
annotateTypes: false,
|
||||||
dimExtrBits: false,
|
dimExtrBits: false,
|
||||||
cookieDisclaimerHidden: false
|
cookieDisclaimerHidden: false,
|
||||||
|
centeredLayout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
const appStateStore = {
|
const appStateStore = {
|
||||||
@@ -39,4 +40,4 @@ const appStateStore = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default appStateStore;
|
export default appStateStore;
|
||||||
|
|||||||
@@ -7,9 +7,10 @@ import DebugIndicators from './DebugIndicators';
|
|||||||
import hash from '../../core/hash';
|
import hash from '../../core/hash';
|
||||||
import TopLinks from './TopLinks';
|
import TopLinks from './TopLinks';
|
||||||
import SettingsPane from './SettingsPane';
|
import SettingsPane from './SettingsPane';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import CommandLink from '../../core/components/CommandLink';
|
||||||
import { faGear } from '@fortawesome/free-solid-svg-icons';
|
import { faGear, faPersonRunning } from '@fortawesome/free-solid-svg-icons';
|
||||||
import CookieDisclaimerFooter from './CookieDisclaimerFooter';
|
import CookieDisclaimerFooter from './CookieDisclaimerFooter';
|
||||||
|
import bladerunner from '../Bladerunner';
|
||||||
|
|
||||||
|
|
||||||
type AppRootProps = {
|
type AppRootProps = {
|
||||||
@@ -19,7 +20,8 @@ type AppRootProps = {
|
|||||||
type AppRootState = {
|
type AppRootState = {
|
||||||
uiTheme: string,
|
uiTheme: string,
|
||||||
emphasizeBytes: boolean,
|
emphasizeBytes: boolean,
|
||||||
commandResults: CommandResultView[]
|
commandResults: CommandResultView[],
|
||||||
|
centeredLayout: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class AppRoot extends React.Component<AppRootProps, AppRootState> {
|
export default class AppRoot extends React.Component<AppRootProps, AppRootState> {
|
||||||
@@ -46,33 +48,48 @@ export default class AppRoot extends React.Component<AppRootProps, AppRootState>
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount(): void {
|
||||||
|
bladerunner.start(this.props.appState);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
const enableNewUi = this.props.appState.env !== 'prod' || true;
|
const enableNewUi = this.props.appState.env !== 'prod' || true;
|
||||||
const newUi = enableNewUi ? 'new-ui' : '';
|
const newUi = enableNewUi ? 'new-ui' : '';
|
||||||
const settingsCss = "settings-button" + (this.props.appState.showSettings ? '' : ' soft');
|
const settingsCss = "settings-button" + (this.props.appState.showSettings ? '' : ' soft');
|
||||||
|
|
||||||
return <div className={`app-root ${this.state.uiTheme} ${newUi}`}>
|
const layoutClass = this.state.centeredLayout ? 'layout-centered' : 'layout-stretched';
|
||||||
<DebugIndicators appState={this.props.appState} />
|
return <div className={`app-root ${this.state.uiTheme} ${newUi} ${layoutClass}`}>
|
||||||
<div className="header">
|
<div className="header-pane">
|
||||||
<h1>Bitwise<span className="header-cmd">Cmd</span>
|
<DebugIndicators appState={this.props.appState} />
|
||||||
</h1>
|
<div className="header">
|
||||||
<TopLinks />
|
<h1 onClick={() => bladerunner.toggleLights()}>
|
||||||
</div>
|
Bitwise<span className="header-cmd">Cmd</span>
|
||||||
|
</h1>
|
||||||
|
<TopLinks />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="expressionInput-container">
|
<div className="expressionInput-container">
|
||||||
<InputBox onCommandEntered={(input) => cmd.execute(input)} />
|
<InputBox onCommandEntered={(input) => cmd.execute(input)} />
|
||||||
|
|
||||||
<button className={settingsCss} title='Toggle Settings' type="button" onClick={() => this.props.appState.toggleShowSettings()}>
|
<span className={settingsCss}>
|
||||||
<FontAwesomeIcon icon={faGear} />
|
<CommandLink text="" command='settings' icon={faGear} />
|
||||||
</button>
|
</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{this.props.appState.showSettings ? <SettingsPane appState={this.props.appState} /> : null}
|
<div className="content-pane">
|
||||||
<div id="output">
|
{this.props.appState.showSettings ? <SettingsPane appState={this.props.appState} /> : null}
|
||||||
{this.getResultViews()}
|
<div id="output">
|
||||||
|
{this.getResultViews()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<CookieDisclaimerFooter appState={this.props.appState} />
|
||||||
|
<div className="bladerunner-easter-egg">
|
||||||
|
<CommandLink text="" command='bladerunner-easter' icon={faPersonRunning} />
|
||||||
</div>
|
</div>
|
||||||
<CookieDisclaimerFooter appSate={this.props.appState} />
|
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ import React from "react";
|
|||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faCaretDown, faCaretUp, faCircleXmark } from "@fortawesome/free-solid-svg-icons";
|
import { faCaretDown, faCaretUp, faCircleXmark } from "@fortawesome/free-solid-svg-icons";
|
||||||
|
|
||||||
function CookieDisclaimerFooter(props: { appSate: AppState }): JSX.Element {
|
function CookieDisclaimerFooter(props: { appState: AppState }): JSX.Element {
|
||||||
|
|
||||||
const [expanded, setShowMore] = useState(false);
|
const [expanded, setShowMore] = useState(false);
|
||||||
const longCss = expanded ? " expanded" : " collapsed";
|
const longCss = expanded ? " expanded" : " collapsed";
|
||||||
const shortCss = expanded ? " collapsed" : " expanded";
|
const shortCss = expanded ? " collapsed" : " expanded";
|
||||||
const buttonText = expanded ? "Read Less" : "Read More";
|
const buttonText = expanded ? "Read Less" : "Read More";
|
||||||
|
|
||||||
if (props.appSate.cookieDisclaimerHidden)
|
if (props.appState.cookieDisclaimerHidden)
|
||||||
return <React.Fragment></React.Fragment>;
|
return <React.Fragment></React.Fragment>;
|
||||||
|
|
||||||
return <div className="cookie-disclaimer">
|
return <div className="cookie-disclaimer">
|
||||||
@@ -34,10 +34,10 @@ function CookieDisclaimerFooter(props: { appSate: AppState }): JSX.Element {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
<button className="button" onClick={() => setShowMore(!expanded)}><FontAwesomeIcon icon={expanded ? faCaretDown : faCaretUp} />{buttonText}</button> <button className="button" onClick={() => props.appSate.setCookieDisclaimerHidden(true)}><FontAwesomeIcon icon={faCircleXmark} />Hide</button>
|
<button className="button" onClick={() => setShowMore(!expanded)}><FontAwesomeIcon icon={expanded ? faCaretDown : faCaretUp} />{buttonText}</button> <button className="button" onClick={() => props.appState.setCookieDisclaimerHidden(true)}><FontAwesomeIcon icon={faCircleXmark} />Hide</button>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CookieDisclaimerFooter;
|
export default CookieDisclaimerFooter;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
.help ul { list-style-type: none; margin: 0; margin-left: 10px; margin-top: 0.2em; padding: 0; }
|
.help ul { list-style-type: none; margin: 0; margin-left: 10px; margin-top: 0.2em; padding: 0; }
|
||||||
.help li { padding: 1px; margin-bottom: 5px;}
|
.help li { padding: 1px; margin-bottom: 5px;}
|
||||||
.help code, .help code a { color:mediumseagreen}
|
|
||||||
.light .help code, .light .help code a { color:green}
|
.light .help code, .light .help code a { color:green}
|
||||||
.help p { margin-top: 0.5em }
|
.help p { margin-top: 0.5em }
|
||||||
.help .section {padding: 1em;}
|
.help .section {padding: 1em;}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ function HelpResultView() {
|
|||||||
<ul>
|
<ul>
|
||||||
<li><code><CommandLink text="light" /></code> — set the Light color theme</li>
|
<li><code><CommandLink text="light" /></code> — set the Light color theme</li>
|
||||||
<li><code><CommandLink text="dark" /></code> — set the Dark color theme</li>
|
<li><code><CommandLink text="dark" /></code> — set the Dark color theme</li>
|
||||||
<li><code><CommandLink text="midnight" /></code> — set the Midnight color theme</li>
|
<li><code><CommandLink text="midnight" /></code> — set the Midnight color theme</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className="section">
|
<div className="section">
|
||||||
@@ -63,7 +63,7 @@ function HelpResultView() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="section soft-border">
|
<div className="section soft-border">
|
||||||
<div className="section-title soft">Supported Number Types <sup className='accent1'>NEW</sup></div>
|
<div className="section-title soft">Supported Number Types</div>
|
||||||
<p>
|
<p>
|
||||||
BitiwseCmd no longer uses the browser's JavaScript engine for the execution of bitwise operations. It has its own calculator implementation which brings supports bitwise operations on the following <i>signed</i> and <i>unsigned</i> data types:
|
BitiwseCmd no longer uses the browser's JavaScript engine for the execution of bitwise operations. It has its own calculator implementation which brings supports bitwise operations on the following <i>signed</i> and <i>unsigned</i> data types:
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -31,4 +31,8 @@
|
|||||||
|
|
||||||
.settings-container .setting {
|
.settings-container .setting {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
/* Theme-specific overrides belong in src/index.css per AGENTS.md */
|
||||||
|
/* Ensure Settings aligns with centered layout */
|
||||||
|
.app-root.layout-centered #settings.settings-container { display: block; }
|
||||||
|
|
||||||
|
|||||||
@@ -44,8 +44,18 @@ function SettingsPane(props : SettingsPaneProps) {
|
|||||||
: "Information about the size of integers is hidden."}
|
: "Information about the size of integers is hidden."}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div className='setting'>
|
||||||
|
<button type="button" onClick={() => appState.toggleCenteredLayout()}>
|
||||||
|
<FontAwesomeIcon size='xl' icon={appState.centeredLayout ? faToggleOn : faToggleOff} /> Centered Layout
|
||||||
|
</button>
|
||||||
|
<p className='description'>
|
||||||
|
{appState.centeredLayout
|
||||||
|
? "Content is centered with wide side margins on large screens."
|
||||||
|
: "Content stretches to full width as before."}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SettingsPane;
|
export default SettingsPane;
|
||||||
|
|||||||
@@ -2,81 +2,90 @@ import React from 'react';
|
|||||||
import CommandLink from '../../core/components/CommandLink';
|
import CommandLink from '../../core/components/CommandLink';
|
||||||
import './WhatsNewResultView.css';
|
import './WhatsNewResultView.css';
|
||||||
|
|
||||||
function WhatsnewResultView() {
|
function WhatsNewResultView() {
|
||||||
|
|
||||||
return <div className="changelog">
|
return <div className="changelog">
|
||||||
<h3>Changelog</h3>
|
<h3>Changelog</h3>
|
||||||
<div className='item item-new'>
|
<div className='item item-new'>
|
||||||
<p>
|
<p>
|
||||||
<span className="soft date">May 10th, 2023</span> <br/>
|
<span className="soft date">Nov 6th, 2025</span> <br />
|
||||||
<p>
|
</p>
|
||||||
Behold! After a long time of inactivity, BitwiseCmd is getting an update. Here is what changed:
|
<ul>
|
||||||
</p>
|
<li>Introduced a Centered Layout option that centers content on wide monitors; you can revert to the stretched layout in <CommandLink text="settings" />.</li>
|
||||||
<ul>
|
</ul>
|
||||||
<li>Browser's JavaScript engine is no longer used for the execution of bitwise operations.
|
</div>
|
||||||
BitwiseCmd has its own shiny custom-built bitwise calculator that supports operations integer of different sizes (8,16,32, and 64 bits) as well as their signed and unsigned versions. <CommandLink text='Check it out!' command='-1b 255ub -1 4294967295u -1l 18446744073709551615u' />.
|
<div className='item'>
|
||||||
This calculator tries to follow the same behavior of bitwise operations as implemented in C.
|
<p>
|
||||||
This includes shifting an integer by the number of bytes equal to its size (spoiler: you get the same number, this is undefined behavior in C. Don't believe me? Check this <a href="https://codeyarns.com/tech/2004-12-20-c-shift-operator-mayhem.html#gsc.tab=0">link</a>).</li>
|
<span className="soft date">May 10th, 2023</span> <br />
|
||||||
<li>A slightly improved UI</li>
|
<p>
|
||||||
</ul>
|
Behold! After a long time of inactivity, BitwiseCmd is getting an update. Here is what changed:
|
||||||
<p>I'm sure there will be some bugs following such a big update. I will do my best to fix them as they are found.</p>
|
</p>
|
||||||
<p>Many thanks to all people that submitted issues on GitHub. Your feedback is greatly appreciated. </p>
|
<ul>
|
||||||
</p>
|
<li>The browser's JavaScript engine is no longer used for executing bitwise operations.
|
||||||
</div>
|
BitwiseCmd now has its own shiny, custom-built bitwise calculator that supports bitwise operations on integers of different sizes (8, 16, 32, and 64 bits), in both signed and unsigned variants. <CommandLink text='Check it out!' command='-1b 255ub -1 4294967295u -1l 18446744073709551615u' />
|
||||||
<div className='item'>
|
This calculator follows the behavior of bitwise operations as implemented in C, including edge cases.
|
||||||
<span className="soft date">May 5th, 2023</span> <br/>
|
For example, shifting an integer by a number of bits equal to its width is undefined behavior in C (see this <a href="https://codeyarns.com/tech/2004-12-20-c-shift-operator-mayhem.html#gsc.tab=0">link</a>).
|
||||||
<p>
|
</li>
|
||||||
Fixed <a href="https://github.com/BorysLevytskyi/BitwiseCmd/issues/13">bug</a> with incorrect binary representation of 64-bit numbers.
|
<li>A slightly improved UI</li>
|
||||||
</p>
|
</ul>
|
||||||
</div>
|
<p>I'm sure there will be some bugs following such a big update. I will do my best to fix them as they are found.</p>
|
||||||
<div className="item">
|
<p>Many thanks to everyone who submitted issues on GitHub. Your feedback is greatly appreciated.</p>
|
||||||
<p><span className="soft date">Jul 24th, 2021</span> <br/>
|
</p>
|
||||||
<ul>
|
</div>
|
||||||
<li>Added support of <code>vpc</code> command to see how VPC network address is divided between VPC, Subnets, and Hosts. Try it out: <CommandLink text="vpc 192.168.24.1/24" /></li>
|
<div className='item'>
|
||||||
<li>Added ability to remove individual results</li>
|
<span className="soft date">May 5th, 2023</span> <br />
|
||||||
</ul>
|
<p>
|
||||||
</p>
|
Fixed a <a href="https://github.com/BorysLevytskyi/BitwiseCmd/issues/13">bug</a> with the binary representation of 64-bit numbers.
|
||||||
</div>
|
</p>
|
||||||
<div className="item">
|
</div>
|
||||||
<span className="soft date">Jun 16th, 2021</span>
|
<div className="item">
|
||||||
<p>
|
<p><span className="soft date">Jul 24th, 2021</span> <br />
|
||||||
Added support of <code>subnet</code> command to display information about subnet IP address such. Try it out: <CommandLink text="subnet 192.168.24.1/14" />
|
<ul>
|
||||||
</p>
|
<li>Added support for the <code>vpc</code> command to see how the VPC network address bits are divided between the VPC, subnets, and hosts. Try it out: <CommandLink text="vpc 192.168.24.1/24" /></li>
|
||||||
</div>
|
<li>Added the ability to remove individual results</li>
|
||||||
<div className="item">
|
</ul>
|
||||||
<span className="soft date">Jun 14th, 2021</span>
|
</p>
|
||||||
<p>
|
</div>
|
||||||
Added support of IP addresses and subnet mask notations. Try them out:
|
<div className="item">
|
||||||
</p>
|
<span className="soft date">Jun 16th, 2021</span>
|
||||||
<ul>
|
<p>
|
||||||
<li>A single IP address <CommandLink text="127.0.0.1" /></li>
|
Added support for the <code>subnet</code> command to display subnet information (network address, broadcast address, etc.). Try it out: <CommandLink text="subnet 192.168.24.1/14" />
|
||||||
<li>Multiple IP addresses and subnet mask notations <CommandLink text="127.0.0.1 192.168.0.0/24" /></li>
|
</p>
|
||||||
</ul>
|
</div>
|
||||||
|
<div className="item">
|
||||||
</div>
|
<span className="soft date">Jun 14th, 2021</span>
|
||||||
<div className="item">
|
<p>
|
||||||
<span className="soft date">Jun 6th, 2017</span>
|
Added support for IP addresses and subnet mask notation. Try them out:
|
||||||
<p>
|
</p>
|
||||||
Added <code><CommandLink text="guid" /></code> command. Use it for generating v4 GUIDs </p>
|
<ul>
|
||||||
</div>
|
<li>A single IP address <CommandLink text="127.0.0.1" /></li>
|
||||||
<div className="item">
|
<li>Multiple IP addresses and subnet mask notations <CommandLink text="127.0.0.1 192.168.0.0/24" /></li>
|
||||||
<span className="soft date">May 27th, 2017</span>
|
</ul>
|
||||||
<p>
|
|
||||||
Added support of binary number notation (e.g. <code><CommandLink text="0b10101" /></code>). </p>
|
</div>
|
||||||
</div>
|
<div className="item">
|
||||||
<div className="item">
|
<span className="soft date">Jun 6th, 2017</span>
|
||||||
<span className="soft">May 20th, 2017</span>
|
<p>
|
||||||
<p>
|
Added the <code><CommandLink text="guid" /></code> command. Use it to generate v4 GUIDs.</p>
|
||||||
A new <CommandLink text="Midnight" /> theme was added.
|
</div>
|
||||||
</p>
|
<div className="item">
|
||||||
</div>
|
<span className="soft date">May 27th, 2017</span>
|
||||||
<div className="item">
|
<p>
|
||||||
<span className="soft">May 16th, 2017</span>
|
Added support of binary number notation (e.g. <code><CommandLink text="0b10101" /></code>). </p>
|
||||||
<p>
|
</div>
|
||||||
Complete rewrite using React. Please let me know if you have problems with this release by <a href="https://github.com/BorysLevytskyi/BitwiseCmd/issues">creating an issue</a> in Github Repo.
|
<div className="item">
|
||||||
</p>
|
<span className="soft">May 20th, 2017</span>
|
||||||
</div>
|
<p>
|
||||||
</div>;
|
A new <CommandLink text="Midnight" /> theme was added.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="item">
|
||||||
|
<span className="soft">May 16th, 2017</span>
|
||||||
|
<p>
|
||||||
|
Complete rewrite using React. Please let me know if you have problems with this release by <a href="https://github.com/BorysLevytskyi/BitwiseCmd/issues">creating an issue</a> in Github Repo.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default WhatsnewResultView;
|
export default WhatsNewResultView;
|
||||||
|
|||||||
@@ -24,6 +24,16 @@ const shellModule = {
|
|||||||
cmd.command("dark", () => appState.setUiTheme('dark'));
|
cmd.command("dark", () => appState.setUiTheme('dark'));
|
||||||
cmd.command("light", () => appState.setUiTheme('light'));
|
cmd.command("light", () => appState.setUiTheme('light'));
|
||||||
cmd.command("midnight", () => appState.setUiTheme('midnight'));
|
cmd.command("midnight", () => appState.setUiTheme('midnight'));
|
||||||
|
cmd.command("settings", () => appState.toggleShowSettings());
|
||||||
|
cmd.command("bladerunner", () => {
|
||||||
|
appState.setUiTheme('bladerunner');
|
||||||
|
sendAnalyticsEvent({eventCategory: "UI", eventAction: "ThemeChanged", eventLabel: "bladerunner"});
|
||||||
|
});
|
||||||
|
cmd.command("bladerunner-easter", (c: CommandInput) => {
|
||||||
|
document.querySelector('.app-root')!.scrollTo(0, 0);
|
||||||
|
cmd.execute("bladerunner");
|
||||||
|
appState.addCommandResult(c.input, () => <TextResultView text="You've discovered the hidden Blade Runner theme. Next time, to activate this theme, use the command 'bladerunner'." />);
|
||||||
|
});
|
||||||
cmd.command("about", (c: CommandInput) => appState.addCommandResult(c.input, () => <AboutResultView />));
|
cmd.command("about", (c: CommandInput) => appState.addCommandResult(c.input, () => <AboutResultView />));
|
||||||
cmd.command("whatsnew", (c: CommandInput) => appState.addCommandResult(c.input, () => <WhatsnewResultView />));
|
cmd.command("whatsnew", (c: CommandInput) => appState.addCommandResult(c.input, () => <WhatsnewResultView />));
|
||||||
cmd.command("guid", (c: CommandInput) => appState.addCommandResult(c.input, () => <TextResultView text={uuid()} />));
|
cmd.command("guid", (c: CommandInput) => appState.addCommandResult(c.input, () => <TextResultView text={uuid()} />));
|
||||||
@@ -92,4 +102,6 @@ const shellModule = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default shellModule;
|
export default shellModule;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user