diff options
Diffstat (limited to 'moneyjsx')
395 files changed, 5845 insertions, 0 deletions
diff --git a/moneyjsx/package.json b/moneyjsx/package.json new file mode 100644 index 0000000..4418f02 --- /dev/null +++ b/moneyjsx/package.json @@ -0,0 +1,32 @@ +{ + "type": "module", + "name": "jqueryjsx", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "build": "webpack --config webpack-prod.config.cjs", + "start": "webpack serve --open --config webpack-dev.config.cjs" + }, + "author": "", + "license": "ISC", + "description": "", + "dependencies": { + "@types/jquery": "^3.5.32", + "@types/react": "^18.3.12", + "copy-webpack-plugin": "^12.0.2", + "css-loader": "^7.1.2", + "highlight.js": "^11.11.1", + "html-webpack-plugin": "^5.6.3", + "jquery": "^4.0.0-beta.2", + "jsx-runtime": "^1.2.0", + "nakedjsx": "^0.17.2", + "style-loader": "^4.0.0", + "typescript": "^5.6.3" + }, + "devDependencies": { + "ts-loader": "^9.5.1", + "webpack": "^5.95.0", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^5.1.0" + } +} diff --git a/moneyjsx/src/api.tsx b/moneyjsx/src/api.tsx new file mode 100644 index 0000000..4ca79c2 --- /dev/null +++ b/moneyjsx/src/api.tsx @@ -0,0 +1,80 @@ +// todo: change this +export const url = "https://api.axonbox.net"; +export let models: Model[] = []; + +export interface ReqParams { + method: string, + body?: string, +} + +export interface Model { + name: string, + capabilities: any, + description: { + full: string, + short: string, + }, + license: string, + free: number +} + +export async function post( endpoint: string, body: Object ) { + return await req( endpoint, { + method: "POST", + body: JSON.stringify( body ), + } ); +} + +export async function req( endpoint: string, params: ReqParams ) { + const res = await fetch( `${url}/${endpoint}`, { + method: params.method, + headers: { + "Content-Type": "application/json", + }, + body: params.body, + } ); + + if( !res.ok ) { + let json = null; + try { + json = await res.json(); + } catch( e: any ) { + throw new Error( "error contacting server" ); + } + + throw new Error( json.msg ); + } + + const json = await res.json(); + if( json.status != 'ok' ) + throw new Error( json.msg ); + return json; +} + +export async function updateModels() { + parseModels(); + + try { + const res = await post( 'models', {} ); + models = res.models as Model[]; + localStorage.setItem( 'models', JSON.stringify( models ) ); + } catch( e: any ) { + throw new Error( e.message ); + } +} + +export function getModelFromName( name: string ) { + for( let model of models ) { + if( model.name === name ) + return model; + } + + return null; +} + +/** + * parses existing models from localStorage +**/ +export function parseModels() { + models = JSON.parse( localStorage.getItem( 'models' ) || '[]' ) as Model[]; +} diff --git a/moneyjsx/src/ascii-art.tsx b/moneyjsx/src/ascii-art.tsx new file mode 100644 index 0000000..d2f53b3 --- /dev/null +++ b/moneyjsx/src/ascii-art.tsx @@ -0,0 +1,165 @@ +import * as JSX from "./jsx"; +import $ from "jquery"; + +export default function AsciiArt() { + const ret = <div id="ascii-art"> + { asciiArtStr } + </div>; + + setTimeout( doAsciiArt ); + return ret; +} + +let startTime = 0.0; +let anim = 0.0; + +function animFunc( a: number ) { + let ringRadius = anim; + let radius = a; + + let dist = ringRadius - radius; + + dist = Math.abs( dist ); + + let ret = Math.pow( dist, 0.1 + 0.8 * Math.pow( (anim + 0.5) / 2, 1.6 ) ); + let remain = ret % 0.12; + return ret - remain; +} + +function hexToRgb( hex: string ) { + let r = parseInt( hex.slice( 1, 3 ), 16 ); + let g = parseInt( hex.slice( 3, 5 ), 16 ); + let b = parseInt( hex.slice( 5, 7 ), 16 ); + return [ r, g, b ]; +} + +function lerpColor( c1: number[], c2: number[], t: number ) { + let r1 = c1[0], g1 = c1[1], b1 = c1[2]; + let r2 = c2[0], g2 = c2[1], b2 = c2[2]; + let r = r1 + ( r2 - r1 ) * t; + let g = g1 + ( g2 - g1 ) * t; + let b = b1 + ( b2 - b1 ) * t; + return [ Math.round( r ), Math.round( g ), Math.round( b ) ]; +} + +function getDist( x: number, y: number ) { + const x1 = 0.5 - x / 125; + const y1 = 0.5 - y / 63; + return Math.sqrt( x1 * x1 + y1 * y1 ); +} + +let isDoingAnim = false; +function doAsciiArt() { + let div = $( "#ascii-art" ); + if( !div.length ) { isDoingAnim = false; return; } + isDoingAnim = true; + + let deltaTime = ( Date.now() - startTime ) * 0.001; + startTime = Date.now(); + anim += .5 * deltaTime; + + if( anim > 2 ) + anim = -0.5; + + let rootColor = hexToRgb( $( ':root' ).css( '--front' ) ); + let innerStr = ""; + for( let i = 0; i < asciiArtStr.length; ++i ) { + let x = i % 125; + let y = Math.floor( i / 125 ); + + if( x == 124 ) { + continue; + } + if( asciiArtStr[i] == ',' || asciiArtStr[i] == ' ' || asciiArtStr[i] == '\t' ) { + innerStr += asciiArtStr[i]; + continue; + } + + let dist = getDist( x, y ); + if( dist < 0.133 ) { + innerStr += asciiArtStr[i]; + continue; + } + + let color = []; + if( asciiArtStr[i] == '#' ) { + let a = animFunc( dist * 2 ); + color = lerpColor( rootColor, [255, 255, 255, 1], a ); + color[3] = Math.max( Math.min( 1, Math.pow( dist, 2 ) + (1.0 - a) ), 0.8 ); + } + else { + color = [255, 255, 255, Math.max( 0.05, 1.0 - animFunc( (dist - 0.1) * 2 ) ) ]; + } + // appending string is faster than jsx + innerStr += `<span style='color: rgba(${color[0]}, ${color[1]}, ${color[2]}, ${color[3]})'>${asciiArtStr[i]}</span>`; + } + + div.html( innerStr ); + setTimeout( doAsciiArt, 75 ); +} + +const asciiArtStr = ` + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # .. # # + # # .. # # + # # .### ### + # # ### ### .. + # # # # .... + # # # # .... + # # # # .. + # # # # + # # # # + .. ############################################## + ................................... ###.. ### ........... ### .........### + .................................. ####+############################################ + #######################################+# #.# + #####-# #.# + #################################### # # #.# + # # #.# + ######################################### #.#...................................... + ### #.#...............--..................... + ######################################### | ##################.###################### + # # ,---.. ,,---.,---.|---.,---.. , ### ### ###... + ################ ,---| >< | || || || | >< ################ ### #################### + ########################### .. ### \`---^' \`\`---'\` '\`---'\`---'' \` #.# ... ### ### + ################## #.# ... ####### + ######################### ... # # #.# . ################## + ############################. #.# #.# # # .............. + ###- #.# #-########################............... + ############################- # # #+# ...###...... ...... + .........................##############-# #-########################.... .. + .........................###. #-# #.# ....................... + ..............+########################################################## ...................... + .................###................... ### ### ...### .......... + .............. ############################################## + ....# #..... # # + ... ... # # # # + ................ # # # # + .................. # # # # + .......################## # # . + .....###### ### # # + ####+###################. # # + ######+ .............. # # + # # ................. # # + # # ...... # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # +`; diff --git a/moneyjsx/src/chat.tsx b/moneyjsx/src/chat.tsx new file mode 100644 index 0000000..56798ab --- /dev/null +++ b/moneyjsx/src/chat.tsx @@ -0,0 +1,1023 @@ +import $ from 'jquery'; +import * as JSX from './jsx'; +import * as api from './api'; +import * as user from './user'; +import * as util from './util'; + +import { Spinner, OkCancelPopup, addPopup, OkPopup } from './components'; + +let chat_id = ''; +let chat_name = 'new chat'; // todo: use or rm +export let msglog: Msg[] = []; +export let file_list: MsgFile[] = []; +let hljs = null; +// todo: send done msg from server when tool limit is reached and dont append line +// to prevent empty spinner +let needs_append = false; +let in_code_block = false; +let in_reason_block = false; +let was_in_reason = false; +let reason_buf = ''; +let code_block_buf = ''; +let tool_buffer = ''; + +export interface MsgFile { + name: string, + type: string, + content: string +}; + +export interface Msg { + content: string, + role: string, + timestamp: string, + toolCall?: string, + images?: string[], + files?: MsgFile[], +}; + +export interface ClientOptions { + seed?: number, + temperature?: number, +}; + +export interface ChatReq { + model: string, + messages: Msg[], + system: string, + chatfile?: string, + options?: ClientOptions, + generateTitle: boolean, + token: string +}; + +export interface ToolCall { + name: string, + parameters: any +}; + +interface ChatJsonRes { + done: boolean, + chunks?: string[], + msgs?: Msg[], + title?: string, + err?: string, +}; + +function getChatId() { + const url = new URL( window.location.href ); + const id = url.searchParams.get( 'id' ); + if( !id ) { + chat_id = ''; + msglog = []; + return null; + } + + if( id == '0' ) { + chat_id = ''; + msglog = []; + return null; + } + + chat_id = id.slice(); + return chat_id; +} + +export async function createChat() { + const res = await user.createChat(); + chat_id = res.chatId; + chat_name = 'new chat'; + + JSX.pushParams( { id: chat_id } ); + await user.updatePrefs(); // todo : error handle this w text box when component made + return getChatId(); +} + +function isToolStr( str: string ) : boolean { + const model = api.getModelFromName( user.settings.site_prefs.model || '' ); + if( !model ) + return false; + + const trimmed = str.replace( /\s+/g, '' ).toLowerCase(); + + for( let tool in model.capabilities ) { + const str = `{"name":"${tool.toLowerCase()}"`; + let matched = true; + + for( let i = 0; i < Math.min( trimmed.length, str.length ); ++i ) { + if( trimmed[i] !== str[i] ) { + matched = false; + break; + } + } + + if( matched ) + return true; + } + + return false; +} + + +let chunk_buf = ''; +function parseChatJson( rawjson: string, is_done: boolean ) : ChatJsonRes { + let msgs = rawjson.split( '\n' ); + let clean_done = false; + let ret_msgs: Msg[] = []; + let ret_chunks: string[] = []; + let title: string = ''; + + for( let raw of msgs ) { + if( !raw.length ) + continue; + + let json = null; + try { + json = JSON.parse( chunk_buf + raw ); + } catch( e: any ) { + chunk_buf += raw; + return { done: false }; + } + + chunk_buf = ''; + + if( json.done ) + clean_done = true; + + if( !clean_done && is_done ) + return { done: true, err: "the stream was closed abruptly. please try again." }; + else if( json.status == 'error' || json.status == 'busy' ) + return { done: true, err: json.msg }; + + if( json.status != 'ok' ) + return { done: true, err: json.msg || 'unknown error' }; + + let chunk: string = json.response; + if( json.finalMsg && json.finalMsg.length > 0 ) { + ret_msgs.push( { timestamp: (new Date()).toLocaleString(), role: 'assistant', content: json.finalMsg } ); + if( json.title && !title.length ) + title = json.title; + } else if( json.tool ) { + ret_msgs.push( { timestamp: (new Date()).toLocaleString(), role: 'tool', content: chunk } ); + } else { + ret_chunks.push( chunk ); + } + } + + return { + done: clean_done || is_done, + title: title.length > 0 ? title : null, + msgs: ret_msgs, + chunks: ret_chunks + }; +} + +function appendUserLine( msg: string, files?: MsgFile[] ) { + const terminal = $( "#terminal-inner" ); + const isbottom = terminal[0].scrollTop == (terminal[0] as any).scrollTopMax; + $( "#terminal-inner" ).append( + <div class="chat-line"> + <div class="chat-role-user"> + { user.settings.nickname } + <span style="color:#fff">: </span> + </div> + <div class="chat-content"> + { msg } + </div> + { files && <ChatFiles id={ msglog.length.toString() } files={ files } noremove /> } + </div> + ); + + if( isbottom ) + terminal.scrollTop( terminal[0].scrollHeight ); +} + +function appendModelLine() { + const terminal = $( "#terminal-inner" ); + const isbottom = terminal[0].scrollTop == (terminal[0] as any).scrollTopMax; + + $( "#terminal-inner" ).append( <div class="chat-line"> + <div class="chat-role-model"> + { user.settings.site_prefs.model || 'err' } + <span style="color:#fff">: </span> + </div> + <div class="chat-content"> + <Spinner style="display: inline" /> + </div> + </div> ); + + if( isbottom ) + terminal.scrollTop( terminal[0].scrollHeight ); +} + +// inserts a new text div +function appendText() { + const terminal = $( "#terminal-inner" ); + const isbottom = terminal[0].scrollTop == (terminal[0] as any).scrollTopMax; + + $( ".chat-line" ).last().append( <div class="chat-content" /> ); + + if( isbottom ) + terminal.scrollTop( terminal[0].scrollHeight ); +} + +// inserts a new code div +function appendCode( lang?: string ) { + if( lang ) { + $( ".chat-line" ).last().append( + <pre> + <div class="chat-code-line">{ lang }</div> + <code class={ `language-${ lang }` }></code> + </pre> + ); + } else { + $( ".chat-line" ).last().append( <pre><code></code></pre> ); + } +} + + +function ToolInfo( props: any ) { + return <div class="tool-call-title-wrapper"> + <div class="tool-call-title"> + { props.title } + </div> + <div class="tool-call-collapse"> + { props.collapsed ? '+' : '-' } + </div> + </div> +} + +function appendReason() { + const collapseToggle = () => { + let list = el.find( '.reason-output' ); + let btn = el.find( '.tool-call-collapse' ); + + const open = list.css( 'display' ) == 'block'; + if( !open ) { + list.css( 'display', 'block' ); + btn.text( '-' ); + } else { + list.css( 'display', 'none' ); + btn.text( '+' ); + } + }; + + const el = $( <div class="tool-call" onclick={ collapseToggle } collapsed /> ); + const ti = $( <ToolInfo title="Reasoning... " /> ); + ti.find( ".tool-call-title" ).append( <Spinner style="display: inline" /> ); + el.append( ti ); + el.append( <div class="reason-output" style="display: none"></div> ); + + $( ".chat-line" ).last().find( ".chat-content" ).replaceWith( el ); +} + +function outputReason( buf: string ) { + const el = $( ".reason-output" ).last(); + const txt = el.text(); + el.text( txt + buf ); +} + +function outputTool( tool: ToolCall, appendLine?: boolean ) { + const content = $( ".chat-line" ).last().find( ".chat-content" ); + if( needs_append || content.text().length > 1 ) + appendModelLine(); + + const collapseToggle = () => { + let list = el.find( '.tool-call-list' ); + let btn = el.find( '.tool-call-collapse' ); + + const open = list.css( 'display' ) == 'block'; + if( !open ) { + list.css( 'display', 'block' ); + btn.text( '-' ); + } else { + list.css( 'display', 'none' ); + btn.text( '+' ); + } + }; + + const el = $( <div class="tool-call" onclick={ collapseToggle } /> ); + const trimmed = tool.name.replace( /\s+/g, '' ); + switch( trimmed.toLowerCase() ) { + case 'notes': + el.append( <ToolInfo title="Note saved" /> ); + el.append( <div class="tool-call-list">{ tool.parameters.contents || '' }</div> ); + break; + case 'web': + el.append( <ToolInfo title="Searching the web..." /> ); + el.append( <div class="tool-call-list">{ tool.parameters.url || '' }</div> ); + if( appendLine ) needs_append = true; + break; + case 'remind': + el.append( <ToolInfo title="Searching the conversation..." /> ); + el.append( <div class="tool-call-list">{ tool.parameters.keywords ? tool.parameters.keywords.join( ' ' ) : '' }</div> ); + if( appendLine ) needs_append = true; + break; + } + if( in_reason_block ) { + $( ".chat-line" ).last().find( ".tool-call" ).find( ".spinner" ).remove(); + $( ".chat-line" ).last().append( el ); + appendModelLine(); + needs_append = false; + appendReason(); + } + else { + $( ".chat-line" ).last().find( ".chat-content" ).replaceWith( el ); + } +} + +function outputError( e: string ) { + const terminal = $( "#terminal-inner" ); + const isbottom = terminal[0].scrollTop == (terminal[0] as any).scrollTopMax; + + if( needs_append ) { + appendModelLine(); + needs_append = false; + } + + let el = $( ".chat-line" ).last(); + el.empty(); + el.append( <div class="chat-error">{ e }</div> ); + + if( isbottom ) + terminal.scrollTop( terminal[0].scrollHeight ); +} + +function outputChunk( chunk: string ) { + const terminal = $( "#terminal-inner" ); + const isbottom = terminal[0].scrollTop == (terminal[0] as any).scrollTopMax; + + if( needs_append ) { + appendModelLine(); + needs_append = false; + } + + let el = $( ".chat-line" ).last().find( ".chat-content" ).last(); + el.find( '.spinner' ).remove(); + el.text( el.text() + chunk ); + + if( isbottom ) + terminal.scrollTop( terminal[0].scrollHeight ); +} + +function outputCode( chunk: string ) { + const terminal = $( "#terminal-inner" ); + const isbottom = terminal[0].scrollTop == (terminal[0] as any).scrollTopMax; + + if( needs_append ) { + appendModelLine(); + needs_append = false; + } + + let el = $( ".chat-line" ).last().find( "code" ).last(); + el.find( '.spinner' ).remove(); + el.text( el.text() + chunk ); + + if( hljs ) + hljs.highlightElement( el[0] ); + + if( isbottom ) + terminal.scrollTop( terminal[0].scrollHeight ); +} + +function checkToolBuffer( chunk: string ) { + tool_buffer += chunk; + + let tool: ToolCall | null = null; + if( isToolStr( tool_buffer ) ) { + try { + tool = JSON.parse( tool_buffer ); + outputTool( tool, true ); + tool_buffer = ''; + } catch( e: any ) {} + + return true; + } + + let buf = tool_buffer.slice(); + tool_buffer = ''; + return buf; +} + + +/// returns 1 and sets in_reason_block if the msg starts with a reason token +/// returns -1 if the msg does not match a reason token +/// returns 0 if the reason token is partially completed +function checkReasonBuffer( chunk: string ) { + const buf = chunk.toLowerCase(); + const wanted_begin = '<think>'; + if( !in_reason_block ) { + if( buf == wanted_begin || (buf.length > wanted_begin.length && buf.startsWith( wanted_begin )) ) { + appendReason(); + in_reason_block = true; + return 1; + } + if( wanted_begin.startsWith( buf ) ) + return 0; + + return -1; + } + + const wanted_end = '</think>'; + if( buf == wanted_end || (buf.length > wanted_end.length && buf.startsWith( wanted_end )) ) { + $( ".chat-line" ).last().append( <div class="chat-content">{ '\n' }</div> ); + $( ".tool-call" ).last().find( ".spinner" ).remove(); + in_reason_block = false; + was_in_reason = true; + return 1; + } + if( wanted_end.endsWith( buf ) ) + return 0; + + return -1; +} + +// todo: clean, static return type. maybe nullable string +function checkCodeBuffer( chunk: string ) { + const backtick = chunk.search( '`' ); + if( backtick != -1 ) { + code_block_buf += chunk.slice( backtick ); + return true; + } + + let buf = chunk; + let parts = chunk.split( '\n' ); + if( code_block_buf.startsWith( '```' ) ) { + if( parts.length <= 1 ) + return true; + + buf = parts[1]; + if( !in_code_block ) { + appendCode(); + const lang = parts[0].substring( 3 ); + if( lang.length > 0 ) { + $( ".chat-line" ).last().find( "code" ).insertBefore( + <div class="chat-code-line"> + { lang } + </div> + ); + } + } + else + appendText(); + in_code_block = !in_code_block; + code_block_buf = ''; + } + + return buf; +} + +function resetBuffers() { + in_reason_block = false; + in_code_block = false; + was_in_reason = false; + needs_append = false; + reason_buf = ''; + tool_buffer = ''; + code_block_buf = ''; +} + +// returns true when stream completes +function handleChatJson( res: ChatJsonRes ) : boolean { + const model = api.getModelFromName( user.settings.site_prefs.model! ); + tool_buffer = ''; + + if( res.err ) { + outputError( res.err ); + } + else if( res.chunks ) { + for( let chunk of res.chunks ) { + let buf = checkToolBuffer( chunk ); + if( buf === true ) + continue; + + if( model.capabilities.thinker ) { + const reason = checkReasonBuffer( buf ); + if( reason > -1 ) + continue; + + if( in_reason_block ) { + outputReason( buf ); + continue; + } + } + + if( was_in_reason ) { + while( buf.startsWith( '\n' ) ) + buf = buf.slice( 1 ); + } + + // todo: fix, this is str8 fkn voodoo . + buf = checkCodeBuffer( buf ); + if( buf === true ) + continue; + if( in_code_block ) + outputCode( buf ); + else + outputChunk( buf ); + } + } + + if( res.msgs ) { + for( let msg of res.msgs ) { + msglog.push( msg ); + } + } + + if( res.title ) { + user.updatePrefs().then( () => { + $( "#chat-list" ).replaceWith( <ChatList /> ); + }).catch( ( e: any ) => { + outputError( e.msg ); + }); + + updateChatTitle( res.title ); + } + + return res.done; +} + +function makeChatReq() : ChatReq { + return { + model: user.settings.site_prefs.model!, + messages: msglog, + system: user.settings.prompt_data.system || '', + chatfile: getChatId(), + token: localStorage.getItem( 'session' ), + generateTitle: true + }; +} + +export async function sendChatReq( cur_chat: string ) { + let res = null; + try { + const req = makeChatReq(); + res = await fetch( `${api.url}/chat`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify( req ) + } ); + } catch( e: any ) { + return outputError( e.message ); + } + + if( !res.ok ) { + let json = null; + try{ + json = await res.json(); + } catch { + return outputError( `error contacting server (${res.statusCode}). are you connected to the internet?` ); + } + + return outputError( json.msg ); + } + + if( chat_id != cur_chat ) + return; + + const reader = res.body?.getReader(); + const decoder = new TextDecoder(); + if( !reader ) + return outputError( "can't read response" ); + + resetBuffers(); + return new Promise( ( resolve ) => { + const readLoop = async() => { + if( chat_id != cur_chat ) + return resolve( true ); + + const { value, done } = await reader.read(); + const raw = decoder.decode( value, { stream: true } ); + const parsed = parseChatJson( raw, done ); + if( handleChatJson( parsed ) ) + return resolve( true ); + + setTimeout( readLoop, 50 ); + } + + setTimeout( readLoop, 50 ); + } ); +} + +function disableInput() { $( "#chat-input" ).remove(); } +function appendInput() { + const terminal = $( "#terminal-inner" ); + const isbottom = terminal[0].scrollTop == (terminal[0] as any).scrollTopMax; + + $( "#terminal-inner" ).append( <ChatInput noupdate /> ); + + if( isbottom ) + terminal.scrollTop( terminal[0].scrollHeight ); +} + +export async function onChat( msg: string ) { + disableInput(); + + appendUserLine( msg, file_list ); + appendModelLine(); + let id = getChatId(); + if( !id ) { + try { id = await createChat() } + catch( e: any ) { + return outputError( "error creating chat: " + e.message ); + } + } + + if( file_list.length ) { + msglog.push( { timestamp: (new Date()).toLocaleString(), content: msg, role: 'user', files: file_list } ); + } + else { + msglog.push( { timestamp: (new Date()).toLocaleString(), content: msg, role: 'user' } ); + } + file_list = []; + await sendChatReq( id ); + + if( getChatId() == id ) + appendInput(); +} + +async function getChatHistory() { + if( !getChatId() ) + throw new Error( 'chat_id not set' ); + + try { + const res = await api.post( 'get-chat', { token: localStorage.getItem( 'session' ), chatId: chat_id } ); + return res; + } catch( e: any ) {} // todo: handle error ? + + return null; +} + +function updateChatTitle( name: string ) { + $( "#chat-name" ).text( name.substring( 0, 500 ) ); + let cur_name = name; + if( cur_name.length > 25 ) { + cur_name = cur_name.substring( 0, 25 ) + "..."; + } + + $( "#chat-selection-current" ).text( cur_name ); +} + +function outputChatTextForHistory( msg: string ) { + let chunks = msg.split( "```" ); + + let in_code = false; + for( let chunk of chunks ) { + if( !in_code ) { + appendText(); + outputChunk( chunk ); + } else { + const newl = chunk.indexOf( "\n" ); + let lang = null; + + if( newl != -1 ) { + lang = chunk.substring( 0, newl ); + chunk = chunk.substring( newl + 1 ); + } + + appendCode( lang ); + outputCode( chunk ); + } + + in_code = !in_code; + } +} + +function outputToolForHistory( msg: Msg ) { + let cur_idx = 0; + let open = -1; + let close = msg.content.lastIndexOf( '}' ); + open = msg.content.indexOf( "{", cur_idx ); // why is this assigned here & not on def ? also, cur_idx will never not be 0 ??? + + if( open == -1 || close == -1 ) { + outputChatTextForHistory( msg.content ); + return; + } + + let slice = msg.content.substring( open, close + 1 ); + try { + const parsed = JSON.parse( slice ); + if( open != 0 ) + outputChatTextForHistory( msg.content.substring( 0, open ) ); + if( parsed.name ) + outputTool( parsed ); + else + outputChatTextForHistory( msg.content ); + } catch( e ) { + outputChatTextForHistory( msg.content ); + } +} + +function outputChatHistory( history: Msg[] ) { + for( let msg of history ) { + if( msg.role == 'assistant' ) { + appendModelLine(); + const content = $( ".chat-line" ).last().find( ".chat-content" ); + content.empty(); + + if( msg.toolCall ) { + outputToolForHistory( msg ); + } + else { + outputChatTextForHistory( msg.content ); + } + } + else if( msg.role == 'user' ) { + appendUserLine( msg.content, msg.files ); + } + } + + setTimeout( () => { + const inner = $( "#terminal-inner" ); + inner.scrollTop( inner.prop( "scrollTopMax" ) ); + + if( history.length > 0 ) { + $( "#suggested-prompts" ).remove(); + } + } ); +} + +// don't ask me what the fuck is happening here, this is some javascript voodoo +// - nave +async function onInputKeyPress( e: KeyboardEvent ) { + let self = $( e.target as HTMLElement ); + const text = self[0].innerText; + + $( "#suggested-prompts" ).remove(); + + if( e.key == 'Enter' ) { + if( e.shiftKey ) + return; + + e.preventDefault(); + e.stopPropagation(); + + if( text.length > 0 ) { + await onChat( text ); + } + } +} + +function handleAttachments() { + $( "#cmd-files" ).remove(); + $( "#cmd" ).append( <ChatFiles id="cmd-files" files={ file_list } /> ); +} + +function onFileReadEvent( e: Event, img: boolean, name: string ) { + let contents = (e.target as any).result; + let b64 = contents.split( 'base64,' )[1]; + + if( img ) { + return; + } + + let txt = atob( b64 ); + if( txt.length > 1024 * 20 ) // todo: arbitrary change prolly + return; + + file_list.push( { name, type: 'text', content: txt } ); + handleAttachments(); +} + +async function onPaste( e: ClipboardEvent ) { + const model = api.getModelFromName( user.settings.site_prefs.model ); + if( !model ) return; + + const vision = !!model.capabilities.vision; + const items = e.clipboardData.items; + + if( !items || !items.length ) + return; + + for( let it of items ) { + if( it.type == 'text/html' ) + continue; + + if( it.kind.startsWith( 'string' ) ) { + let s = e.clipboardData.getData( 'text' ); + if( s.length > 512 ) { + e.preventDefault(); + file_list.push( { + name: `file${file_list.length}.txt`, + content: s, + type: 'text' + } ); + handleAttachments(); + } + } + else { + let isImg = false; + if( it.type.startsWith( 'image' ) ) { + if( !vision ) + continue; + isImg = true; + } + + let blob = it.getAsFile(); + let reader = new FileReader(); + + reader.onload = ( e ) => onFileReadEvent( e, isImg, blob.name ); + reader.readAsDataURL( blob ); + e.preventDefault(); + } + } +} + +function removeFile( key: number ) { + file_list.splice( key, 1 ); + + handleAttachments(); +} + +function ChatFile( props: any ) { + return <div id={ props.id } class="cmd-file"> + <span class="cmd-file-name">{ props.name.toString() }</span> + <span class="cmd-file-size">{ util.sizeHumanReadable( props.size ) }</span> + { props.key !== undefined && + <a class="cmd-file-remove" + onclick={ () => removeFile( props.key ) } + href="#" + > + remove + </a> + } + </div> +} + +function ChatFiles( props: any ) { + if( !props.files.length ) + return <div /> + + const show_remove = props.noremove === undefined; + + return <div id={ props.id } class='cmd-files'> + <div class="cmd-files-header"> + Attachments: + </div> + { props.files.map( ( f: MsgFile, i: number ) => { + if( !show_remove ) + return <ChatFile id={ `${props.id}-${i}` } size={ f.content.length } name={ f.name } /> + return <ChatFile id={ `${props.id}-${i}` } size={ f.content.length } name={ f.name } key={i} /> + } ) } + </div> +} + +export function ChatCmdLine() { + return <div id="cmd-input" contenteditable spellcheck="false" + onkeydown={ onInputKeyPress } + onpaste={ onPaste } + > + <span id="input-content"><br /></span> + </div> +} + +export function ChatInput( props: any ) { + const task = async () => { + const chat_id = getChatId(); + if( !chat_id ) { + return; + } + + disableInput(); + $( "#terminal-inner" ).empty(); + const spinner = $( <Spinner class="chat-spinner" /> ); + $( "#terminal-inner" ).append( spinner ); + + const chat = await getChatHistory(); + if( !chat ) { + msglog = []; + spinner.remove(); + return appendInput(); + } + + try { + msglog = JSON.parse( chat.contents ); + outputChatHistory( JSON.parse( chat.contents ) ); + } catch( e: any ) { + msglog = []; + } + + updateChatTitle( chat.name ); + spinner.remove(); + setTimeout( appendInput ); + }; + + if( !props.noupdate ) + setTimeout( task ); + + const ret = $( <div class="chat-line" id="chat-input"> + <div id="cmd"> + <div class="chat-role-user" style="width: fit-content; float: left"> + { user.settings.nickname }<span style="color: #fff">:</span> + </div> + <ChatCmdLine /> + <div style="clear: both" /> + </div> + </div> ); + + return ret[0]; +} + +function onSidebarHover() { $( "#chat-selection-sidebar" ).show(); } +function onSidebarLeave() { $( "#chat-selection-sidebar" ).hide(); } + +async function deleteChat( id: string ) { + try { + await user.deleteChat( id ); + await user.updatePrefs(); + + if( id == getChatId() ) + JSX.navigateParams( "/terminal", {} ); + else { + $( "#chat-list" ).replaceWith( <ChatList /> ); + } + + const popup = $( <OkPopup> + Chat deleted. + </OkPopup> ); + + addPopup( popup ); + } catch( e: any ) { + const popup = $( <OkPopup> + Error deleting chat: { e.message } + </OkPopup> ); + + addPopup( popup ); + } +} + +function showDeletePopup( id: string, name: string ) { + const popup = $( <OkCancelPopup onclick={ () => { deleteChat( id ) } }> + <div> + Are you sure you want to delete {name}? + </div> + </OkCancelPopup> ); + + addPopup( popup ); +} + +function ChatListEntry( props: any ) { + let title = props.title; + if( title.length > 20 ) { + title = title.substring( 0, 20 ) + '...'; + } + + return <div class="chat-item" id={ 'chatbtn-' + props.id } style={ props.style }> + <div class="chat-name" onclick={ () => JSX.navigateParams( "/terminal", props.id != '0' ? { id: props.id } : {} ) }> + <a>{ title }</a> + </div> + { + (() => { + if( props.id != 0 ) + return <div class="chat-delete"> + <a onclick={ () => showDeletePopup( props.id, props.title ) }>š</a> + </div> + })() + } + </div> +} + +let hljs_imported = 0; +async function importHlJs() { + if( hljs ) return; + if( hljs_imported ) return; + + hljs_imported = 1; + hljs = ( await import( 'highlight.js' ) ).default; + + $( ".chat-line.code" ).each( ( e ) => { + hljs.highlightElement( e[0] ); + } ); +} + +export function ChatList() { + if( !hljs ) { + importHlJs(); + } + + setTimeout( () => { + if( !user.settings.chat_files || !user.settings.chat_files.files ) + return; + + const files = user.settings.chat_files.files; + const entries = files.reverse().map( ( file: user.ChatFile ) => { + return <ChatListEntry id={ file.id } title={ file.name } /> + } ); + for( let e of entries ) + $( "#chat-selection-sidebar" ).append( e ); + } ); + + return <div id="chat-list"> + <div id="chat-selection"> + current chat + <div id="chat-selection-inner" onmouseenter={ onSidebarHover } ontouchstart={ onSidebarHover }> + <div> + <span id="chat-selection-current">new chat</span> + </div> + </div> + </div> + <div id="chat-selection-sidebar" style="display: none" onmouseleave={ onSidebarLeave } ontouchend={ onSidebarLeave } ontouchcancel={ onSidebarLeave }> + <ChatListEntry id={ '0' } title={ "new chat [*]" } style="padding-top: 5px" /> + </div> + </div> +} diff --git a/moneyjsx/src/components.tsx b/moneyjsx/src/components.tsx new file mode 100644 index 0000000..ff317af --- /dev/null +++ b/moneyjsx/src/components.tsx @@ -0,0 +1,238 @@ +import $ from "jquery"; +import * as JSX from "./jsx"; +import { Header } from "./header" + +const popup_stack = []; +window.onclick = ( e: Event ) => { + if( !e.target ) return; + + if( popup_stack.length > 0 ) { + const last = popup_stack[popup_stack.length - 1]; + if( last.el[0] == e.target || last.el.find( e.target ).length != 0 ) return; + e.preventDefault(); + e.stopPropagation(); + if( last.fn ) + last.fn(); + + popup_stack.pop(); + last.el.remove(); + } +} + +/** + * appends an element to the DOM and saves it in the popup stack to be removed. +**/ +export function addPopup( element: JQuery ) { + document.body.appendChild( element[0] ); + setTimeout( () => popup_stack.push( { el: element, fn: null } ) ); +} + +/** + * closes the topmost popup +**/ +export function closePopup() { + if( popup_stack.length > 0 ) { + const last = popup_stack[popup_stack.length - 1]; + if( last.fn ) + last.fn(); + + popup_stack.pop(); + setTimeout( () => last.el.remove() ); + } +} + +/** + * sets a callback that will get executed once the current popup is closed + **/ +export function onPopupClosed( fn: Function ) { + setTimeout( () => { + if( popup_stack.length > 0 ) { + popup_stack[popup_stack.length - 1].fn = fn; + } + } ); +} + +/* + * accepts "folded" prop +**/ +export function RolldownListItem( props: any ) { + const ret = <div class="rolldown"> + <div class="rolldown-collapsed-container"> + <div class="rolldown-icon-container">></div> + <div class="rolldown-collapsed">{props.folded}</div> + </div> + <div class="rolldown-expanded-container"> + <div class="rolldown-expanded">{props.children}</div> + </div> + </div>; + + ret.onclick = () => { + $( ret ).toggleClass( "active" ); + $( ret ).find( ".rolldown-expanded-container" ).toggleClass( 'active' ); + }; + + return ret; +} + +export function Spinner( props: any ) { + let spinner_steps = [ + '/', + '-', + '\\', + '|', + '/', + '-', + '\\', + '|' + ]; + + const id = props.id || ''; + + let el = $( <div class="spinner" id={ id } style={ props.style || '' } /> ); + let i = 0; + let loop = () => { + el.text( spinner_steps[i++] ); + if( i > spinner_steps.length ) + i = 0; + + if( el[0].isConnected ) + setTimeout( loop, 100 ); + }; + + setTimeout( loop, 100 ); + return el[0]; +} + +/* + * accepts title prop +**/ +export function RolldownList( props: any ) { + return <GroupBox title={props.title} style={props.style} innerStyle="margin: 0px; width: 100%"> + <div class="rolldownlist"> + { props.children } + </div> + </GroupBox> +} + +/* + * accepts title prop and optional innerStyle +**/ +export function GroupBox( props: any ) { + return <div class="groupbox" id={props.id || ''} style={props.style || ''}> + <span class="grouptitle"> + {props.title} + </span> + <span class="groupbody" style={props.innerStyle || ''}> + {props.children} + </span> + </div> +} + +export function Page( props: any ) { + return <> + <Header /> + <div id="page-main"> + {props.children} + </div> + </> +} + +export function DropdownItem( props: any ) { + return <div class="dropdown-inner" style={ props.style || "" } onclick={ props.onclick || null }> + {props.children} + </div> +} + +/** + * supports innerStyle for styling the actual dropdown picker + **/ +export function Dropdown( props: any ) { + const children = props.children; + let title = props.title; + let inline = props.inline; + let onchange = props.onchange; + let classes = props.class || ''; + let style = props.style || ""; + let id = props.id || ''; + let innerStyle = props.innerStyle || ""; + + const showItems = ( e: Event ) => { + e.preventDefault(); + const target = $( e.target as HTMLElement ); + + const newDropdown = $( <div class="dropdown-wrapper" style={ innerStyle }> + { children.map( ( child: HTMLElement ) => { + if( !child.onclick ) child.onclick = onchange; return child; + } ) } + </div> ); + target.parent().append( newDropdown[0] ); + setTimeout( () => popup_stack.push( { el: newDropdown, fn: null } ) ); + } + + if( inline ) { + return <button class={ 'dropdown' + ' ' + classes } style={ style } onclick={ showItems } id={ id }> + { title } + </button> + } + else { + return <> + <label>{ title }</label> + <button class={ 'dropdown' + ' ' + classes } style={ style } onclick={ showItems } id={ id }> + </button> + </> + } +} + +export function OkPopup( props: any ) { + const children = props.children; + const classes = props.class || ''; + const style = props.style || ''; + const id = props.id || ''; + + const onclick = ( e: Event ) => { + e.preventDefault(); + e.stopPropagation(); + if( props.onclick ) + props.onclick(); + + closePopup(); + } + + return <div class={ "popup-msg " + classes } id={ id } style={ style }> + { children } + <div style="display: flex; justify-content: center"> + <button onclick={ onclick }>Ok</button> + </div> + </div> +} + +export function OkCancelPopup( props: any ) { + const children = props.children; + const classes = props.class || ''; + const style = props.style || ''; + const id = props.id || ''; + + const onclick = ( e: Event ) => { + e.preventDefault(); + e.stopPropagation(); + if( props.onclick ) + props.onclick(); + + closePopup(); + } + + const oncancel = ( e: Event ) => { + e.preventDefault(); + e.stopPropagation(); + + closePopup(); + } + + return <div class={ "popup-msg " + classes } id={ id } style={ style }> + { children } + <div style="display: flex; justify-content: center"> + <button onclick={ onclick } style="margin-right: 10px">Ok</button> + <button onclick={ oncancel }>Cancel</button> + </div> + </div> +} diff --git a/moneyjsx/src/first-landing.tsx b/moneyjsx/src/first-landing.tsx new file mode 100644 index 0000000..8d01512 --- /dev/null +++ b/moneyjsx/src/first-landing.tsx @@ -0,0 +1,55 @@ +import * as JSX from './jsx'; +import * as user from './user'; + +import $ from 'jquery'; + +import { GroupBox, Page, Spinner } from './components'; + +async function saveNickname() { + const username = $( '#username-input' ).val() as string; + const spinner = $( <Spinner /> ); + $( "#confirm-btn" ).append( spinner ); + + if( username.length > 1 ) { + try { + await user.savePrefs( { nickname: username } ); + localStorage.removeItem( 'needs-setup' ); + JSX.navigateParams( "/terminal", {} ); + } catch( e: any ) { + $( "#landing-error" ).text( e.message ); + $( "#landing-error" ).show(); + } + } + + spinner.remove(); +} + +export default function FirstLanding() { + if( user.settings && user.settings.nickname && user.settings.nickname.length > 1 ) + setTimeout( () => JSX.navigateParams( "/terminal", {} ) ); + + if( !user.is_loggedin ) { + setTimeout( () => JSX.navigate( "/" ) ); + return <Page>not logged in</Page> + } + + return <Page> + <GroupBox title="First configuration"> + <div> + Welcome to axonbox.net + </div> + <div> + Please input a username. This can be changed at any time. + </div> + <div id="landing-error" style="display: none"></div> + <input type="text" id="username-input" maxlength="15" placeholder="username" /> + <div style="width: 100%; text-align: right; margin-top: -20px"> + <button style="width: 150px; margin-right: 5px; display: inline; height: 20px" + class="settings-btn" + id="confirm-btn" + onclick={ saveNickname } + >Confirm</button> + </div> + </GroupBox> + </Page> +} diff --git a/moneyjsx/src/header.tsx b/moneyjsx/src/header.tsx new file mode 100644 index 0000000..e79e256 --- /dev/null +++ b/moneyjsx/src/header.tsx @@ -0,0 +1,98 @@ +import $ from 'jquery'; +import * as JSX from './jsx'; +import * as user from './user'; +import * as settings from './settings'; +import { Dropdown, DropdownItem, Spinner, addPopup } from './components'; + + +async function logout() { + await user.logout(); +} + +/** + * NavItem component + * takes in title and route, optionally "disabled" +**/ +function NavItem( props: any ) { + const url = new URL( window.location.href ); + var style = `height: 45px;`; + var onclick = () => JSX.navigate( props.route ); + if( props.disabled || url.pathname == props.route ) { + style += "color: #888;pointer-events: none;"; + onclick = null; + } + + return <DropdownItem onclick={ onclick } style={ style }> + <a>[ { props.title } ]</a> + </DropdownItem> +} + +function SettingsButton( props: any ) { + let openSettings = settings.openPopup; + let style = `height: 45px;`; + + if( props.disabled ) { + openSettings = null; + style += "color: #888; pointer-events: none;"; + } + + return <DropdownItem onclick={ openSettings } style={ style }> + <a>[ Settings ]</a> + </DropdownItem> +} + +function EmailInput() { + const sendLink = async () => { + const email = $( "#login-email" ).val().toString(); + $( "#login-btn-wrapper" ).append( <Spinner /> ); + + const res = await user.sendLoginLink( email ); + if( res === true ) { + $( "#header-login-dropdown" ).replaceWith( + <div style="padding: 5px">Success! Check your inbox for a login link.</div> + ); + } else { + $( "#header-login-dropdown" ).replaceWith( + <div style="padding: 5px">Error sending email: { res }</div> + ); + } + }; + + return <div id="header-dropdown"> + <div id="header-login-dropdown"> + Log in + <input type="text" placeholder="email" id="login-email" style="margin-bottom: 5px" /> + <div id="login-btn-wrapper" style="display: flex; justify-content: space-between; margin-top: 5px;"> + <button onclick={ sendLink }> + [ get code ] + </button> + </div> + </div> + </div> +} + +function showLoginPopup() { + addPopup( $( <EmailInput /> ) ); +} + +export function Header() { + return <header id="header"> + <div id="header-user"> + { user.is_loggedin && <><b>User: </b><b id="username">{ user.settings.nickname }</b> </> } + { user.is_loggedin && <button onclick={ logout }>[ Log out ]</button> } + { !user.is_loggedin && <button onclick={ showLoginPopup }>[ Log in ]</button> } + </div> + <div id="header-ctrls"> + <a style="padding-right: 10px" onclick={ () => JSX.navigate( "/support" ) }>Site Map</a> + <Dropdown title="ā”" inline innerStyle="top: 24px; margin-left: 0" style="width: 48px" id="header-dropdown-btn"> + { + user.is_loggedin ? <NavItem title="Terminal" route="/terminal" /> : <NavItem title="Terminal" route="/" disabled /> + } + { + user.is_loggedin ? <SettingsButton /> : <SettingsButton disabled /> + } + <NavItem title="Home" route="/" /> + </Dropdown> + </div> + </header> +} diff --git a/moneyjsx/src/home.tsx b/moneyjsx/src/home.tsx new file mode 100644 index 0000000..cd53eaf --- /dev/null +++ b/moneyjsx/src/home.tsx @@ -0,0 +1,90 @@ +import $ from "jquery"; +import * as JSX from "./jsx"; +import AsciiArt from "./ascii-art" +import { GroupBox, Page, RolldownList, RolldownListItem } from "./components"; + +const text_l = [ + "Have you considered how public AI tools might expose proprietary information?", + "What would the impact be if the sensitive data you have shared with AI tool was leaked?", + "How does your current AI provider handle security indicents? How transparent are they, really?", + "What happens to your data after it is shared with public AI tools?", + "Are you comfortable with the AI models that you interact with being retrained on the data you've shared with it?", +]; + +const text_r = [ + "Unrestricted prompt and tooling customization.", + "100% private LLM access with dedicated personal instances.", + "Frictionless access and removal for all of your shared information.", + "Long-term memory, web access, and notes provided with base configuration.", + "Custom embedded 'modules' available by direct contact via support page.", + "Unlimited API calls.", +]; + +function runTypewriter( messages: string[], elId: string ) { + const el = $( elId ).find( ".groupbody" ); + if( !el ) return; + + const type = ( el: JQuery, str: string ) => { + const span = $( <span></span> ); + span.html( "> " ); + el.append( span ); + + let i = 0; + const typeWord = () => { + const words = str.split( ' ' ); + if( i < words.length ) { + span.html( span.html() + words[i] + ' ' ); + setTimeout( typeWord, 25 + Math.random() * 100 ); + } + ++i; + }; + typeWord(); + } + + for( let msg of messages ) { + type( el, msg ); + el.append( <br/> ); + } +} + +function HomeInfo() { + const ret = <div id="homepagemain"> + <GroupBox title="Questions to ask" id="q2a"/> + <GroupBox title="Features" id="features" /> + </div>; + + setTimeout( () => { + runTypewriter( text_l, "#q2a" ); + runTypewriter( text_r, "#features" ); + } ); + return ret; +} + +function HomeFaq() { + return <RolldownList title="FAQ" style="min-width: 333px; max-width: 600px; width: calc( 100% - 12px )"> + <RolldownListItem folded="What makes our service the ideal choice?"> + Unlike many of our competitors, we do not harvest or sell your personal data. We are hobbyists that simply want to provide the best possible service to assist you in achieving your goals. + </RolldownListItem> + <RolldownListItem folded="What do we offer that others can't?"> + We pride ourselves in the fact that we are small and tight-knit team of hobbyist developers with a passion to create and ship tools that can help reshape your daily life. + </RolldownListItem> + <RolldownListItem folded="How do you plan to shape the AI sector?"> + We believe that competition is a benefit in society. If we are successful in our growth, we can apply pressure towards others to stop data-brokering practices and instead focus on delivering real transparency and an ideal product. + </RolldownListItem> + <RolldownListItem folded="What forms of payment do we accept?"> + At the moment, we utilize Stripe to accept payments. If you have issues with this, please reach out to us on Twitter. We gladly accept BTC, and would prefer it for any custom work we may perform for you. + </RolldownListItem> + <RolldownListItem folded="How can I get in touch?"> + The best form of contact will be through our support account <a href="https://twitter.com/axonbox">here on Twitter</a>. Alternatively, you can email us <a href="mailto:support@axonbox.net">here</a>. However, since we are a small team, Twitter would be the most convenient. + </RolldownListItem> + </RolldownList> +} + +export default function Home() { + return <Page> + <AsciiArt /> + <h3 style="margin-top: 15px">Welcome your new second-in-command</h3> + <HomeInfo /> + <HomeFaq /> + </Page>; +} diff --git a/moneyjsx/src/index-page.tsx b/moneyjsx/src/index-page.tsx new file mode 100644 index 0000000..a7130d2 --- /dev/null +++ b/moneyjsx/src/index-page.tsx @@ -0,0 +1,32 @@ +import * as JSX from "./jsx"; +import * as user from "./user"; + +import PaymentSuccess from "./payment-success"; +import FirstLanding from "./first-landing"; +import Tutorial from "./support-tutorial" +import Terminal from "./terminal"; +import Support from "./support"; +import Upgrade from "./upgrade"; +import Models from "./support-models"; +import Login from "./login"; +import Home from "./home"; +import ToS from "./support-tos"; +import Api from "./support-api"; + +JSX.addRoute( "/payment-success", () => <PaymentSuccess /> ); +JSX.addRoute( "/first-landing", () => <FirstLanding /> ); +JSX.addRoute( "/terminal", () => <Terminal /> ); +JSX.addRoute( "/tutorial", () => <Tutorial /> ); +JSX.addRoute( "/support", () => <Support /> ); +JSX.addRoute( "/upgrade", () => <Upgrade /> ); +JSX.addRoute( "/models", () => <Models /> ); +JSX.addRoute( "/login", () => <Login /> ); +JSX.addRoute( "/tos", () => <ToS /> ); +JSX.addRoute( "/api", () => <Api /> ); +JSX.addRoute( "/", () => <Home /> ); + +window.onpopstate = JSX.onPopState; +JSX.onPreNavigate( user.onNavigate ); + +const url = new URL( window.location.href ); +JSX.navigateParams( url.pathname, url.searchParams.entries() ); diff --git a/moneyjsx/src/index.html b/moneyjsx/src/index.html new file mode 100644 index 0000000..bebbed2 --- /dev/null +++ b/moneyjsx/src/index.html @@ -0,0 +1,93 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="UTF-8"> + <meta name="description" content=" "> + <meta name="viewport" content="width=device-width,user-scalable=no"> + <title>axonbox.net</title> + <link rel="stylesheet" href="/static/main.css"> + <link href="/static/highlight.css" rel="preload" as="style" onload="this.rel='stylesheet'"> + <link rel="apple-touch-icon" href="files/globe.ico"> + <link rel="icon" href="files/globe.ico" type="image/x-icon"> + <link rel="shortcut icon" href="files/globe.ico" type="image/x-icon"> + </head> + <body> + <div id="moneyjsx-root"> + <div id="homepage" style="padding-top: 0px"> + <noscript> + <!--- for browsers with noscript !---> + <div id="ascii-art"> + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # .. # # + # # .. # # + # # .### ### + # # ### ### .. + # # # # .... + # # # # .... + # # # # .. + # # # # + # # # # + .. ############################################## + ................................... ###.. ### ........... ### .........### + .................................. ####+############################################ + #######################################+# #.# + #####-# #.# + #################################### # # #.# + # # #.# + ######################################### #.#...................................... + ### #.#...............--..................... + ######################################### | ##################.###################### + # # ,---.. ,,---.,---.|---.,---.. , ### ### ###... + ################ ,---| &rt;< | || || || | &rt;< ################ ### #################### + ########################### .. ### `---^' ``---'` '`---'`---'' ` #.# ... ### ### + ################## #.# ... ####### + ######################### ... # # #.# . ################## + ############################. #.# #.# # # .............. + ###- #.# #-########################............... + ############################- # # #+# ...###...... ...... + .........................##############-# #-########################.... .. + .........................###. #-# #.# ....................... + ..............+########################################################## ...................... + .................###................... ### ### ...### .......... + .............. ############################################## + ....# #..... # # + ... ... # # # # + ................ # # # # + .................. # # # # + .......################## # # . + .....###### ### # # + ####+###################. # # + ######+ .............. # # + # # ................. # # + # # ...... # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + # # # # + </div> + <h3 style="margin-top: 5px;">axonbox.net</h3> + <div> + you need javascript to use this website + </div> + </noscript> + </div> + </div> + </body> +</html> + diff --git a/moneyjsx/src/jsx.tsx b/moneyjsx/src/jsx.tsx new file mode 100644 index 0000000..f167877 --- /dev/null +++ b/moneyjsx/src/jsx.tsx @@ -0,0 +1,239 @@ +import $ from 'jquery'; +const assetAttributeNames = new Set( ['data', 'srcset', 'src', 'href'] ); + +export interface Route { + path: string, + component: Function, +}; + +const routes = []; +let err404page = "/"; +let rootId = "moneyjsx-root"; +let onprenavigate: Function = () => {}; +let onpostnavigate: Function = () => {}; + +/** + * sets the id of the element to be replaced by the navigator + **/ +export function setRootId( rootId: string ) { + rootId = rootId; +} + +/** + * adds a route component to the routes list + * the component function must return either a jquery or a DOM element + **/ +export function addRoute( name: string, component: Function ) { + routes[name] = component; +} + +/** + * sets the route for a 404 page + **/ +export function set404Route( name: string ) { + err404page = name; +} + +/** + * sets the callback that will get called when a route changes + **/ +export function onPreNavigate( callback: Function ) { + onprenavigate = callback; +} + +/** + * sets the callback that will get called when a route changes + **/ +export function onPostNavigate( callback: Function ) { + onpostnavigate = callback; +} + +/** + * replaces the root element with the route component + **/ +export function navigate( route: string ) { + let url = new URL( window.location.href ); + url.pathname = route; + if( !routes[route] ) { + return navigate( err404page ); + } + window.history.pushState( {}, null, url.href ); + + onprenavigate(); + const el = $( routes[route]() ); + + $( `#${rootId}` ).children().remove(); + $( `#${rootId}` ).append( el ); + onpostnavigate(); +} + +/** + * navigate with params. see: navigate + **/ +export function navigateParams( route: string, params: any ) { + let url = new URL( window.location.href ); + let uparams = new URLSearchParams( params ); + url.pathname = route; + url.search = uparams.toString(); + if( !routes[route] ) { + return navigate( err404page ); + } + window.history.pushState( {}, null, url.href ); + + onprenavigate(); + const el = $( routes[route]() ); + + $( `#${rootId}` ).children().remove(); + $( `#${rootId}` ).append( el ); + onpostnavigate(); +} + +/** + * wrapper for history.pushState + **/ +export function pushParams( params: any ) { + const url = new URL( window.location.href ); + url.search = new URLSearchParams( params ).toString(); + + window.history.pushState( {}, null, url.href ); +} + +/** + * navigates without adding a history entry + * useful for e.g. re-rendering a page after waiting for a data callback +**/ +export function navigateParamsSilent( route: string, params: any ) { + let url = new URL( window.location.href ); + let uparams = new URLSearchParams( params ); + url.pathname = route; + url.search = uparams.toString(); + if( !routes[route] ) { + return navigateSilent( err404page ); + } + + onprenavigate(); + const el = $( routes[route]() ); + + $( `#${rootId}` ).children().remove(); + $( `#${rootId}` ).append( el ); + onpostnavigate(); +} + +/** + * see: navigateParamsSilent + **/ +export function navigateSilent( route: string ) { + let url = new URL( window.location.href ); + url.pathname = route; + if( !routes[route] ) { + return navigateSilent( err404page ); + } + + onprenavigate(); + const el = $( routes[route]() ); + + $( `#${rootId}` ).children().remove(); + $( `#${rootId}` ).append( el ); + onpostnavigate(); +} + +/** + * action when the back button is pressed +**/ +export function onPopState() { + let url = new URL( window.location.href ); + let uparams = new URLSearchParams( url.searchParams ); + url.search = uparams.toString(); + if( !routes[url.pathname] ) { + return navigateSilent( err404page ); + } + + onprenavigate(); + const el = $( routes[url.pathname]() ); + + $( `#${rootId}` ).children().remove(); + $( `#${rootId}` ).append( el ); + onpostnavigate(); +} + +export function getRoutes() : Route[] { + return routes; +} + + +// internal stuff below + +const originalAppendChild = Element.prototype.appendChild; +Element.prototype.appendChild = function( child: any ) { + if( Array.isArray( child ) ) { + for( const childArrayMember of child ) + this.appendChild( childArrayMember ); + + return child; + } + else if( typeof child === 'string' ) { + return originalAppendChild.call( this, document.createTextNode( child ) ); + } + else if( child ) { + return originalAppendChild.call( this, child ); + } +}; + +export function createElement( tag: any, props: any, ...children: any ) { + props = props || {}; + + if( typeof tag === "function" ) { + props.children = children; + return tag( props ); + } + + if( tag === 'raw-content' ) { + const dummy = document.createElement( 'div' ); + dummy.innerHTML = props.content; + return [...dummy.children]; + } + + const element = document.createElement( tag ); + + for( const [name, value] of Object.entries( props ) ) { + if( name.startsWith( 'on' ) ) { + const lowercaseName = name.toLowerCase(); + + if( lowercaseName in window ) { + element.addEventListener( lowercaseName.substring(2 ), value ); + continue; + } + } + + if( name == 'ref' ) { + ( value as any ).current = element; + continue; + } + + if( value === false ) + continue; + + if( value === true ) { + element.setAttribute( name, '' ); + continue; + } + + if( assetAttributeNames.has( name ) ) { + if( typeof value === 'string' ) { + element.setAttribute( name, value ); + } + continue; + } + + element.setAttribute( name, value ); + }; + + for( const child of children ) + element.appendChild( child ); + + return element; +} + +export function createFragment( props: any ) { + return props.children; +} diff --git a/moneyjsx/src/login.tsx b/moneyjsx/src/login.tsx new file mode 100644 index 0000000..0be6acc --- /dev/null +++ b/moneyjsx/src/login.tsx @@ -0,0 +1,29 @@ +import $ from 'jquery'; +import * as JSX from './jsx'; +import * as user from './user'; +import { GroupBox, Page } from './components'; + +export default function Login() { + if( user.is_loggedin ) + return JSX.navigateParams( "/", {} ); + + const url = new URL( window.location.href ); + const code = url.searchParams.get( "token" ); + let msg = "You should be redirected shortly..."; + if( !code ) { + msg = "The link you followed is invalid."; + } + else { + user.onLogin( code ).then( () => { + JSX.navigateParams( '/terminal', {} ); + } ).catch( ( e: any ) => { + $( "#login-msg" ).text( e.message ); + } ); + } + + return <Page> + <GroupBox title="Login"> + <span id="login-msg">{ msg }</span> + </GroupBox> + </Page> +} diff --git a/moneyjsx/src/payment-success.tsx b/moneyjsx/src/payment-success.tsx new file mode 100644 index 0000000..30316fb --- /dev/null +++ b/moneyjsx/src/payment-success.tsx @@ -0,0 +1,19 @@ +import * as JSX from './jsx'; +import { Page, GroupBox } from './components'; + +export default function PaymentSuccess( props: any ) { + setTimeout( () => JSX.navigateParams( "/terminal", {} ), 1000 ); + + return <Page> + <GroupBox title="Payment successful"> + <div style="padding: 5px"> + Your payment was successful. You should be redirected shortly... + </div> + <div style="width: 100%; text-align: right;"> + <button style="margin-right: 5px" onclick={ () => JSX.navigateParams( "/terminal", {} ) }> + go to terminal + </button> + </div> + </GroupBox> + </Page> +} diff --git a/moneyjsx/src/settings.tsx b/moneyjsx/src/settings.tsx new file mode 100644 index 0000000..ba39126 --- /dev/null +++ b/moneyjsx/src/settings.tsx @@ -0,0 +1,402 @@ +import $ from "jquery"; +import * as JSX from "./jsx"; +import * as api from "./api"; +import * as util from "./util"; +import * as user from "./user"; +import * as terminal from "./terminal"; +import { + addPopup, onPopupClosed, closePopup, + Dropdown, DropdownItem, + Spinner, + OkPopup, OkCancelPopup +} from "./components"; + +let old_font = ''; +const fonts = [ + 'Terminal', + 'Arial', + 'Monospace', + 'Sans-serif', + 'Serif', + 'Times' +]; + +function showDeleteTokenPopup( id: number ) { + const deleteToken = async() => { + try { + await user.deleteToken( id ); + $( `#token-${ id }` ).remove(); + } catch( e: any ) { + addPopup( $( <OkPopup> + Error deleting token: { e.message } + </OkPopup> ) ); + } + } + + addPopup( $( + <OkCancelPopup onclick={ deleteToken }> + Are you sure you want to erase this API token? + </OkCancelPopup> + ) ); +} + +function showDeleteAllTokensPopup() { + const deleteTokens = async() => { + try { + await user.deleteAllTokens(); + closePopup(); + } catch( e: any ) { + addPopup( $( <OkPopup> + Error deleting all tokens: { e.message } + </OkPopup> ) ); + } + } + + addPopup( $( + <OkCancelPopup onclick={ deleteTokens }> + Are you sure you want to erase all API tokens? + </OkCancelPopup> + ) ); +} + +function TokenEntry( props: any ) { + const token = props.token; + + return <div class="tokens-entry" id={ `token-${ token.id }` }> + <span>{ token.value }</span> + <button class="tokens-delete" onclick={ () => showDeleteTokenPopup( token.id ) }>š</button> + </div> +} + +async function createNewToken( e: Event ) { + const btn = $( e.target ); + + e.preventDefault(); + e.stopPropagation(); + + const spinner = $( <Spinner /> ); + btn.append( spinner ); + + try { + const token = await user.createToken(); + const tokens = await user.getTokens(); + // re-draw token popup + closePopup(); + addPopup( $( <TokensPopup tokens={ tokens } /> ) ); + + const copyTokenToClipboard = () => { navigator.clipboard.writeText( token ); } + addPopup( $( + <OkCancelPopup + style="max-width: 330px; width: auto; text-align: center; display: flex; justify-content: center;" + onclick={ copyTokenToClipboard } + > + Your api token has been created.<br /> + Make sure to save it as it will not be shown to you again.<br /> + <div style="background-color: #000; width: 100%; overflow: scroll; padding: 5px"> + { token } + </div> + + Press OK to copy the token to clipboard. + </OkCancelPopup> + ) ); + } catch( e: any ) { + addPopup( $( + <OkPopup> + Error creating token: { e.message } + </OkPopup> + ) ); + } + + spinner.remove(); +} + +function TokensPopup( props: any ) { + return <div id="tokens-popup"> + { props.tokens.length > 0 && + <div id="tokens-inner"> + { props.tokens.map( ( tok: any ) => { + return <TokenEntry token={tok} /> + } ) } + </div> + } + { + props.tokens.length == 0 && <div> + No api tokens have been created. + </div> + } + <div style="display: flex; margin-top: 10px;"> + <button class="settings-btn" style="width: 150px; margin-right: 5px" onclick={ createNewToken }>Create new token</button> + <button class="settings-btn" style="width: 150px" onclick={ showDeleteAllTokensPopup }>Delete all tokens</button> + </div> + </div> +} + +async function openTokensPopup() { + let spinner = $( <Spinner /> ); + $( "#tokens-btn" ).append( spinner ); + try { + const tokens = await user.getTokens(); + spinner.remove(); + + return addPopup( $( <TokensPopup tokens={ tokens } /> ) ); + } catch( e: any ) { + spinner.remove(); + return addPopup( $( <OkPopup>{ e.message }</OkPopup> ) ); + } +} + + +function showDeleteNotePopup( note_id: string ) { + const deleteNote = async() => { + try { + await user.deleteNote( note_id ); + $( `#note-${ note_id }` ).remove(); + } catch( e: any ) { + addPopup( $( + <OkPopup> + Error deleting note<br />{ e.message } + </OkPopup> + ) ); + } + } + + addPopup( $( + <OkCancelPopup onclick={ deleteNote }> + Are you sure you want to delete this note? + </OkCancelPopup> + ) ); +} + +function showDeleteAllNotesPopup() { + addPopup( $( + <OkCancelPopup onclick={ async() => { await user.deleteAllNotes(); closePopup(); } }> + Are you sure you want to delete all notes? + </OkCancelPopup> + ) ); +} + +function NotesPopup( props: any ) { + return <div id="notes-popup"> + <div id="notes-inner"> + { props.notes.map( ( n: any ) => { + return <div class="notes-entry" id={ `note-${ n.id }` }> + <span>{ n.content.split(' : ')[1] }</span> + <button class="notes-delete" onclick={ () => showDeleteNotePopup( n.id ) }>š</button> + </div> + } ) } + </div> + <div style="display: flex; margin-top: 10px;"> + <button class="settings-btn" style="width: 200px" onclick={ showDeleteAllNotesPopup }>Delete all notes</button> + </div> + </div> +} + +async function openNotesPopup() { + let spinner = $( <Spinner /> ); + $( "#notes-btn" ).append( spinner ); + try { + const notes = await user.getNotes(); + spinner.remove(); + if( notes.length == 0 ) + return addPopup( $( <OkPopup>No notes found</OkPopup> ) ); + + return addPopup( $( <NotesPopup notes={ notes } /> ) ); + } catch( e: any ) { + spinner.remove(); + return addPopup( $( <OkPopup>{ e.message }</OkPopup> ) ); + } +} + +function onSettingsClosed() { + if( old_font.length > 0 ) { + const style = document.documentElement.style; + style.setProperty( "--site-font", old_font ); + } +} + +function onFontChanged( e: Event ) { + const el = $( e.target ); + const font = el.text(); + if( !old_font.length ) + old_font = user.settings.site_prefs.font; + + user.settings.site_prefs.font = font; + const style = document.documentElement.style; + style.setProperty( "--site-font", font ); + + $( "#settings-font" ).text( font ); + closePopup(); +} + +function onModelChanged( e: Event ) { + const el = $( e.target ); + const model = el.text(); + + if( user.settings.plan.plan == 'free' ) { + for( let m of api.models ) { + if( m.name == model && !m.free ) { + const popup = $( <OkCancelPopup onclick={ () => JSX.navigateParams( "/upgrade", {} ) }> + This model is only available for paid users. + Please upgrade your plan to use it. + </OkCancelPopup> ); + + return addPopup( popup ); + } + } + } + + user.settings.site_prefs.model = model; + + $( "#settings-model" ).text( model ); + closePopup(); +} + +async function save() { + const newprefs = { + site_prefs: user.settings.site_prefs, + prompt_data: user.settings.prompt_data, + nickname: user.settings.nickname + }; + + const newprompt = $( "#system-prompt" ).val(); + newprefs.prompt_data.system = newprompt as string; + + const newname = $( "#uname-setting" ).val() as string; + if( newname.length > 1 ) + newprefs.nickname = newname; + + $( "#settings-spinner-wrapper" ).append( <Spinner /> ); + try { + await user.savePrefs( newprefs ); + } catch( e: any ) { + $( "#settings-spinner-wrapper" ).empty(); + $( "#settings-spinner-wrapper" ).append( <div class="settings-err">{ e.message }</div> ); + return; + } + + old_font = ''; + $( "#settings-spinner-wrapper" ).empty(); + $( "#username" ).text( user.settings.nickname ); + $( "#uname-setting" ).attr( "placeholder", user.settings.nickname ); + terminal.updateCapabilitiesDisplay(); +} + +function PlanDisplay() { + const el = $( <div style="margin-top: 10px; display: flex; justify-content: space-evenly" /> ); + if( user.settings.plan.plan == 'free' ) { + el.append( + <span> + Plan: <b>free</b> + <a onclick={ () => JSX.navigate( "/upgrade" ) }>[ upgrade ]</a> + </span> + ); + } else { + el.append( + <span> + Plan: <b>{ user.settings.plan.plan }</b> + </span> + ); + + let days_left = ''; + if( user.settings.plan.endTime == -1 ) + days_left = 'inf'; + else + days_left = Math.floor( ( user.settings.plan.endTime - Date.now() ) / 60000 / 60 / 24 ).toString(); + el.append( + <span> + Time left: { days_left.toString() } days + </span> + ); + } + + return el[0]; +} + +async function downloadAllData() { + const spinner = $( <Spinner /> ); + $( "#settings-spinner-wrapper" ).append( spinner ); + + try { + await user.downloadAllData(); + } catch( e: any ) { + addPopup( $( + <OkPopup> + Error processing request: { e.message } + </OkPopup> + ) ); + } + + spinner.remove(); +} + +async function invalidateAllSessions() { + const spinner = $( <Spinner /> ); + $( "#settings-spinner-wrapper" ).append( spinner ); + + try { + await user.invalidateAllSessions(); + } catch( e: any ) { + addPopup( $( + <OkPopup> + Error invalidating sessions: { e.message } + </OkPopup> + ) ); + } + + spinner.remove(); +} + +function SettingsPopup() { + return <div id="settings-popup"> + <div id="settings-top"> + <div> + <label>System prompt</label><br/> + <textarea maxlength="1024" placeholder="..." id="system-prompt"> + { util.escapeHtml( user.settings.prompt_data.system || '' ) } + </textarea> + </div> + <div> + <div class="chat-column"> + <label style="margin-bottom: 1px">Username</label> + <input type="text" placeholder={ user.settings.nickname || '' } id="uname-setting" /> + </div> + <div class="chat-column"> + <label>Site font</label> + <Dropdown title={ user.settings.site_prefs.font } id="settings-font" inline> + { fonts.map( ( f ) => <DropdownItem onclick={ onFontChanged }>{ f }</DropdownItem> ) } + </Dropdown> + </div> + <div class="chat-column"> + <label>Chat model</label> + <Dropdown title={ user.settings.site_prefs.model! } id="settings-model" inline> + { api.models.map( ( m ) => { + if( m.free || user.settings.plan.plan == 'paid' ) + return <DropdownItem onclick={ onModelChanged }>{ m.name }</DropdownItem>; + return <DropdownItem onclick={ onModelChanged } style="color: #888">{ m.name }</DropdownItem>; + } ) } + </Dropdown> + </div> + <div style="display: flex; justify-content: space-between; margin-top: 10px"> + <button class="settings-btn" id="notes-btn" onclick={ openNotesPopup }>View notes</button> + <button class="settings-btn" id="tokens-btn" onclick={ openTokensPopup }>View tokens</button> + </div> + <PlanDisplay /> + </div> + </div> + + <div style="display: flex; flex-direction: column;"> + <button style="margin: 2px" onclick={ downloadAllData }>download all my data</button> + <button style="margin: 2px" onclick={ invalidateAllSessions }>sign out all devices</button> + <button style="margin: 2px" onclick={ save }>Save</button> + <div id="settings-spinner-wrapper" /> + </div> + </div>; +} + +export function openPopup() { + if( !user.is_loggedin ) + return; + const el = $( <SettingsPopup /> ); + addPopup( el ); + onPopupClosed( onSettingsClosed ); +} diff --git a/moneyjsx/src/support-api.tsx b/moneyjsx/src/support-api.tsx new file mode 100644 index 0000000..abb4072 --- /dev/null +++ b/moneyjsx/src/support-api.tsx @@ -0,0 +1,214 @@ +import * as JSX from './jsx'; + +import $ from 'jquery'; + +import { Page, GroupBox } from './components'; + +export default function Api() { + return <Page> + <GroupBox title="API" style="width: 85%"> + <div id="support-container" style="text-align: left; width: 100%"> + + <h2>POST /update-settings</h2> + <p>Updates user settings based on the preferences provided.</p> + + <h3>Request</h3> + <p><strong>Body:</strong></p> +<pre><code>{ `{ + "token": "JWT token", + "prefs": { + "nickname": "string", + "prompt_data": { "system": "string" }, + "site_prefs": { "model": "string" } + } +}` }</code></pre> + + <h3>Responses</h3> +<pre>{ $( `<code>{ + "status": "ok" | "error", + "msg": "settings updated" | "error message", + "userprefs": { + "uuid": "string", <span class="comment">/* the user uuid */</span> + "nickname": "string", <span class="comment">/* the user's set nickname */</span> + "prompt_data": { "system": "string" }, <span class="comment">/* the custom system prompt */</span> + "site_prefs": { "model": "string" }, <span class="comment">/* the user preferred model */</span> + "chat_files": { "files": [ { "id": "string", "name": "string" } ] }, <span class="comment">/* list of user's chat files */</span> + } +}</code>` )[0] }</pre> + <ul> + <li><span class="status">200 OK</span>: Settings updated successfully</li> + <li><span class="status">400 Bad Request</span>: Invalid value or nickname out of allowed range</li> + <li><span class="status">401 Unauthorized</span>: Invalid or expired token</li> + <li><span class="status">500 Internal Server Error</span>: General server error</li> + </ul> + + <hr /> + + <h2>POST /settings</h2> + <p>Fetches user settings.</p> + + <h3>Request</h3> + <p><strong>Body:</strong></p> +<pre><code>{ `{ + "token": "JWT token" +}` }</code></pre> + + <h3>Responses</h3> +<pre>{ $( `<code>{ + "uuid": "string", <span class="comment">/* the user uuid */</span> + "nickname": "string", <span class="comment">/* the user's set nickname */</span> + "prompt_data": { "system": "string" }, <span class="comment">/* the custom system prompt */</span> + "site_prefs": { "model": "string" }, <span class="comment">/* the user preferred model */</span> + "chat_files": { "files": [ { "id": "string", "name": "string" } ] }, <span class="comment">/* list of user's chat files */</span> +}</code>` )[0] }</pre> + <ul> + <li><span class="status">200 OK</span>: Returns user preferences</li> + <li><span class="status">401 Unauthorized</span>: Invalid or expired token</li> + <li><span class="status">500 Internal Server Error</span>: No user data found</li> + </ul> + + <hr /> + + <h2>POST /create-chat</h2> + <p>Creates a new chat file for the user.</p> + + <h3>Request</h3> + <p><strong>Body:</strong></p> +<pre><code>{ `{ + "token": "JWT token" +}` }</code></pre> + + <h3>Responses</h3> +<pre>{ $( `<code>{ + "status": "ok" | "nodata" | "error", + "msg": "chat created" | "error message", + "chatId": "string" <span class="comment">/* the uuid/filename of the newly created chat. */</span> +}</code>` )[0] }</pre> + <ul> + <li><span class="status">200 OK</span>: Chat created with ID and topic name</li> + <li><span class="status">400 Bad Request</span>: Missing user data</li> + <li><span class="status">401 Unauthorized</span>: Invalid or expired token</li> + <li><span class="status">500 Internal Server Error</span>: Error creating chat file or updating database</li> + </ul> + + <hr /> + + <h2>POST /get-chat</h2> + <p>Fetches the contents of a specified chat file.</p> + + <h3>Request</h3> + <p><strong>Body:</strong></p> +<pre>{ $( `<code>{ + "token": "JWT token", + "chatId": "string" <span class="comment">/* chat file uuid */</span> +}</code>` )[0] }</pre> + + <h3>Responses</h3>~ +<pre><code>{ `{ + "status": "ok" | "error", + "msg": "chat not found" | "error message", + "contents": [ { }, ... ] +}` }</code></pre> + <ul> + <li><span class="status">200 OK</span>: Returns chat file contents</li> + <li><span class="status">401 Unauthorized</span>: Invalid or expired token</li> + <li><span class="status">404 Not Found</span>: Chat does not exist</li> + <li><span class="status">500 Internal Server Error</span>: User data not found</li> + </ul> + + <hr /> + + <h2>POST /models</h2> + <p>Lists available models for chat.</p> + + <h3>Request</h3> + <p><strong>Body:</strong></p> +<pre><code>{ `{ + "token": "JWT token" +}` }</code></pre> + + <h3>Responses</h3> + <ul> + <li><span class="status">200 OK</span>: Returns list of models with their attributes</li> + <li><span class="status">401 Unauthorized</span>: Invalid or expired token</li> + </ul> + + <hr /> + + <h2>POST /generate</h2> + <p>Generates text based on the input prompt. Can optionally be used for in-the-middle generation.</p> + + <h3>Request</h3> + <p><strong>Body:</strong></p> +<pre>{ $( `<code>{ + "token": "JWT token", + "prompt": "string", <span class="comment">/* the text before the generated text */</span> + "suffix": "string", <span class="comment">/* optional - the text after the generated text */</span> + "model": "string", + "options": { "seed": Number, "temperature": Number } <span class="comment">/* optional */</span> +}</code>` )[0] }</pre> + + <h3>Response</h3> + <p><strong>Body:</strong></p> +<pre>{ $( `<code>{ + "status": "ok" | "error", + "response": "string", + "finalMsg": "string" <span class="comment">/* optional - only at the end of chunked transmission */</span> +}</code>` )[0] }</pre> + + <ul> + <li><span class="status">200 OK</span>: Returns streamed chat response</li> + <li><span class="status">400 Bad Request</span>: Missing required parameters</li> + <li><span class="status">401 Unauthorized</span>: Invalid or expired token</li> + <li><span class="status">429 Too Many Requests</span>: A request from this user is already being processed</li> + <li><span class="status">504 Gateway Timeout</span>: No chat instance available</li> + <li><span class="status">500 Internal Server Error</span>: Chat server error</li> + </ul> + + <hr /> + + <h2>POST /chat</h2> + <p>Sends a message to the chat server and streams the response back to the user.</p> + + <h3>Request</h3> + <p><strong>Body:</strong></p> +<pre>{ $( `<code>{ + "token": "JWT token", + "model": "string", + "messages": [ { + "role": "user" | "assistant" | "tool" | "system", + "content": "string", + timestamp: "string" + } ], + "system": "string", <span class="comment">/* optional */</span> + "options": { "seed": Number, "temperature": Number }, <span class="comment">/* optional */</span> + "chatfile": "string" <span class="comment">/* optional - chat file uuid */</span> +}</code>` )[0] }</pre> + + <h3>Responses</h3> + <p><strong>Message:</strong></p> +<pre><code>{ `{ + "status": "ok" | "error", + "msg": "string", + "done": false, + "tool": "string" +}` }</code></pre> + <p><strong>End:</strong></p> +<pre><code>{ `{ + "status": "ok" | "error", + "msg": "string", + "fullMsg": "full message returned by the model", + "done": true | false +}` }</code></pre> + <ul> + <li><span class="status">200 OK</span>: Returns streamed chat response</li> + <li><span class="status">400 Bad Request</span>: Missing required parameters</li> + <li><span class="status">401 Unauthorized</span>: Invalid or expired token</li> + <li><span class="status">429 Too Many Requests</span>: A request from this user is already being processed</li> + <li><span class="status">504 Gateway Timeout</span>: No chat instance available</li> + <li><span class="status">500 Internal Server Error</span>: Chat server error</li> + </ul> + </div> + </GroupBox> + </Page> +} diff --git a/moneyjsx/src/support-models.tsx b/moneyjsx/src/support-models.tsx new file mode 100644 index 0000000..2afd726 --- /dev/null +++ b/moneyjsx/src/support-models.tsx @@ -0,0 +1,114 @@ +import $ from "jquery"; +import * as JSX from './jsx'; +import * as API from "./api"; +import * as user from "./user"; +import * as util from "./util"; + +import { Page, GroupBox, Spinner, Dropdown, DropdownItem } from './components'; + +export default function Models() { + if( !API.models.length ) { + const modelTimeout = () => { + if( API.models.length ) + JSX.navigateSilent( "/models" ); + else + setTimeout( modelTimeout, 100 ); + } + + modelTimeout(); + + return <Page> + <div> + <Spinner /> + </div> + </Page> + } + + let model = API.models[0].name; + if( user.is_loggedin && user.settings.site_prefs && user.settings.site_prefs.model ) + model = user.settings.site_prefs.model!; + + return <Page> + <GroupBox title="Models" style="width: 85%"> + <div id="selector-wrapper"> + <Dropdown title={ model } id="model-selector" inline> + { API.models.map( ( m ) => <DropdownItem onclick={ changeModel }>{ m.name }</DropdownItem> ) } + </Dropdown> + </div> + + <div id="model-list"><ModelInfo model={ API.getModelFromName( model ) } /></div> + </GroupBox> + </Page> +} + +function changeModel( e: Event ) { + const el = $( e.target ); + const txt = el.text(); + console.log( txt ); + const m = API.getModelFromName( txt ); + console.log( m ); + + $( "#model-list" ).children().replaceWith( + <ModelInfo model={ m } /> + ); + + $( "#model-selector" ).text( m.name ); +} + + +function ModelInfo( props: any ) { + const m = props.model as API.Model; + return <div class="model-item"> + <div class="model-header" style="text-align: left"> + <h2 style="padding: 0px 10px 20px; margin: 0;"> + { m.name } + </h2> + </div> + <div class="model-body"> + <div class="model-capabilities"> + <span class={ m.capabilities.web ? "green" : "red" }>Web { m.capabilities.web ? 'ā' : 'ā' }</span> + <span class={ m.capabilities.notes ? "green" : "red" }>Notes { m.capabilities.notes ? 'ā' : 'ā' }</span> + <span class={ m.capabilities.vision ? "green" : "red" }>Vision { m.capabilities.vision ? 'ā' : 'ā' }</span> + <span class={ m.capabilities.remind ? "green" : "red" }>Memory Lookup { m.capabilities.remind ? 'ā' : 'ā' }</span> + </div> + <div class="model-description"> + { m.description.full } + </div> + <div id="model-license-wrapper"></div> + <br /> + </div> + <ModelLicense> + { util.escapeHtml( m.license ) } + </ModelLicense> + </div>; +} + +let license_open = false; +function ModelLicense( props: any ) { + const collapseToggle = () => { + const el = $( "#model-license" ); + let list = el.find( '.tool-call-list' ); + let btn = el.find( '.tool-call-collapse' ); + + license_open = list.css( 'display' ) == 'block'; + if( !license_open ) { + list.css( 'display', 'block' ); + btn.text( '-' ); + } else { + list.css( 'display', 'none' ); + btn.text( '+' ); + } + }; + + let el = <div class='tool-call' id="model-license" onclick={ collapseToggle }> + <div class='tool-call-title-wrapper'> + <span class='tool-call-title'>License</span> + <span class='tool-call-collapse'>{ license_open ? '-' : '+' }</span> + </div> + <div class='tool-call-list' style={ `display: ${ license_open ? 'block' : 'none' }; white-space: pre-line; text-align: left` }> + { props.children } + </div> + </div>; + + return el; +} diff --git a/moneyjsx/src/support-tos.tsx b/moneyjsx/src/support-tos.tsx new file mode 100644 index 0000000..2aab52e --- /dev/null +++ b/moneyjsx/src/support-tos.tsx @@ -0,0 +1,69 @@ +import * as JSX from './jsx'; + +import { Page, GroupBox } from './components'; + +export default function ToS() { + return <Page> + <GroupBox title="ToS" style="width: 85%;"> + <span id="tos-text"> +1. Acceptance of Terms<br /> + Upon account creation, your agreement to these Terms of Service will be permanently stored in case of legal discourse.<br /> +<br /> +2. Definitions<br /> + "We", "us", and any first-person references, refer to axonbox as an organization, and the individuals that represent it.<br /> + "Service" refers to any service ( LLMs, API, module, website, etc. ) provided by axonbox.<br /> + "The user", "user", and "users" refers to any individual or entity that accesses or uses the Service.<br /> + "Content" refers to all information, messages, and data provided by Users or generated by the Service.<br /> +<br /> +3. User Responsibilities<br /> + The user agrees to use the Service only for lawful purposes.<br /> + The user will not use the Service to generate harmful, illegal, or offensive content.<br /> + The user must be at least 15 years of age to use the Service.<br /> + The user must abide by these terms, or else risk a suspension, or permanent ban, of access to our services.<br /> +<br /> +4. Prohibited Uses<br /> + Users agree not to use the Service in any of the following unintended ways:<br /> + Engaging in any activity that disrupts or interferes with the Service or its servers.<br /> + Attempting to gain unauthorized access to any portion of the Service or any other systems or networks connected to the Service.<br /> + Using the Service for any automated data collection, scraping, or similar activities.<br /> +<br /> +5. Intellectual Property<br /> + All content generated by the service is owned by the user unless otherwise stated.<br /> + If opted in to data sharing the user grants us a license to use it for the purpose of training future models, and only that.<br /> +<br /> +6. Account Management<br /> + Users must create an account to access the features and services provided by axonbox.<br /> + The user is responsible for maintaining the security of their own account information and for all activities that occur under said account. Any account disputes must be handled directly by axonbox support.<br /> +<br /> +7. Privacy Policy<br /> + The use of the Service is also governed by our Privacy Policy, which explains how we collect, use, and protect user information. Axonbox only performs collection of data necessary for axonbox services' critical functionality. If axonbox were to ever cease operations, all information related to users will be securely, permanently, and thoroughly destructed and destroyed.<br /> +<br /> + Data collected by axonbox is limited to:<br /> + - User email<br /> + - User Service preferences<br /> + - Account creation timestamp<br /> + - IP Addresses of web requests<br /> + - Notes generated by chat models<br /> + - Chat logs until deletion ( encrypted with AES-256 )<br /> +<br /> +8. Dispute Resolution<br /> + Any disputes arising from these Terms will be resolved through binding arbitration in accordance with the rules of Texas law.<br /> +<br /> +9. Limitation of Liability<br /> + Axonbox is not liable for any direct, indirect, incidental, or consequential damages arising from use of the Service.<br /> +<br /> +10. Termination<br /> + We reserve the right to suspend or terminate access to the Service at our discretion at any time, without notice, for violations of these Terms.<br /> +<br /> +11. Modifications<br /> + We may update these Terms from time to time. We will notify users of any changes via the respective provided email or through the Service. Continued use of the Service constitutes acceptance of the updated Terms.<br /> +<br /> +12. Governing Law<br /> + These Terms shall be governed by the rules of Texas law.<br /> +<br /> +13. Contact Information<br /> + For any questions or concerns regarding these Terms, please contact us via our support account on X, accessible from the site map. + </span> + </GroupBox> + </Page>; +}
\ No newline at end of file diff --git a/moneyjsx/src/support-tutorial.tsx b/moneyjsx/src/support-tutorial.tsx new file mode 100644 index 0000000..a1d8a14 --- /dev/null +++ b/moneyjsx/src/support-tutorial.tsx @@ -0,0 +1,156 @@ +import $ from "jquery"; +import * as JSX from './jsx'; + +import { Dropdown, DropdownItem, Page, GroupBox } from './components'; + +interface TutorialPage { + title: string, + content: HTMLElement +} + +const pages: TutorialPage[ ] = [ + { + title: "Choosing the right model", + content: + <span> + It would get quite wordy if we were to discuss every model in detail that we provide, + so our best suggestion is to check out our <a onclick={ () => JSX.navigate( "/models" ) }>Models</a> page. + <br /> + Here, you can see the various personalities our models come with by default, + the provided tooling, as well as licensing information for each respective model! + </span> + }, + { + title: "Effective chatting", + content: + <span> + Effective chatting best practices are also, as with most things, on a model-by-model basis. + However, there are some good standards to abide by when interacting with any LLM to increase effectiveness. + We'll list a few of our personally notable ones here, in no particular order: + <div style="padding: 10px 10px 0;"> + <b>1) Prompting :</b> A good prompt can drastically change the output of a large language model, + effective prompts will be elaborated on in the <a onclick={ () => selectPage( pages[ 2 ] ) }>next</a> section. + <br /><br /> + <b>2) Clarify :</b> As the saying "garbage in, garbage out" goes with computing, it continues here to an extraordinary extent. + One of, if not, the most effective methods of improving LLM responses is by providing and continually improving: + queries, instructions, sample code, or other data you feed into the language model that fits your current need. + <br /><br /> + <b>3) Reminders :</b> LLMs, just like humans, need reminders sometimes. If you are sending large amounts of data, or + if you are having a model make many web requests, it's very likely you will leave the model's + context window. This can lead to unpredictable and unexplainable results, so do with that information + what you will. + <br /><br /> + <b>4) Tooling :</b> Luckily for you, utilizing our provided <a onclick={ () => selectPage( pages[ 4 ] ) }>tooling</a> is not something that you will have to initiate. + Models equipped with tooling functionality will automatically use our provided tools to better complete your requests. + All this being said, you will have to "manage" your tooling. For web requests, as mentioned above, they can quickly + devour your avaiable context window and cause erroneous responses to occur. Notes as well, when above capacity, can + cause the same. We do provide a way to manage notes, and we can only suggest to keep web requests to a minimum. + </div> + </span> + }, + { + title: "Prompting", + content: + <span> + We feel like this cannot be understated, so we will mention it again. + Each model is different, and will respond differently to the same query, prompt, image, etc. + This is what we describe as "personalities". + <br /> + However, as with chatting, we can provide general advice that applies across the board. + As well, we will attach some resources below that we have used in our journey in this process. + We feel these are of good quality and dig into a low level in layman's terms to help you + understand easily. + <br /> + <div style="padding: 10px 10px 0;"> + <b>1) Prompt format matters :</b> As seen in the resources below, there are many types of prompting. + Using the wrong style of prompt for the wrong purpose could hinder + service performance rather than improve it. Make sure you have a + rudimentary understanding of what prompting is and what it does before + embarking on your quest. + <br /><br /> + <b>2) Prompt interferes with context window :</b> This is a good one to keep in mind. Though it will + likely never be an issue for the average user, advanced + power users may find a point in which a lengthy prompt + causes a model to *only* output erroneous data. Keeping + your prompt clear and concise should be the goal of any + power user. + <br /><br /> + <b>3) Test, test, and test again :</b> This is the most important step. The true essence of trial and error + is found here. Attempting different variations, structures, and wordings + of the same prompt can lead to vastly different outcomes, all coinciding + with the previously discussed points. + </div> + <br /> + The aforementioned resources are as follows, in an order that we'd suggest approaching this topic with : + <div style="padding: 10px 10px 0;"> + 1) <a href="https://github.blog/ai-and-ml/generative-ai/prompt-engineering-guide-generative-ai-llms/" target="_blank">What is prompting</a> + <br /> + 2) <a href="https://github.com/tghurair/agentic-prompting/tree/main/techniques" target="_blank">Basic prompting examples</a> + <br /> + 3) <a href="https://www.promptingguide.ai/models" target="_blank">Model-specific prompting tips</a> + </div> + </span> + }, + { + title: "Modules", + content: + <span> + Modules are a product that we offer outside of being a convenient host and frontend for a wide array of hand-picked open source LLMs. + They can be created using a fraction of our available <a onclick={ () => selectPage( pages[ 5 ] ) }>api</a>, and still create a lively environment for any + chatbot, website, video game dialog, or any other endeavour only the mind can uncover. + <br /> + At the moment, our pricing for module implementation to your service starts at $250 USD, and of course goes up with project scope. + </span> + }, + { + title: "Tools", + content: + <span> + To not repeat ourselves too much here, we'd suggest reading #4 of <a onclick={ () => selectPage( pages[ 1 ] ) }>effective chatting</a> before this portion. + <br /><br /> + As stated there, our provided tooling is initiated automatically by the will of the selected model, but you are in charge + of managing its resource consumption. If you notice it taking a lot of notes, it will be worthwhile to clean out notes that + aren't so important. If your current conversation has a lot of web requests in it's history, it could prove resourceful to + start a new chat to initiate a new context window to refreshing the models "short-term memory", while carrying over useful + notes from past conversations. These nuanced tweaks will become frictionless and scale overtime to further hone in the model + to become tailored to you, the user. + </span> + }, + { + title: "API", + content: + <span> + Our OpenAI-compatible API is the core that powers this entire site. + As you can see for yourself in the inspector, this site is written completely with an in-house framework. + None of the nonsense that plagues the modern industry. We understand the importance of simplicty. + What makes this all possible, outside of our ability to "Make It Work" as developers, is our robust API. + + To dig deeper and become a power user, please visit <a onclick={ () => JSX.navigate( "/api" ) }>this</a> page. + </span> + } +]; + +let selected_page: TutorialPage = pages[ 0 ]; +export default function Tutorial() { + return <Page> + <GroupBox title="Tutorial" style="width: 85%; display: flex;"> + <div id="page-selector-wrapper"> + <Dropdown title={ selected_page.title } inline id="tutorial-links-box"> + { pages.map( ( p ) => <DropdownItem onclick={ () => selectPage( p ) }> { p.title } </DropdownItem> ) } + </Dropdown> + </div> + + <div class="tutorial-section"> + <span id="tutorial-content"> + { selected_page.content } + </span> + </div> + </GroupBox> + </Page> +} + +function selectPage( page: TutorialPage ) { + selected_page = page; + $( "#tutorial-links-box" ).text( page.title ); // moneyjsx todo @nave : FIX PLEASE, I SHOULDN'T HAVE TO DO THIS ( IT'S BROKEN ON MODEL PAGE AS WELL ) -- intuitive functionality is that it rerenders when the selected_page var is modified + $( "#tutorial-content" ).html( page.content ); // if we could add a reactive body to that as well that responds when selection changed, we could remove this entire need for onclick, but that's also probably a fuck ton of work . +} diff --git a/moneyjsx/src/support.tsx b/moneyjsx/src/support.tsx new file mode 100644 index 0000000..2b718be --- /dev/null +++ b/moneyjsx/src/support.tsx @@ -0,0 +1,18 @@ +import * as JSX from './jsx'; + +import { Page, GroupBox } from './components'; + +export default function Support() { + return <Page> + <GroupBox title="Support pages" style="width: 60%"> + <div style="display: flex; flex-direction: column"> + { /* note day: u have to actually add those routes in index-page.tsx */ } + <a onclick={ () => JSX.navigate( "/models" ) }>Models</a> + <a onclick={ () => JSX.navigate( "/tutorial" ) }>Tutorial</a> + <a onclick={ () => JSX.navigate( "/api" ) }>API</a> + <a onclick={ () => JSX.navigate( "/tos" ) }>ToS</a> + <a href="https://twitter.com/axonbox">Contact</a> + </div> + </GroupBox> + </Page> +} diff --git a/moneyjsx/src/terminal.tsx b/moneyjsx/src/terminal.tsx new file mode 100644 index 0000000..bc4657d --- /dev/null +++ b/moneyjsx/src/terminal.tsx @@ -0,0 +1,275 @@ +import $ from 'jquery'; +import * as JSX from './jsx'; +import * as api from './api'; +import * as user from './user'; +import * as chat from './chat'; + +import { Page } from './components'; +import { ChatInput, ChatList } from './chat'; + +let start_w = 0, start_h = 0; +let start_mx = 0, start_my = 0; +let is_resizing = false; +let has_listener = false; + +function startResize( e: MouseEvent ) { + const terminal = $( "#terminal" ); + start_mx = e.pageX; + start_my = e.pageY; + + if( terminal[0].style.width ) + start_w = parseInt( terminal[0].style.width ); + else + start_w = terminal[0].clientWidth; + + if( terminal[0].style.height ) + start_h = parseInt( terminal[0].style.height ); + else + start_h = terminal[0].clientHeight * 1.05; + + window.addEventListener( "touchmove", resize ); + window.addEventListener( "touchend", saveSize ); + window.addEventListener( "touchcancel", saveSize ); + window.addEventListener( "mousemove", resize ); + window.addEventListener( "mouseup", saveSize ); + is_resizing = true; +} + +function resize( e: MouseEvent ) { + if( !is_resizing ) + return; + + let new_w = start_w + ( e.pageX - start_mx ) * 2.0; + let new_h = start_h + ( ( e.pageY - start_my ) * 1.05 ); + + const body = $( "body" ); + const max_h = body.outerHeight() - 60; + + if( new_h > max_h ) + new_h = max_h; + + const terminal = $( "#terminal" ); + + terminal.css( `width`, `${ new_w }px` ); + terminal.css( `height`, `${ new_h }px` ); +} + +function saveSize() { + if( !is_resizing ) + return; + + const terminal = $( "#terminal" ); + let size = { + width: terminal[0].style.width, + height: terminal[0].style.height, + }; + + is_resizing = false; + localStorage.setItem( "terminal-size", JSON.stringify( size ) ); + + window.removeEventListener( "touchmove", resize ); + window.removeEventListener( "touchend", saveSize ); + window.removeEventListener( "touchcancel", saveSize ); + window.removeEventListener( "mousemove", resize ); + window.removeEventListener( "mouseup", saveSize ); +} + +function getStyleForSize() { + let style = ""; + if( window.innerWidth > 768 ) { + const size_settings = localStorage.getItem( "terminal-size" ); + if( size_settings ) { + const parsed = JSON.parse( size_settings ); + style = `width: ${ parsed.width }; height: ${ parsed.height };`; + } + } + else { + style = `width: 95%; height: ${Math.floor( window.innerHeight - 130 )}px`; + } + + return style; +} + +function onWindowResize() { + const terminal = $( "#terminal" ); + const style = getStyleForSize(); + terminal.attr( "style", style ); + + if( window.innerWidth < 768 ) + $( "#terminal-resizer" ).hide(); + else + $( "#terminal-resizer" ).show(); +} + +function focusInput( e: Event ) { + const sel = window.getSelection(); + if( sel && sel.type == 'Range' ) + return; + + const input = $( "#cmd-input" ); + const content = input.find( "#input-content" ); + if( !input.length || !content.length ) + return; + + for( let iclass of ( e.target as HTMLElement )?.classList ) { + if( iclass.startsWith( "tool-call" ) ) + return; + } + + input[0].focus(); + + // move cursor to the end of text + if( sel.anchorNode != content[0] && sel.anchorNode.parentElement != content[0] ) { + const range = document.createRange(); + if( content.length ) { + const child = content[0].firstChild; + if( child ) { + range.setStart( child, 0 ); + range.setEnd( child, child.textContent.length ); + } + else { + range.selectNodeContents( content[0] ); + } + range.collapse( false ); + + sel.removeAllRanges(); + sel.addRange( range ); + } + } +} + +function TerminalResizer( props: any ) { + return <div id="terminal-resizer" + onmousedown={ startResize } + ontouchstart={ startResize } + style={ props.style || '' } + /> +} + +let promptc = 0; +function writePrompt( promptTxt: string ) { + let el = $( + <div id={ `prompt-${promptc++}` } onclick={ () => inputPrompt( promptTxt ) }> + <a href="#"></a> + </div> + ); + + let writeChar = ( str: string, i: number ) => { + if( i >= str.length ) + return; + + let char = str.charAt( i ); + let link = el.find( 'a' ); + let text = link.text(); + link.text( text + char ); + setTimeout( () => writeChar( str, i + 1 ), 50 ); + }; + + writeChar( promptTxt, 0 ); + $( '#suggested-prompts' ).append( el ); +} + +async function getPrompts() { + const prompts_req = await fetch( `${window.location.origin}/static/prompts.json` ); + const data = await prompts_req.json(); + const { prompts } = data; + + const shuffled = prompts.sort( () => Math.random() - 0.5 ); + const random_prompts = shuffled.slice( 0, 5 ); + + random_prompts.forEach( ( p: string ) => { + writePrompt( p ); + } ); +} + +function inputPrompt( txt: string ) { + const input = $( "#cmd-input" ); + const el = input[0] as HTMLInputElement; + + input.text( txt ); + input[0].focus(); + + let range = document.createRange() + let sel = window.getSelection() + + range.setStart( el.childNodes[0], txt.length ); + range.collapse( true ) + + sel.removeAllRanges() + sel.addRange( range ) +} + +function SuggestedPrompts() { + setTimeout( () => { + if( !chat.msglog.length ) + getPrompts(); + } ); + + return <div id="suggested-prompts"> + </div> +} + +function TerminalWindow() { + if( !has_listener ) { + window.onresize = onWindowResize; + has_listener = true; + } + + const style = getStyleForSize(); + return <div id="terminal" style={ style } onclick={ focusInput }> + <div id="terminal-header"> + <div> + <div id="chat-name">new chat</div> + <a href="#" onclick={ () => JSX.navigateParams( "/terminal", {} ) }>X</a> + </div> + </div> + <div id="terminal-inner"> + <ChatInput /> + <SuggestedPrompts /> + </div> + <div> + <TerminalResizer style={ window.innerWidth <= 768 ? "display: none" : "" } /> + </div> + </div> +} + +function ModelCapabilities() { + const model = api.getModelFromName( user.settings.site_prefs.model! ); + if( !model ) + return <div /> + + const capabilities = model.capabilities; + if( !capabilities ) + return <div /> + + let model_str = `${model.name} | `; + model_str += `vision ${capabilities.vision ? 'ā' : 'ā'} | `; + model_str += `web ${capabilities.web ? 'ā' : 'ā'} | `; + model_str += `notes ${capabilities.notes ? 'ā' : 'ā'} | `; + model_str += `memory lookup ${capabilities.remind ? 'ā' : 'ā'}`; + // todo: later + // model_str += ` | reasoning ${capabilities.reasoning ? 'ā' : 'ā'}`; + + return <div id="model-capabilities"> + { model_str } + </div> +} + +export function updateCapabilitiesDisplay() { + const div = $( "#model-capabilities" ); + if( div.length > 0 ) + div.replaceWith( <ModelCapabilities /> ); +} + +export default function Terminal() { + if( !user.is_loggedin ) { + setTimeout( () => JSX.navigate( "/" ) ); + return <Page>not logged in</Page> + } + + return <Page> + <TerminalWindow /> + <ModelCapabilities /> + <ChatList /> + </Page> +} diff --git a/moneyjsx/src/tsconfig.json b/moneyjsx/src/tsconfig.json new file mode 100644 index 0000000..b964594 --- /dev/null +++ b/moneyjsx/src/tsconfig.json @@ -0,0 +1,121 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + "moduleResolution": "node", + /* Language and Environment */ + "target": "es2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "lib": [ + "ES2017", + "DOM", + "DOM.Iterable", + "ScriptHost" + ], + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + "jsx": "react", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + "jsxFactory": "JSX.createElement", + "jsxFragmentFactory": "JSX.createFragment", + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "es2020", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + "baseUrl": ".", + "paths": { + "*": ["types/*"] + }, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + "typeRoots": [ + "./node_modules/@types", + "./types" + ], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "noUncheckedSideEffectImports": true, /* Check side effect imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": false, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + "strictNullChecks": false, /* When type checking, take into account 'null' and 'undefined'. */ + "strictFunctionTypes": false, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + "strictBindCallApply": false, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + "strictPropertyInitialization": false, /* Check for class properties that are declared but not set in the constructor. */ + "strictBuiltinIteratorReturn": false, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */ + "noImplicitThis": false, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/moneyjsx/src/upgrade.tsx b/moneyjsx/src/upgrade.tsx new file mode 100644 index 0000000..ab29e34 --- /dev/null +++ b/moneyjsx/src/upgrade.tsx @@ -0,0 +1,206 @@ +import * as JSX from './jsx'; +import * as user from './user'; +import * as api from './api'; +import $ from 'jquery'; + +import { Page, GroupBox, Spinner } from './components'; + +let stripe = null; +let card = null; +let selected_product = 2; + +async function loadStripe() { + return new Promise( function (resolve, reject ) { + const s = document.createElement( 'script' ); + s.src = 'https://js.stripe.com/v3/'; + s.onload = resolve; + s.onerror = reject; + document.head.appendChild( s ); + } ); +} + +function showError( text: string ) { + $( "#payment-error" ).show(); + $( "#payment-error" ).text( text ); +} + +async function onFormSubmit( e: Event ) { + e.preventDefault(); + const { paymentMethod, error } = await stripe.createPaymentMethod( { + type: 'card', + card + } ); + + if( error ) + return showError( error.message ); + + const res = await api.post( 'create-payment-intent', { + token: localStorage.getItem( 'session' ), + paymentMethodId: paymentMethod.id, + subLength: selected_product + } ); + + if( res.status == 'ok' ) { + const intent = res.paymentIntent; + if( intent.status == 'succeeded' ) + return JSX.navigateParams( '/payment-success', {} ); + else + return showError( "Payment failed. Contact support if the issue persists." ); + } + else if( res.msg ) + return showError( "Error: " + res.msg ); + else + return showError( "Payment failed. Contact support if the issue persists." ); +} + +function waitForStripe() { + const iframes = $( 'iframe' ); + if( !iframes.length ) + return setTimeout( waitForStripe, 50 ); + + for( let iframe of iframes ) { + if( iframe.attributes.getNamedItem( 'name' ).value == 'hcaptcha-invisible' ) { + $( '#upgrade-loading' ).remove(); + $( '#upgrade-inner' ).show(); + + return; + } + } + + setTimeout( waitForStripe, 50 ); +} + +async function initStripe() { + stripe = window['Stripe']( 'pk_live_51Q9JG602rmv2yeiGYNNfwFkqp5ntpXIDIMIoiwDoEOrB5IsC75WDy3XOqekvuwY6PecviSSo5ERt0umrdBdUtqhd00FyYZe5p3' ); + const font = user.settings.site_prefs.font; + + const params = { + mode: 'billing', + style: { + base: { + color: '#fff', + fontFamily: font, + fontSize: '15px', + '::placeholder': { + color: '#ccc', + }, + }, + }, + } + + const el = getComputedStyle( document.body ); + const back = el.getPropertyValue( '--back' ); + const front = el.getPropertyValue( '--front' ); + const appearance = { + theme: 'stripe', + disableAnimations: true, + + variables: { + colorPrimary: front, + colorBackground: back, + colorText: '#fff', + fontFamily: font, + fontSizeBase: '15px', + fontSizeSm: '13px', + spacingUnit: '2px', + borderRadius: '0px', + }, + rules: { + ".Input": { + border: 'none' + } + } + } + + const elements = stripe.elements( { appearance } ); + const name = elements.create( 'address', { mode: 'billing', appearance } ); + name.mount( '#name-element' ); + + card = elements.create( 'card', params ); + card.mount( '#card-element' ); +} + +function onProductChange( e: Event ) { + selected_product = parseInt( (e.target as HTMLInputElement).value ); +} + +function SelectionRadio( params: any ) { + return <div style="display: flex"> + { params.checked && + <input type="radio" + name="product" + value={ params.value } + onChange={ onProductChange } + checked="checked" + /> + } + { !params.checked && + <input type="radio" + name="product" + value={ params.value } + onChange={ onProductChange } + /> + } + <label class="radio-label" style="margin-left: 5px"> + { params.text } <span style="color: var(--front)">-- ${ params.price }</span> + </label> + </div> +} + +function UpgradeLoaded() { + return <GroupBox + title="Account upgrade" + style="width: 90%; max-width: 550px; display: none" + innerStyle="width: calc( 100% - 10px )" + id="upgrade-inner" + > + <div style="border-bottom: 1px solid var(--front);"> + <h2 style="padding: 8px 0px; margin: 0px; font-size: 28px">Summary</h2> + <div style="width: 60%"> + <h3 style="margin: 5px 0;"> + Product: + </h3> + <h4 style="margin: 5px 0"> + <span id="product-name">Axonbox premium account upgrade</span><br /> + <SelectionRadio text="1 week" price="2.70" value="1"/> + <SelectionRadio text="1 month" price="10" value="2" checked="checked"/> + <SelectionRadio text="1 year" price="100" value="3"/> + </h4> + </div> + </div> + <div> + <h3 style="margin: 5px 0"> + Payment information + </h3> + </div> + <form id="upgrade-form" method="POST" action="" onsubmit={ onFormSubmit }> + <div> + <label for="name-element">Contact information</label> + <div id="name-element"></div> + <label for="card-element">Credit or debit card</label> + <div id="card-element" style="padding: 10px 0"></div> + <div id="card-errors" role="alert"></div> + </div> + <div> + <span style="display:none" id='payment-error'></span> + </div> + <button type="submit">Submit</button> + </form> + </GroupBox> +} + +export default function Upgrade() { + setTimeout( () => { + loadStripe().then( () => { + $( <UpgradeLoaded /> ).insertAfter( "#upgrade-loading" ); + initStripe(); + waitForStripe(); + } ); + } ); + + return <Page> + <GroupBox title="Account upgrade" id="upgrade-loading"> + <span>Loading... <Spinner style="display: inline" /></span> + </GroupBox> + </Page> +} diff --git a/moneyjsx/src/user.tsx b/moneyjsx/src/user.tsx new file mode 100644 index 0000000..7755670 --- /dev/null +++ b/moneyjsx/src/user.tsx @@ -0,0 +1,261 @@ +import $ from 'jquery'; + +import * as JSX from './jsx'; +import * as api from './api'; + +export interface ChatFile { + id: string, + name: string +} + +export interface UserSettings { + uuid: string, + nickname: string, + site_prefs: { + font: string, + model?: string + }, + prompt_data: { + system?: string + }, + chat_files?: { + files?: ChatFile[] + }, + plan: { + endTime: number, + plan: string + } +}; + +export let is_loggedin = false; +export let settings: UserSettings = null; + +let on_prefs_updated: Function = () => {}; + +export async function onPrefsUpdated( fn: Function ) { + on_prefs_updated = fn; +} + +/** + * polls settings from the server +**/ +export async function updatePrefs() { + if( !is_loggedin ) { + return; + } + + let res = null; + try { + res = await fetch( `${api.url}/settings`, { + method: 'POST', + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify( { + token: localStorage.getItem( 'session' ), + } ) + } ); + + if( !res.ok ) { + try { + const json = await res.json(); + if( json.status == 'nodata' ) { + localStorage.setItem( 'needs-setup', 'true' ); + if( window.location.pathname != '/first-landing' ) + return JSX.navigate( '/first-landing' ); + else { + settings = null; + localStorage.setItem( 'settings', '{}' ); + } + } else if( json.status != 'ok' ) { + is_loggedin = false; + localStorage.clear(); + } + + throw new Error( json.msg ); + } catch( e: any ) { + throw new Error( "error contacting server" ); + } + } + + res = await res.json(); + } catch( e: any ) { + throw new Error( e.message ); + } + + settings = res.userprefs; + localStorage.setItem( 'settings', JSON.stringify( settings ) ); + on_prefs_updated(); +} + +/** + * saves prefs on the server +**/ +export async function savePrefs( prefs: any ) { + const res = await api.post( `update-settings`, { token: localStorage.getItem( 'session' ), prefs } ); + settings = res.userprefs; + localStorage.setItem( 'settings', JSON.stringify( settings ) ); +} + +export async function getNotes() { + const res = await api.post( `get-notes`, { token: localStorage.getItem( 'session' ) } ); + return res.notes; +} + +export async function deleteNote( note_id: string ) { + await api.post( `delete-note`, { token: localStorage.getItem( 'session' ), noteId: note_id } ); +} + +export async function deleteAllNotes() { + await api.post( `delete-notes`, { token: localStorage.getItem( 'session' ) } ); +} + +export async function getTokens() { + const res = await api.post( `get-tokens`, { token: localStorage.getItem( 'session' ) } ); + return res.tokens; +} + +export async function createToken() { + const res = await api.post( `create-token`, { token: localStorage.getItem( 'session' ) } ); + return res.token; +} + +export async function deleteToken( token_id: number ) { + await api.post( `delete-token`, { id: token_id, token: localStorage.getItem( 'session' ) } ); +} + +export async function deleteAllTokens() { + await api.post( `delete-tokens`, { token: localStorage.getItem( 'session' ) } ); +} + +export async function createChat() { + const res = await api.post( `create-chat`, { token: localStorage.getItem( 'session' ) } ); + return res; +} + +export async function deleteChat( chatId: string ) { + await api.post( `delete-chat`, { chatId, token: localStorage.getItem( 'session' ) } ); +} + +export async function downloadAllData() { + let res = await fetch( `${api.url}/getalldata`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify( { token: localStorage.getItem( 'session' ) } ) + } ); + + let contentType = res.headers.get( 'content-type' ); + if( contentType && contentType.includes( 'application/zip' ) ) { + let blob = await res.blob(); + let url = window.URL.createObjectURL( blob ); + const a = <a style="display:none" href={url} download="userdata.zip"/>; + $( 'body' ).append( a ); + a.onclick = ( e: Event ) => { e.stopPropagation(); }; + a.click(); + window.URL.revokeObjectURL( url ); + } + else { + let json = null; + try { + json = await res.json(); + } catch( e: any ) { + throw new Error( "Error contacting server" ); + } + + if( json.status != 'ok' ) + throw new Error( json.msg ); + } +} + +export async function invalidateAllSessions() { + const res = await api.post( `invalidate-all-sessions`, { token: localStorage.getItem( 'session' ) } ); + localStorage.setItem( 'session', res.session ); +} + +function updateFont() { + const style = document.documentElement.style; + if( settings.site_prefs && settings.site_prefs.font != null ) + style.setProperty( "--site-font", settings.site_prefs.font ); +} + +async function onNavigateAsync() { + try { + if( is_loggedin ) { + if( localStorage.getItem( 'needs-setup' ) && window.location.pathname !== "/first-landing" ) + setTimeout( () => JSX.navigate( "/first-landing" ) ); + else + await updatePrefs(); + // update it again in case it changed in prefs + updateFont(); + } + + await api.updateModels(); + } catch( e: any ) { + // todo: display message box w error + console.log( e ); + } +} + +export function onNavigate() { + settings = JSON.parse( localStorage.getItem( 'settings' ) || '{}' ) as UserSettings; + api.parseModels(); + if( localStorage.getItem( 'session' ) ) + is_loggedin = true; + + if( is_loggedin ) + updateFont(); + + onNavigateAsync(); +} + +/** + * returns true on success, error message on failure +**/ +export async function sendLoginLink( email: string ) { + let res = null; + try { + res = await api.post( `send-login-link`, { email } ); + } catch( e: any ) { + return e.message; + } + + return true; +} + +export async function onLogin( code: string ) { + let json = null; + try { + const res = await fetch( `${api.url}/login?token=${code}` ); + json = await res.json(); + } catch( e: any ) { + throw new Error( "error contacting server" ); + } + + if( json.status != 'ok' ) + throw new Error( json.msg ); + + localStorage.setItem( 'session', json.session ); + is_loggedin = true; + + try { + await updatePrefs(); + } catch( e: any ) { + throw new Error( e.msg ); + } +} + +export async function logout() { + if( !is_loggedin ) + return; + + try { + await api.post( 'invalidate-session', { token: localStorage.getItem( 'session' ) } ); + } catch( e: any ) {} + + localStorage.clear(); + is_loggedin = false; + JSX.navigate( '/' ); + window.location.reload(); +} diff --git a/moneyjsx/src/util.tsx b/moneyjsx/src/util.tsx new file mode 100644 index 0000000..097502e --- /dev/null +++ b/moneyjsx/src/util.tsx @@ -0,0 +1,83 @@ +import * as api from './api'; +import * as chat from './chat'; + +export function escapeHtml( html: string ) { + const entityMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '/': '/', + '`': '`', + '=': '=' + }; + + return String( html ).replace( /[&<>"'`=\/]/g, ( s ) => { + return entityMap[s]; + } ); +} + +export function parseJWT( token: string ) : any { + const parts = token.split( '.' ); + let encoded = parts[1]; + encoded = encoded.replace(/-/g, '+').replace(/_/g, '/'); + const pad = encoded.length % 4; + if( pad === 1 ) + throw new Error( 'what the fuck' ); + if( pad > 1 ) + encoded += new Array( 5 - pad ).join( '=' ); + + const payload = JSON.parse( atob( encoded ) ); + return payload; +} + +export function isToolStr( buf: string, model: api.Model ) { + const trimmed = buf.replace( /\s+/g, '' ).toLowerCase(); + const capabilities = model.capabilities; + + for( let tool in capabilities ) { + let name = tool.toLowerCase(); + let str = `{"name":"${name}"`; + + let not_matched = false; + for( let i = 0; i < Math.min( trimmed.length, str.length ); i++ ) { + if( trimmed[i] !== str[i] ) { + not_matched = true; + break; + } + } + + if( !not_matched ) + return true; + } + + return false; +} + +export function getToolCall( msg: chat.Msg ) { + let first_bracket = msg.content.indexOf( '{' ); + let last_bracket = msg.content.lastIndexOf( '}' ); + + if( first_bracket == -1 || last_bracket == -1 ) + return null; + + let call = msg.content.substring( first_bracket, last_bracket + 1 ); + let json = null; + try { json = JSON.parse( call ); } + catch( e ) { return null; } + + return json; +} + +export function sizeHumanReadable( size: number ) { + if( size < 1024 ) + return size + ' B'; + else if( size < 1024 * 1024 ) + return ( size / 1024 ).toFixed( 2 ) + ' KB'; + else if( size < 1024 * 1024 * 1024 ) + return ( size / 1024 / 1024 ).toFixed( 2 ) + ' MB'; + else + return ( size / 1024 / 1024 / 1024 ).toFixed( 2 ) + ' GB'; +} + diff --git a/moneyjsx/static/fonts/LICENSE.TXT b/moneyjsx/static/fonts/LICENSE.TXT new file mode 100644 index 0000000..fd662a7 --- /dev/null +++ b/moneyjsx/static/fonts/LICENSE.TXT @@ -0,0 +1,428 @@ +Attribution-ShareAlike 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution-ShareAlike 4.0 International Public +License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution-ShareAlike 4.0 International Public License ("Public +License"). To the extent this Public License may be interpreted as a +contract, You are granted the Licensed Rights in consideration of Your +acceptance of these terms and conditions, and the Licensor grants You +such rights in consideration of benefits the Licensor receives from +making the Licensed Material available under these terms and +conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. BY-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + k. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + l. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + m. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + b. ShareAlike. + + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + + including for purposes of Section 3(b); and + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the āLicensor.ā The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. + diff --git a/moneyjsx/static/fonts/README.NFO b/moneyjsx/static/fonts/README.NFO new file mode 100644 index 0000000..f09ee43 --- /dev/null +++ b/moneyjsx/static/fonts/README.NFO @@ -0,0 +1,45 @@ +
+ _ Ä --- Ä _ Ä --- Ä
+ .ł" ,Ā, ~=Ņ_ .ł. .ł" ~=Ņ_
+ . . .OZZZOø ^g, . .žų~ųž. ^%· .s%ZOæ
+ ` Ą¦qZp¦' ųł `Z, ` _.,ś `gZæ ł:ZZ|
+ _Āg%%oc, ~ _., ` ŌZ; _.,Ā©y%Z=-:ś .s%Z%L, `OZZYi%gĀ_
+ jOZZZZOLś jOZZŖ, `Zb _.Ā©y%ZZZZZZZZ%=:ł jZZZZZZZb `ZZZZZZZb
+ łZZ?~ ~\ZZZ| |ZZZZO\ ś?Z.ł%ZZZZZZ¦*Źü^ų"`' /ZZ¦"~"¦ZZ\ łT ~!ZZ“
+ Z6f łZZZOłś|ZZZ^ZZi ]Z1ś:-":ZZZ' _. łOZ/ \ZZL : |6Z'
+ . `ZZŖ._ ~"^Z| łZZZ;\ZZ ĘZµ śZZZś _Ā%ZZś l%! .oZo, ]ZZśł _ŅZZ' .
+ , ~^Ź*Ź^~.ZśśZZZl ZZĀZZ1 ś łZZZZł ^¦!ZZł :=l dZZZb łZZ| ~^"~
+ ł g%ZZZśśZZZZ `ZZZų : śZZZZ: łlZZ| ł;ł :ZZZF śZZ| .'
+ ~Ä_ śZZZZ| łZZZZ ĄZZ' ł ?ZZZ! :ZZ³ś śł "¦" dZgś _Ä~
+ ~"^ :ZZZOłł|ZZZ! `^' ' `ZZZ ś¦ZZ: ś ./ZZf śÄ--`~
+ OZZZł jZ¦Ź~ `. _ _. . ~^¦L, YZZZZOzzĀĀ śł:=CO/
+ -V! j¦Ź^~ . ~-ŗł-~ . `^ʦZZF'śł:%CG' . O R G
+ ~Ä_ T _Ä~ ~' '^"~
+ ~"Ķ=|=Ķ"~
+ ł p r e s e n t s
+ ś
+
+
+ The Ultimate Oldschool PC Font Pack
+
+ < http://int10h.org/oldschool-pc-fonts/ >
+
+ v2.2 // 2020-11-21
+
+ ------------------------------------------------------------------------
+
+ For documentation see the 'docs' folder or these pages:
+
+ Readme: < http://int10h.org/oldschool-pc-fonts/readme/ >
+
+ Font list: < http://int10h.org/oldschool-pc-fonts/fontlist/ >
+
+ ------------------------------------------------------------------------
+
+ The Ultimate Oldschool PC Font Pack is licensed under a Creative Commons
+ Attribution-ShareAlike 4.0 International License.
+
+ You should have received a copy of the license along with this work. If
+ not, see < http://creativecommons.org/licenses/by-sa/4.0/ >.
+
+ (c) 2016-2020 VileR
diff --git a/moneyjsx/static/fonts/README.TXT b/moneyjsx/static/fonts/README.TXT new file mode 100644 index 0000000..02b06ef --- /dev/null +++ b/moneyjsx/static/fonts/README.TXT @@ -0,0 +1,46 @@ +
+ _ ā --- ā _ ā --- ā
+ .ā" ,ā¬, ~=ā„_ .ā. .ā" ~=ā„_
+ . . .OZZZOā ^g, . .ā °~°ā . ^%ā .s%ZOā
+ ` āĀŖqZpĀŖ' °ā `Z, ` _.,Ā· `gZā ā:ZZ|
+ _ā¬g%%oc, ~ _., ` āZ; _.,ā¬āy%Z=-:Ā· .s%Z%L, `OZZYi%gā¬_
+ jOZZÿÿZZOLĀ· jOZZÿ¬, `Zb _.ā¬āy%ZZZZZZZZ%=:ā jZZZZZZZb `ZZZZĆæZZZb
+ āZZ?~ ~\ZZZ| |Ā¢ZZZZO\ Ā·?Z.ā%ĆæZZZZZZĀŖ*ā©āæ^°"`' /ZZĀŖ"~"ĀŖZZ\ āT ~!ZZā¤
+ Z6f āZZZOāĀ·|ZZZ^ZZi ]Z1Ā·:-":ZZZ' _. āOZ/ \ZZL : |6Z'
+ . `ZZ¬._ ~"^Z| āZZZ;\ZZ āZā” Ā·Ā¢ZZZĀ· _ā¬%ZZĀ· l%! .oZo, ]ZZĀ·ā _ā„ZZ' .
+ , ~^ā©*ā©^~.Z¢··ZZZl ZZā¬ZZ1 Ā· āZZZZā ^ĀŖ!ZZā :=l dZZZb āZZ| ~^"~
+ ā g%ZZZĀ·Ā·ZZZZ `Ā„ZZZ° : Ā·ZZZZ: ālZZ| ā;ā :ZZZF Ā·ZZ| .'
+ ~ā_ Ā·ZZZZ| āZZZZ āZZĆæ' ā ?ZZZ! :ZZāĀ· Ā·ā "ĀŖ" dZgĀ· _ā~
+ ~"^ :ZZZOāā|ZZZ! `^' ' `Ā„ZZZ Ā·ĀŖZZ: Ā· ./ZZf Ā·ā--`~
+ OZZZā jZĀŖā©~ `. _ _. . ~^ĀŖL, YZZZZOzzā¬ā¬ Ā·ā:=CO/
+ -V! jĀŖā©^~ . ~-āā-~ . `^ā©ĀŖZ„ÿZF'Ā·ā:%CG' . O R G
+ ~ā_ T _ā~ ~' '^"~
+ ~"ā=|=ā"~
+ ā p r e s e n t s
+ Ā·
+
+
+ The Ultimate Oldschool PC Font Pack
+
+ < http://int10h.org/oldschool-pc-fonts/ >
+
+ v2.2 // 2020-11-21
+
+ ------------------------------------------------------------------------
+
+ For documentation see the 'docs' folder or these pages:
+
+ Readme: < http://int10h.org/oldschool-pc-fonts/readme/ >
+
+ Font list: < http://int10h.org/oldschool-pc-fonts/fontlist/ >
+
+ ------------------------------------------------------------------------
+
+ The Ultimate Oldschool PC Font Pack is licensed under a Creative Commons
+ Attribution-ShareAlike 4.0 International License.
+
+ You should have received a copy of the license along with this work. If
+ not, see < http://creativecommons.org/licenses/by-sa/4.0/ >.
+
+ (c) 2016-2020 VileR
+
diff --git a/moneyjsx/static/fonts/Web437_ACM_VGA_8x14.woff b/moneyjsx/static/fonts/Web437_ACM_VGA_8x14.woff Binary files differnew file mode 100644 index 0000000..9f44664 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ACM_VGA_8x14.woff diff --git a/moneyjsx/static/fonts/Web437_ACM_VGA_8x16.woff b/moneyjsx/static/fonts/Web437_ACM_VGA_8x16.woff Binary files differnew file mode 100644 index 0000000..b828c2b --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ACM_VGA_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_ACM_VGA_8x8.woff b/moneyjsx/static/fonts/Web437_ACM_VGA_8x8.woff Binary files differnew file mode 100644 index 0000000..acfebfa --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ACM_VGA_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_ACM_VGA_9x14.woff b/moneyjsx/static/fonts/Web437_ACM_VGA_9x14.woff Binary files differnew file mode 100644 index 0000000..c388f41 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ACM_VGA_9x14.woff diff --git a/moneyjsx/static/fonts/Web437_ACM_VGA_9x16.woff b/moneyjsx/static/fonts/Web437_ACM_VGA_9x16.woff Binary files differnew file mode 100644 index 0000000..9f7f85f --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ACM_VGA_9x16.woff diff --git a/moneyjsx/static/fonts/Web437_ACM_VGA_9x8.woff b/moneyjsx/static/fonts/Web437_ACM_VGA_9x8.woff Binary files differnew file mode 100644 index 0000000..7b82f03 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ACM_VGA_9x8.woff diff --git a/moneyjsx/static/fonts/Web437_AMI_EGA_8x14.woff b/moneyjsx/static/fonts/Web437_AMI_EGA_8x14.woff Binary files differnew file mode 100644 index 0000000..385f625 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_AMI_EGA_8x14.woff diff --git a/moneyjsx/static/fonts/Web437_AMI_EGA_8x8-2y.woff b/moneyjsx/static/fonts/Web437_AMI_EGA_8x8-2y.woff Binary files differnew file mode 100644 index 0000000..0073dbd --- /dev/null +++ b/moneyjsx/static/fonts/Web437_AMI_EGA_8x8-2y.woff diff --git a/moneyjsx/static/fonts/Web437_AMI_EGA_8x8.woff b/moneyjsx/static/fonts/Web437_AMI_EGA_8x8.woff Binary files differnew file mode 100644 index 0000000..69e5483 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_AMI_EGA_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_AMI_EGA_9x14.woff b/moneyjsx/static/fonts/Web437_AMI_EGA_9x14.woff Binary files differnew file mode 100644 index 0000000..37813dd --- /dev/null +++ b/moneyjsx/static/fonts/Web437_AMI_EGA_9x14.woff diff --git a/moneyjsx/static/fonts/Web437_AST_PremiumExec.woff b/moneyjsx/static/fonts/Web437_AST_PremiumExec.woff Binary files differnew file mode 100644 index 0000000..9613ecf --- /dev/null +++ b/moneyjsx/static/fonts/Web437_AST_PremiumExec.woff diff --git a/moneyjsx/static/fonts/Web437_ATI_8x14.woff b/moneyjsx/static/fonts/Web437_ATI_8x14.woff Binary files differnew file mode 100644 index 0000000..bc1a987 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ATI_8x14.woff diff --git a/moneyjsx/static/fonts/Web437_ATI_8x16.woff b/moneyjsx/static/fonts/Web437_ATI_8x16.woff Binary files differnew file mode 100644 index 0000000..c782766 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ATI_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_ATI_8x8-2y.woff b/moneyjsx/static/fonts/Web437_ATI_8x8-2y.woff Binary files differnew file mode 100644 index 0000000..a2098f8 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ATI_8x8-2y.woff diff --git a/moneyjsx/static/fonts/Web437_ATI_8x8.woff b/moneyjsx/static/fonts/Web437_ATI_8x8.woff Binary files differnew file mode 100644 index 0000000..7984412 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ATI_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_ATI_9x14.woff b/moneyjsx/static/fonts/Web437_ATI_9x14.woff Binary files differnew file mode 100644 index 0000000..a8f1153 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ATI_9x14.woff diff --git a/moneyjsx/static/fonts/Web437_ATI_9x16.woff b/moneyjsx/static/fonts/Web437_ATI_9x16.woff Binary files differnew file mode 100644 index 0000000..1f017ab --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ATI_9x16.woff diff --git a/moneyjsx/static/fonts/Web437_ATI_9x8.woff b/moneyjsx/static/fonts/Web437_ATI_9x8.woff Binary files differnew file mode 100644 index 0000000..c53ff48 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ATI_9x8.woff diff --git a/moneyjsx/static/fonts/Web437_ATI_SmallW_6x8.woff b/moneyjsx/static/fonts/Web437_ATI_SmallW_6x8.woff Binary files differnew file mode 100644 index 0000000..479d653 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ATI_SmallW_6x8.woff diff --git a/moneyjsx/static/fonts/Web437_ATT_PC6300-2x.woff b/moneyjsx/static/fonts/Web437_ATT_PC6300-2x.woff Binary files differnew file mode 100644 index 0000000..9d633b5 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ATT_PC6300-2x.woff diff --git a/moneyjsx/static/fonts/Web437_ATT_PC6300.woff b/moneyjsx/static/fonts/Web437_ATT_PC6300.woff Binary files differnew file mode 100644 index 0000000..c7cb2c4 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ATT_PC6300.woff diff --git a/moneyjsx/static/fonts/Web437_Acer710_CGA-2y.woff b/moneyjsx/static/fonts/Web437_Acer710_CGA-2y.woff Binary files differnew file mode 100644 index 0000000..74d7126 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Acer710_CGA-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Acer710_CGA.woff b/moneyjsx/static/fonts/Web437_Acer710_CGA.woff Binary files differnew file mode 100644 index 0000000..07fddbc --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Acer710_CGA.woff diff --git a/moneyjsx/static/fonts/Web437_Acer710_Mono.woff b/moneyjsx/static/fonts/Web437_Acer710_Mono.woff Binary files differnew file mode 100644 index 0000000..c6cf32c --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Acer710_Mono.woff diff --git a/moneyjsx/static/fonts/Web437_Acer_VGA_8x8-2y.woff b/moneyjsx/static/fonts/Web437_Acer_VGA_8x8-2y.woff Binary files differnew file mode 100644 index 0000000..0422518 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Acer_VGA_8x8-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Acer_VGA_8x8.woff b/moneyjsx/static/fonts/Web437_Acer_VGA_8x8.woff Binary files differnew file mode 100644 index 0000000..d13fa7b --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Acer_VGA_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_Acer_VGA_9x8.woff b/moneyjsx/static/fonts/Web437_Acer_VGA_9x8.woff Binary files differnew file mode 100644 index 0000000..36c1e47 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Acer_VGA_9x8.woff diff --git a/moneyjsx/static/fonts/Web437_Amstrad_PC-2y.woff b/moneyjsx/static/fonts/Web437_Amstrad_PC-2y.woff Binary files differnew file mode 100644 index 0000000..2a8593f --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Amstrad_PC-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Amstrad_PC.woff b/moneyjsx/static/fonts/Web437_Amstrad_PC.woff Binary files differnew file mode 100644 index 0000000..89f7b01 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Amstrad_PC.woff diff --git a/moneyjsx/static/fonts/Web437_ApricotPortable.woff b/moneyjsx/static/fonts/Web437_ApricotPortable.woff Binary files differnew file mode 100644 index 0000000..3b562f5 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ApricotPortable.woff diff --git a/moneyjsx/static/fonts/Web437_ApricotXenC.woff b/moneyjsx/static/fonts/Web437_ApricotXenC.woff Binary files differnew file mode 100644 index 0000000..a2cde2a --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ApricotXenC.woff diff --git a/moneyjsx/static/fonts/Web437_Apricot_200L-2y.woff b/moneyjsx/static/fonts/Web437_Apricot_200L-2y.woff Binary files differnew file mode 100644 index 0000000..e4bf1f3 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Apricot_200L-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Apricot_200L.woff b/moneyjsx/static/fonts/Web437_Apricot_200L.woff Binary files differnew file mode 100644 index 0000000..5329aee --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Apricot_200L.woff diff --git a/moneyjsx/static/fonts/Web437_Apricot_256L-2y.woff b/moneyjsx/static/fonts/Web437_Apricot_256L-2y.woff Binary files differnew file mode 100644 index 0000000..710985f --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Apricot_256L-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Apricot_256L.woff b/moneyjsx/static/fonts/Web437_Apricot_256L.woff Binary files differnew file mode 100644 index 0000000..ef73b30 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Apricot_256L.woff diff --git a/moneyjsx/static/fonts/Web437_Apricot_Mono.woff b/moneyjsx/static/fonts/Web437_Apricot_Mono.woff Binary files differnew file mode 100644 index 0000000..e1041a3 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Apricot_Mono.woff diff --git a/moneyjsx/static/fonts/Web437_CL_EagleIII_8x16.woff b/moneyjsx/static/fonts/Web437_CL_EagleIII_8x16.woff Binary files differnew file mode 100644 index 0000000..f0e9430 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_CL_EagleIII_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_CL_EagleIII_9x16.woff b/moneyjsx/static/fonts/Web437_CL_EagleIII_9x16.woff Binary files differnew file mode 100644 index 0000000..1866e81 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_CL_EagleIII_9x16.woff diff --git a/moneyjsx/static/fonts/Web437_CL_EagleII_8x16.woff b/moneyjsx/static/fonts/Web437_CL_EagleII_8x16.woff Binary files differnew file mode 100644 index 0000000..342cdc6 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_CL_EagleII_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_CL_EagleII_9x16.woff b/moneyjsx/static/fonts/Web437_CL_EagleII_9x16.woff Binary files differnew file mode 100644 index 0000000..38e8b1d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_CL_EagleII_9x16.woff diff --git a/moneyjsx/static/fonts/Web437_CL_Stingray_8x16.woff b/moneyjsx/static/fonts/Web437_CL_Stingray_8x16.woff Binary files differnew file mode 100644 index 0000000..94dc555 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_CL_Stingray_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_CL_Stingray_8x16_bold.woff b/moneyjsx/static/fonts/Web437_CL_Stingray_8x16_bold.woff Binary files differnew file mode 100644 index 0000000..78cb4fc --- /dev/null +++ b/moneyjsx/static/fonts/Web437_CL_Stingray_8x16_bold.woff diff --git a/moneyjsx/static/fonts/Web437_CL_Stingray_8x19.woff b/moneyjsx/static/fonts/Web437_CL_Stingray_8x19.woff Binary files differnew file mode 100644 index 0000000..1781f2f --- /dev/null +++ b/moneyjsx/static/fonts/Web437_CL_Stingray_8x19.woff diff --git a/moneyjsx/static/fonts/Web437_CL_Stingray_8x19_bold.woff b/moneyjsx/static/fonts/Web437_CL_Stingray_8x19_bold.woff Binary files differnew file mode 100644 index 0000000..da422df --- /dev/null +++ b/moneyjsx/static/fonts/Web437_CL_Stingray_8x19_bold.woff diff --git a/moneyjsx/static/fonts/Web437_CompaqThin_8x14.woff b/moneyjsx/static/fonts/Web437_CompaqThin_8x14.woff Binary files differnew file mode 100644 index 0000000..c448c58 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_CompaqThin_8x14.woff diff --git a/moneyjsx/static/fonts/Web437_CompaqThin_8x16.woff b/moneyjsx/static/fonts/Web437_CompaqThin_8x16.woff Binary files differnew file mode 100644 index 0000000..7914e4c --- /dev/null +++ b/moneyjsx/static/fonts/Web437_CompaqThin_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_CompaqThin_8x8.woff b/moneyjsx/static/fonts/Web437_CompaqThin_8x8.woff Binary files differnew file mode 100644 index 0000000..62772df --- /dev/null +++ b/moneyjsx/static/fonts/Web437_CompaqThin_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_Compaq_Port3-2x.woff b/moneyjsx/static/fonts/Web437_Compaq_Port3-2x.woff Binary files differnew file mode 100644 index 0000000..a859b9f --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Compaq_Port3-2x.woff diff --git a/moneyjsx/static/fonts/Web437_Compaq_Port3.woff b/moneyjsx/static/fonts/Web437_Compaq_Port3.woff Binary files differnew file mode 100644 index 0000000..b96d4e5 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Compaq_Port3.woff diff --git a/moneyjsx/static/fonts/Web437_Compis.woff b/moneyjsx/static/fonts/Web437_Compis.woff Binary files differnew file mode 100644 index 0000000..44721a2 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Compis.woff diff --git a/moneyjsx/static/fonts/Web437_Copam_BIOS-2y.woff b/moneyjsx/static/fonts/Web437_Copam_BIOS-2y.woff Binary files differnew file mode 100644 index 0000000..1a301bf --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Copam_BIOS-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Copam_BIOS.woff b/moneyjsx/static/fonts/Web437_Copam_BIOS.woff Binary files differnew file mode 100644 index 0000000..1c51092 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Copam_BIOS.woff diff --git a/moneyjsx/static/fonts/Web437_Cordata_PPC-21.woff b/moneyjsx/static/fonts/Web437_Cordata_PPC-21.woff Binary files differnew file mode 100644 index 0000000..bab8c7b --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Cordata_PPC-21.woff diff --git a/moneyjsx/static/fonts/Web437_Cordata_PPC-400.woff b/moneyjsx/static/fonts/Web437_Cordata_PPC-400.woff Binary files differnew file mode 100644 index 0000000..5f95c1b --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Cordata_PPC-400.woff diff --git a/moneyjsx/static/fonts/Web437_DG_One-2y.woff b/moneyjsx/static/fonts/Web437_DG_One-2y.woff Binary files differnew file mode 100644 index 0000000..5ebc340 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DG_One-2y.woff diff --git a/moneyjsx/static/fonts/Web437_DG_One-2y_bold.woff b/moneyjsx/static/fonts/Web437_DG_One-2y_bold.woff Binary files differnew file mode 100644 index 0000000..38a7339 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DG_One-2y_bold.woff diff --git a/moneyjsx/static/fonts/Web437_DG_One.woff b/moneyjsx/static/fonts/Web437_DG_One.woff Binary files differnew file mode 100644 index 0000000..9bee64f --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DG_One.woff diff --git a/moneyjsx/static/fonts/Web437_DG_One_bold.woff b/moneyjsx/static/fonts/Web437_DG_One_bold.woff Binary files differnew file mode 100644 index 0000000..a887854 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DG_One_bold.woff diff --git a/moneyjsx/static/fonts/Web437_DOS-V_TWN16.woff b/moneyjsx/static/fonts/Web437_DOS-V_TWN16.woff Binary files differnew file mode 100644 index 0000000..4a9692a --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DOS-V_TWN16.woff diff --git a/moneyjsx/static/fonts/Web437_DOS-V_TWN19.woff b/moneyjsx/static/fonts/Web437_DOS-V_TWN19.woff Binary files differnew file mode 100644 index 0000000..3ebeeb5 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DOS-V_TWN19.woff diff --git a/moneyjsx/static/fonts/Web437_DOS-V_re_ANK16.woff b/moneyjsx/static/fonts/Web437_DOS-V_re_ANK16.woff Binary files differnew file mode 100644 index 0000000..a61193e --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DOS-V_re_ANK16.woff diff --git a/moneyjsx/static/fonts/Web437_DOS-V_re_ANK19.woff b/moneyjsx/static/fonts/Web437_DOS-V_re_ANK19.woff Binary files differnew file mode 100644 index 0000000..6842296 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DOS-V_re_ANK19.woff diff --git a/moneyjsx/static/fonts/Web437_DOS-V_re_ANK24.woff b/moneyjsx/static/fonts/Web437_DOS-V_re_ANK24.woff Binary files differnew file mode 100644 index 0000000..a54c6ad --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DOS-V_re_ANK24.woff diff --git a/moneyjsx/static/fonts/Web437_DOS-V_re_ANK30.woff b/moneyjsx/static/fonts/Web437_DOS-V_re_ANK30.woff Binary files differnew file mode 100644 index 0000000..623d973 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DOS-V_re_ANK30.woff diff --git a/moneyjsx/static/fonts/Web437_DOS-V_re_JPN12.woff b/moneyjsx/static/fonts/Web437_DOS-V_re_JPN12.woff Binary files differnew file mode 100644 index 0000000..04ea332 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DOS-V_re_JPN12.woff diff --git a/moneyjsx/static/fonts/Web437_DOS-V_re_JPN16.woff b/moneyjsx/static/fonts/Web437_DOS-V_re_JPN16.woff Binary files differnew file mode 100644 index 0000000..6c91b6e --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DOS-V_re_JPN16.woff diff --git a/moneyjsx/static/fonts/Web437_DOS-V_re_JPN19.woff b/moneyjsx/static/fonts/Web437_DOS-V_re_JPN19.woff Binary files differnew file mode 100644 index 0000000..48f154d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DOS-V_re_JPN19.woff diff --git a/moneyjsx/static/fonts/Web437_DOS-V_re_JPN24.woff b/moneyjsx/static/fonts/Web437_DOS-V_re_JPN24.woff Binary files differnew file mode 100644 index 0000000..a77aca7 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DOS-V_re_JPN24.woff diff --git a/moneyjsx/static/fonts/Web437_DOS-V_re_JPN30.woff b/moneyjsx/static/fonts/Web437_DOS-V_re_JPN30.woff Binary files differnew file mode 100644 index 0000000..3073f72 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DOS-V_re_JPN30.woff diff --git a/moneyjsx/static/fonts/Web437_DOS-V_re_PRC16.woff b/moneyjsx/static/fonts/Web437_DOS-V_re_PRC16.woff Binary files differnew file mode 100644 index 0000000..4ddf047 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DOS-V_re_PRC16.woff diff --git a/moneyjsx/static/fonts/Web437_DOS-V_re_PRC19.woff b/moneyjsx/static/fonts/Web437_DOS-V_re_PRC19.woff Binary files differnew file mode 100644 index 0000000..322c960 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DOS-V_re_PRC19.woff diff --git a/moneyjsx/static/fonts/Web437_DTK_BIOS-2y.woff b/moneyjsx/static/fonts/Web437_DTK_BIOS-2y.woff Binary files differnew file mode 100644 index 0000000..14c9926 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DTK_BIOS-2y.woff diff --git a/moneyjsx/static/fonts/Web437_DTK_BIOS.woff b/moneyjsx/static/fonts/Web437_DTK_BIOS.woff Binary files differnew file mode 100644 index 0000000..7a1cbaf --- /dev/null +++ b/moneyjsx/static/fonts/Web437_DTK_BIOS.woff diff --git a/moneyjsx/static/fonts/Web437_EagleSpCGA_Alt1-2y.woff b/moneyjsx/static/fonts/Web437_EagleSpCGA_Alt1-2y.woff Binary files differnew file mode 100644 index 0000000..15a696b --- /dev/null +++ b/moneyjsx/static/fonts/Web437_EagleSpCGA_Alt1-2y.woff diff --git a/moneyjsx/static/fonts/Web437_EagleSpCGA_Alt1.woff b/moneyjsx/static/fonts/Web437_EagleSpCGA_Alt1.woff Binary files differnew file mode 100644 index 0000000..a2af2d5 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_EagleSpCGA_Alt1.woff diff --git a/moneyjsx/static/fonts/Web437_EagleSpCGA_Alt2-2y.woff b/moneyjsx/static/fonts/Web437_EagleSpCGA_Alt2-2y.woff Binary files differnew file mode 100644 index 0000000..cfee97a --- /dev/null +++ b/moneyjsx/static/fonts/Web437_EagleSpCGA_Alt2-2y.woff diff --git a/moneyjsx/static/fonts/Web437_EagleSpCGA_Alt2.woff b/moneyjsx/static/fonts/Web437_EagleSpCGA_Alt2.woff Binary files differnew file mode 100644 index 0000000..dbfdce7 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_EagleSpCGA_Alt2.woff diff --git a/moneyjsx/static/fonts/Web437_EagleSpCGA_Alt3-2y.woff b/moneyjsx/static/fonts/Web437_EagleSpCGA_Alt3-2y.woff Binary files differnew file mode 100644 index 0000000..c7562a7 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_EagleSpCGA_Alt3-2y.woff diff --git a/moneyjsx/static/fonts/Web437_EagleSpCGA_Alt3.woff b/moneyjsx/static/fonts/Web437_EagleSpCGA_Alt3.woff Binary files differnew file mode 100644 index 0000000..3ac1dfe --- /dev/null +++ b/moneyjsx/static/fonts/Web437_EagleSpCGA_Alt3.woff diff --git a/moneyjsx/static/fonts/Web437_EpsonMGA-2y.woff b/moneyjsx/static/fonts/Web437_EpsonMGA-2y.woff Binary files differnew file mode 100644 index 0000000..31f04fb --- /dev/null +++ b/moneyjsx/static/fonts/Web437_EpsonMGA-2y.woff diff --git a/moneyjsx/static/fonts/Web437_EpsonMGA.woff b/moneyjsx/static/fonts/Web437_EpsonMGA.woff Binary files differnew file mode 100644 index 0000000..3139daf --- /dev/null +++ b/moneyjsx/static/fonts/Web437_EpsonMGA.woff diff --git a/moneyjsx/static/fonts/Web437_EpsonMGA_Alt-2y.woff b/moneyjsx/static/fonts/Web437_EpsonMGA_Alt-2y.woff Binary files differnew file mode 100644 index 0000000..4680e93 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_EpsonMGA_Alt-2y.woff diff --git a/moneyjsx/static/fonts/Web437_EpsonMGA_Alt.woff b/moneyjsx/static/fonts/Web437_EpsonMGA_Alt.woff Binary files differnew file mode 100644 index 0000000..0616ea7 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_EpsonMGA_Alt.woff diff --git a/moneyjsx/static/fonts/Web437_EpsonMGA_Mono.woff b/moneyjsx/static/fonts/Web437_EpsonMGA_Mono.woff Binary files differnew file mode 100644 index 0000000..4b132bf --- /dev/null +++ b/moneyjsx/static/fonts/Web437_EpsonMGA_Mono.woff diff --git a/moneyjsx/static/fonts/Web437_EuroPC_CGA-2y.woff b/moneyjsx/static/fonts/Web437_EuroPC_CGA-2y.woff Binary files differnew file mode 100644 index 0000000..ef56d5d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_EuroPC_CGA-2y.woff diff --git a/moneyjsx/static/fonts/Web437_EuroPC_CGA.woff b/moneyjsx/static/fonts/Web437_EuroPC_CGA.woff Binary files differnew file mode 100644 index 0000000..89b84ac --- /dev/null +++ b/moneyjsx/static/fonts/Web437_EuroPC_CGA.woff diff --git a/moneyjsx/static/fonts/Web437_EuroPC_Mono.woff b/moneyjsx/static/fonts/Web437_EuroPC_Mono.woff Binary files differnew file mode 100644 index 0000000..2692893 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_EuroPC_Mono.woff diff --git a/moneyjsx/static/fonts/Web437_EverexME_5x8.woff b/moneyjsx/static/fonts/Web437_EverexME_5x8.woff Binary files differnew file mode 100644 index 0000000..1a84a60 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_EverexME_5x8.woff diff --git a/moneyjsx/static/fonts/Web437_EverexME_7x8.woff b/moneyjsx/static/fonts/Web437_EverexME_7x8.woff Binary files differnew file mode 100644 index 0000000..5b4c9d4 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_EverexME_7x8.woff diff --git a/moneyjsx/static/fonts/Web437_EverexME_8x16.woff b/moneyjsx/static/fonts/Web437_EverexME_8x16.woff Binary files differnew file mode 100644 index 0000000..1a47ea4 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_EverexME_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_FMTowns_re_8x16-2x.woff b/moneyjsx/static/fonts/Web437_FMTowns_re_8x16-2x.woff Binary files differnew file mode 100644 index 0000000..1424b2a --- /dev/null +++ b/moneyjsx/static/fonts/Web437_FMTowns_re_8x16-2x.woff diff --git a/moneyjsx/static/fonts/Web437_FMTowns_re_8x16.woff b/moneyjsx/static/fonts/Web437_FMTowns_re_8x16.woff Binary files differnew file mode 100644 index 0000000..702078a --- /dev/null +++ b/moneyjsx/static/fonts/Web437_FMTowns_re_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_FMTowns_re_8x8.woff b/moneyjsx/static/fonts/Web437_FMTowns_re_8x8.woff Binary files differnew file mode 100644 index 0000000..526cb89 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_FMTowns_re_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_HP_100LX_10x11.woff b/moneyjsx/static/fonts/Web437_HP_100LX_10x11.woff Binary files differnew file mode 100644 index 0000000..223e168 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_HP_100LX_10x11.woff diff --git a/moneyjsx/static/fonts/Web437_HP_100LX_16x12.woff b/moneyjsx/static/fonts/Web437_HP_100LX_16x12.woff Binary files differnew file mode 100644 index 0000000..2eaa62e --- /dev/null +++ b/moneyjsx/static/fonts/Web437_HP_100LX_16x12.woff diff --git a/moneyjsx/static/fonts/Web437_HP_100LX_6x8-2x.woff b/moneyjsx/static/fonts/Web437_HP_100LX_6x8-2x.woff Binary files differnew file mode 100644 index 0000000..3c48c55 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_HP_100LX_6x8-2x.woff diff --git a/moneyjsx/static/fonts/Web437_HP_100LX_6x8.woff b/moneyjsx/static/fonts/Web437_HP_100LX_6x8.woff Binary files differnew file mode 100644 index 0000000..5d6069c --- /dev/null +++ b/moneyjsx/static/fonts/Web437_HP_100LX_6x8.woff diff --git a/moneyjsx/static/fonts/Web437_HP_100LX_8x8-2x.woff b/moneyjsx/static/fonts/Web437_HP_100LX_8x8-2x.woff Binary files differnew file mode 100644 index 0000000..87304c6 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_HP_100LX_8x8-2x.woff diff --git a/moneyjsx/static/fonts/Web437_HP_100LX_8x8.woff b/moneyjsx/static/fonts/Web437_HP_100LX_8x8.woff Binary files differnew file mode 100644 index 0000000..f60db64 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_HP_100LX_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_HP_150_re.woff b/moneyjsx/static/fonts/Web437_HP_150_re.woff Binary files differnew file mode 100644 index 0000000..3eaaf6d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_HP_150_re.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_3270pc.woff b/moneyjsx/static/fonts/Web437_IBM_3270pc.woff Binary files differnew file mode 100644 index 0000000..fb9cd72 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_3270pc.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_BIOS-2x.woff b/moneyjsx/static/fonts/Web437_IBM_BIOS-2x.woff Binary files differnew file mode 100644 index 0000000..c5fe090 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_BIOS-2x.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_BIOS-2y.woff b/moneyjsx/static/fonts/Web437_IBM_BIOS-2y.woff Binary files differnew file mode 100644 index 0000000..860baf5 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_BIOS-2y.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_BIOS.woff b/moneyjsx/static/fonts/Web437_IBM_BIOS.woff Binary files differnew file mode 100644 index 0000000..9daecb3 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_BIOS.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_CGA-2y.woff b/moneyjsx/static/fonts/Web437_IBM_CGA-2y.woff Binary files differnew file mode 100644 index 0000000..5967b6f --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_CGA-2y.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_CGA.woff b/moneyjsx/static/fonts/Web437_IBM_CGA.woff Binary files differnew file mode 100644 index 0000000..fe8f17a --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_CGA.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_CGAthin-2y.woff b/moneyjsx/static/fonts/Web437_IBM_CGAthin-2y.woff Binary files differnew file mode 100644 index 0000000..99bd14a --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_CGAthin-2y.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_CGAthin.woff b/moneyjsx/static/fonts/Web437_IBM_CGAthin.woff Binary files differnew file mode 100644 index 0000000..c7efcf1 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_CGAthin.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_Conv-2x.woff b/moneyjsx/static/fonts/Web437_IBM_Conv-2x.woff Binary files differnew file mode 100644 index 0000000..6ffe99d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_Conv-2x.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_Conv-2y.woff b/moneyjsx/static/fonts/Web437_IBM_Conv-2y.woff Binary files differnew file mode 100644 index 0000000..9c07239 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_Conv-2y.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_Conv.woff b/moneyjsx/static/fonts/Web437_IBM_Conv.woff Binary files differnew file mode 100644 index 0000000..656f15a --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_Conv.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_DOS_ISO8-2x.woff b/moneyjsx/static/fonts/Web437_IBM_DOS_ISO8-2x.woff Binary files differnew file mode 100644 index 0000000..f40721f --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_DOS_ISO8-2x.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_DOS_ISO8.woff b/moneyjsx/static/fonts/Web437_IBM_DOS_ISO8.woff Binary files differnew file mode 100644 index 0000000..d5b9bac --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_DOS_ISO8.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_DOS_ISO9-2x.woff b/moneyjsx/static/fonts/Web437_IBM_DOS_ISO9-2x.woff Binary files differnew file mode 100644 index 0000000..e5f89ee --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_DOS_ISO9-2x.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_DOS_ISO9.woff b/moneyjsx/static/fonts/Web437_IBM_DOS_ISO9.woff Binary files differnew file mode 100644 index 0000000..fe3eda9 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_DOS_ISO9.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_EGA_8x14-2x.woff b/moneyjsx/static/fonts/Web437_IBM_EGA_8x14-2x.woff Binary files differnew file mode 100644 index 0000000..77b7fef --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_EGA_8x14-2x.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_EGA_8x14.woff b/moneyjsx/static/fonts/Web437_IBM_EGA_8x14.woff Binary files differnew file mode 100644 index 0000000..84efc99 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_EGA_8x14.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_EGA_8x8-2x.woff b/moneyjsx/static/fonts/Web437_IBM_EGA_8x8-2x.woff Binary files differnew file mode 100644 index 0000000..63de4fb --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_EGA_8x8-2x.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_EGA_8x8.woff b/moneyjsx/static/fonts/Web437_IBM_EGA_8x8.woff Binary files differnew file mode 100644 index 0000000..35506d2 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_EGA_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_EGA_9x14-2x.woff b/moneyjsx/static/fonts/Web437_IBM_EGA_9x14-2x.woff Binary files differnew file mode 100644 index 0000000..c301231 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_EGA_9x14-2x.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_EGA_9x14.woff b/moneyjsx/static/fonts/Web437_IBM_EGA_9x14.woff Binary files differnew file mode 100644 index 0000000..e70ffa2 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_EGA_9x14.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_EGA_9x8-2x.woff b/moneyjsx/static/fonts/Web437_IBM_EGA_9x8-2x.woff Binary files differnew file mode 100644 index 0000000..05a30bd --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_EGA_9x8-2x.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_EGA_9x8.woff b/moneyjsx/static/fonts/Web437_IBM_EGA_9x8.woff Binary files differnew file mode 100644 index 0000000..1e77b7e --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_EGA_9x8.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_MDA.woff b/moneyjsx/static/fonts/Web437_IBM_MDA.woff Binary files differnew file mode 100644 index 0000000..677f562 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_MDA.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_Model30r0-2x.woff b/moneyjsx/static/fonts/Web437_IBM_Model30r0-2x.woff Binary files differnew file mode 100644 index 0000000..1d5c9db --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_Model30r0-2x.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_Model30r0.woff b/moneyjsx/static/fonts/Web437_IBM_Model30r0.woff Binary files differnew file mode 100644 index 0000000..0756047 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_Model30r0.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_Model3x_Alt1.woff b/moneyjsx/static/fonts/Web437_IBM_Model3x_Alt1.woff Binary files differnew file mode 100644 index 0000000..de87cb1 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_Model3x_Alt1.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_Model3x_Alt2.woff b/moneyjsx/static/fonts/Web437_IBM_Model3x_Alt2.woff Binary files differnew file mode 100644 index 0000000..b088d34 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_Model3x_Alt2.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_Model3x_Alt3.woff b/moneyjsx/static/fonts/Web437_IBM_Model3x_Alt3.woff Binary files differnew file mode 100644 index 0000000..6f647d0 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_Model3x_Alt3.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_Model3x_Alt4.woff b/moneyjsx/static/fonts/Web437_IBM_Model3x_Alt4.woff Binary files differnew file mode 100644 index 0000000..26b82bc --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_Model3x_Alt4.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_PGC-2x.woff b/moneyjsx/static/fonts/Web437_IBM_PGC-2x.woff Binary files differnew file mode 100644 index 0000000..e0b4aaa --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_PGC-2x.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_PGC.woff b/moneyjsx/static/fonts/Web437_IBM_PGC.woff Binary files differnew file mode 100644 index 0000000..23a07a1 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_PGC.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_PS-55_re.woff b/moneyjsx/static/fonts/Web437_IBM_PS-55_re.woff Binary files differnew file mode 100644 index 0000000..09cfd77 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_PS-55_re.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_VGA_8x14-2x.woff b/moneyjsx/static/fonts/Web437_IBM_VGA_8x14-2x.woff Binary files differnew file mode 100644 index 0000000..60529c8 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_VGA_8x14-2x.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_VGA_8x14.woff b/moneyjsx/static/fonts/Web437_IBM_VGA_8x14.woff Binary files differnew file mode 100644 index 0000000..79c2b66 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_VGA_8x14.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_VGA_8x16-2x.woff b/moneyjsx/static/fonts/Web437_IBM_VGA_8x16-2x.woff Binary files differnew file mode 100644 index 0000000..894dc88 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_VGA_8x16-2x.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_VGA_8x16.woff b/moneyjsx/static/fonts/Web437_IBM_VGA_8x16.woff Binary files differnew file mode 100644 index 0000000..1f1508d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_VGA_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_VGA_9x14-2x.woff b/moneyjsx/static/fonts/Web437_IBM_VGA_9x14-2x.woff Binary files differnew file mode 100644 index 0000000..1b1184f --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_VGA_9x14-2x.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_VGA_9x14.woff b/moneyjsx/static/fonts/Web437_IBM_VGA_9x14.woff Binary files differnew file mode 100644 index 0000000..3cea8b2 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_VGA_9x14.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_VGA_9x16-2x.woff b/moneyjsx/static/fonts/Web437_IBM_VGA_9x16-2x.woff Binary files differnew file mode 100644 index 0000000..34cdcf8 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_VGA_9x16-2x.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_VGA_9x16.woff b/moneyjsx/static/fonts/Web437_IBM_VGA_9x16.woff Binary files differnew file mode 100644 index 0000000..8ff3510 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_VGA_9x16.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_VGA_9x8-2x.woff b/moneyjsx/static/fonts/Web437_IBM_VGA_9x8-2x.woff Binary files differnew file mode 100644 index 0000000..0a5b0c2 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_VGA_9x8-2x.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_VGA_9x8.woff b/moneyjsx/static/fonts/Web437_IBM_VGA_9x8.woff Binary files differnew file mode 100644 index 0000000..a79352d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_VGA_9x8.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_XGA-AI_12x20.woff b/moneyjsx/static/fonts/Web437_IBM_XGA-AI_12x20.woff Binary files differnew file mode 100644 index 0000000..dab7e96 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_XGA-AI_12x20.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_XGA-AI_12x23.woff b/moneyjsx/static/fonts/Web437_IBM_XGA-AI_12x23.woff Binary files differnew file mode 100644 index 0000000..d9e764d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_XGA-AI_12x23.woff diff --git a/moneyjsx/static/fonts/Web437_IBM_XGA-AI_7x15.woff b/moneyjsx/static/fonts/Web437_IBM_XGA-AI_7x15.woff Binary files differnew file mode 100644 index 0000000..6faa01f --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IBM_XGA-AI_7x15.woff diff --git a/moneyjsx/static/fonts/Web437_IGS_VGA_8x16.woff b/moneyjsx/static/fonts/Web437_IGS_VGA_8x16.woff Binary files differnew file mode 100644 index 0000000..6e0104b --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IGS_VGA_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_IGS_VGA_9x16.woff b/moneyjsx/static/fonts/Web437_IGS_VGA_9x16.woff Binary files differnew file mode 100644 index 0000000..8521543 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_IGS_VGA_9x16.woff diff --git a/moneyjsx/static/fonts/Web437_ITT_Xtra-2y.woff b/moneyjsx/static/fonts/Web437_ITT_Xtra-2y.woff Binary files differnew file mode 100644 index 0000000..af66678 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ITT_Xtra-2y.woff diff --git a/moneyjsx/static/fonts/Web437_ITT_Xtra.woff b/moneyjsx/static/fonts/Web437_ITT_Xtra.woff Binary files differnew file mode 100644 index 0000000..37e10f6 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ITT_Xtra.woff diff --git a/moneyjsx/static/fonts/Web437_Kaypro2K_G-2y.woff b/moneyjsx/static/fonts/Web437_Kaypro2K_G-2y.woff Binary files differnew file mode 100644 index 0000000..9e5b7aa --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Kaypro2K_G-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Kaypro2K_G.woff b/moneyjsx/static/fonts/Web437_Kaypro2K_G.woff Binary files differnew file mode 100644 index 0000000..de7a0e9 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Kaypro2K_G.woff diff --git a/moneyjsx/static/fonts/Web437_LE_Model_D_CGA-2y.woff b/moneyjsx/static/fonts/Web437_LE_Model_D_CGA-2y.woff Binary files differnew file mode 100644 index 0000000..a34026e --- /dev/null +++ b/moneyjsx/static/fonts/Web437_LE_Model_D_CGA-2y.woff diff --git a/moneyjsx/static/fonts/Web437_LE_Model_D_CGA.woff b/moneyjsx/static/fonts/Web437_LE_Model_D_CGA.woff Binary files differnew file mode 100644 index 0000000..6d7e05a --- /dev/null +++ b/moneyjsx/static/fonts/Web437_LE_Model_D_CGA.woff diff --git a/moneyjsx/static/fonts/Web437_LE_Model_D_Mono.woff b/moneyjsx/static/fonts/Web437_LE_Model_D_Mono.woff Binary files differnew file mode 100644 index 0000000..a464a1d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_LE_Model_D_Mono.woff diff --git a/moneyjsx/static/fonts/Web437_MBytePC230_8x16.woff b/moneyjsx/static/fonts/Web437_MBytePC230_8x16.woff Binary files differnew file mode 100644 index 0000000..14ed558 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_MBytePC230_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_MBytePC230_CGA-2y.woff b/moneyjsx/static/fonts/Web437_MBytePC230_CGA-2y.woff Binary files differnew file mode 100644 index 0000000..ba95952 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_MBytePC230_CGA-2y.woff diff --git a/moneyjsx/static/fonts/Web437_MBytePC230_CGA.woff b/moneyjsx/static/fonts/Web437_MBytePC230_CGA.woff Binary files differnew file mode 100644 index 0000000..a5cc805 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_MBytePC230_CGA.woff diff --git a/moneyjsx/static/fonts/Web437_MBytePC230_EGA.woff b/moneyjsx/static/fonts/Web437_MBytePC230_EGA.woff Binary files differnew file mode 100644 index 0000000..c896ad5 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_MBytePC230_EGA.woff diff --git a/moneyjsx/static/fonts/Web437_MBytePC230_Mono.woff b/moneyjsx/static/fonts/Web437_MBytePC230_Mono.woff Binary files differnew file mode 100644 index 0000000..6d9ea1e --- /dev/null +++ b/moneyjsx/static/fonts/Web437_MBytePC230_Mono.woff diff --git a/moneyjsx/static/fonts/Web437_Master_512-2y.woff b/moneyjsx/static/fonts/Web437_Master_512-2y.woff Binary files differnew file mode 100644 index 0000000..0622dde --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Master_512-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Master_512-2y_bold.woff b/moneyjsx/static/fonts/Web437_Master_512-2y_bold.woff Binary files differnew file mode 100644 index 0000000..3c75008 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Master_512-2y_bold.woff diff --git a/moneyjsx/static/fonts/Web437_Master_512-M7.woff b/moneyjsx/static/fonts/Web437_Master_512-M7.woff Binary files differnew file mode 100644 index 0000000..750bb88 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Master_512-M7.woff diff --git a/moneyjsx/static/fonts/Web437_Master_512-M7_bold.woff b/moneyjsx/static/fonts/Web437_Master_512-M7_bold.woff Binary files differnew file mode 100644 index 0000000..74e54fe --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Master_512-M7_bold.woff diff --git a/moneyjsx/static/fonts/Web437_Master_512.woff b/moneyjsx/static/fonts/Web437_Master_512.woff Binary files differnew file mode 100644 index 0000000..e37dd6f --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Master_512.woff diff --git a/moneyjsx/static/fonts/Web437_Master_512_bold.woff b/moneyjsx/static/fonts/Web437_Master_512_bold.woff Binary files differnew file mode 100644 index 0000000..d3be3bc --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Master_512_bold.woff diff --git a/moneyjsx/static/fonts/Web437_Mindset-2x.woff b/moneyjsx/static/fonts/Web437_Mindset-2x.woff Binary files differnew file mode 100644 index 0000000..792b938 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Mindset-2x.woff diff --git a/moneyjsx/static/fonts/Web437_Mindset-2y.woff b/moneyjsx/static/fonts/Web437_Mindset-2y.woff Binary files differnew file mode 100644 index 0000000..7536e50 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Mindset-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Mindset.woff b/moneyjsx/static/fonts/Web437_Mindset.woff Binary files differnew file mode 100644 index 0000000..8401df9 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Mindset.woff diff --git a/moneyjsx/static/fonts/Web437_NEC_APC3_8x16-2x.woff b/moneyjsx/static/fonts/Web437_NEC_APC3_8x16-2x.woff Binary files differnew file mode 100644 index 0000000..a6977d8 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_NEC_APC3_8x16-2x.woff diff --git a/moneyjsx/static/fonts/Web437_NEC_APC3_8x16.woff b/moneyjsx/static/fonts/Web437_NEC_APC3_8x16.woff Binary files differnew file mode 100644 index 0000000..cb06dd7 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_NEC_APC3_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_NEC_APC3_8x8-2y.woff b/moneyjsx/static/fonts/Web437_NEC_APC3_8x8-2y.woff Binary files differnew file mode 100644 index 0000000..8efe53a --- /dev/null +++ b/moneyjsx/static/fonts/Web437_NEC_APC3_8x8-2y.woff diff --git a/moneyjsx/static/fonts/Web437_NEC_APC3_8x8.woff b/moneyjsx/static/fonts/Web437_NEC_APC3_8x8.woff Binary files differnew file mode 100644 index 0000000..06728ce --- /dev/null +++ b/moneyjsx/static/fonts/Web437_NEC_APC3_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_NEC_MultiSpeed-2x.woff b/moneyjsx/static/fonts/Web437_NEC_MultiSpeed-2x.woff Binary files differnew file mode 100644 index 0000000..69d4399 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_NEC_MultiSpeed-2x.woff diff --git a/moneyjsx/static/fonts/Web437_NEC_MultiSpeed-2x_bold.woff b/moneyjsx/static/fonts/Web437_NEC_MultiSpeed-2x_bold.woff Binary files differnew file mode 100644 index 0000000..16688dd --- /dev/null +++ b/moneyjsx/static/fonts/Web437_NEC_MultiSpeed-2x_bold.woff diff --git a/moneyjsx/static/fonts/Web437_NEC_MultiSpeed.woff b/moneyjsx/static/fonts/Web437_NEC_MultiSpeed.woff Binary files differnew file mode 100644 index 0000000..8028efd --- /dev/null +++ b/moneyjsx/static/fonts/Web437_NEC_MultiSpeed.woff diff --git a/moneyjsx/static/fonts/Web437_NEC_MultiSpeed_bold.woff b/moneyjsx/static/fonts/Web437_NEC_MultiSpeed_bold.woff Binary files differnew file mode 100644 index 0000000..38e0287 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_NEC_MultiSpeed_bold.woff diff --git a/moneyjsx/static/fonts/Web437_Nix8810_M15.woff b/moneyjsx/static/fonts/Web437_Nix8810_M15.woff Binary files differnew file mode 100644 index 0000000..b452fbf --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Nix8810_M15.woff diff --git a/moneyjsx/static/fonts/Web437_Nix8810_M16.woff b/moneyjsx/static/fonts/Web437_Nix8810_M16.woff Binary files differnew file mode 100644 index 0000000..45f2b56 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Nix8810_M16.woff diff --git a/moneyjsx/static/fonts/Web437_Nix8810_M35-2y.woff b/moneyjsx/static/fonts/Web437_Nix8810_M35-2y.woff Binary files differnew file mode 100644 index 0000000..2c564f3 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Nix8810_M35-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Nix8810_M35.woff b/moneyjsx/static/fonts/Web437_Nix8810_M35.woff Binary files differnew file mode 100644 index 0000000..433bac3 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Nix8810_M35.woff diff --git a/moneyjsx/static/fonts/Web437_OlivettiThin_8x14.woff b/moneyjsx/static/fonts/Web437_OlivettiThin_8x14.woff Binary files differnew file mode 100644 index 0000000..96a3803 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_OlivettiThin_8x14.woff diff --git a/moneyjsx/static/fonts/Web437_OlivettiThin_8x16.woff b/moneyjsx/static/fonts/Web437_OlivettiThin_8x16.woff Binary files differnew file mode 100644 index 0000000..9a6c9d7 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_OlivettiThin_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_OlivettiThin_9x14.woff b/moneyjsx/static/fonts/Web437_OlivettiThin_9x14.woff Binary files differnew file mode 100644 index 0000000..b43b457 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_OlivettiThin_9x14.woff diff --git a/moneyjsx/static/fonts/Web437_OlivettiThin_9x16.woff b/moneyjsx/static/fonts/Web437_OlivettiThin_9x16.woff Binary files differnew file mode 100644 index 0000000..8686839 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_OlivettiThin_9x16.woff diff --git a/moneyjsx/static/fonts/Web437_Olivetti_M15-2y.woff b/moneyjsx/static/fonts/Web437_Olivetti_M15-2y.woff Binary files differnew file mode 100644 index 0000000..41b83b2 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Olivetti_M15-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Olivetti_M15.woff b/moneyjsx/static/fonts/Web437_Olivetti_M15.woff Binary files differnew file mode 100644 index 0000000..212a1a8 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Olivetti_M15.woff diff --git a/moneyjsx/static/fonts/Web437_Paradise132_7x16.woff b/moneyjsx/static/fonts/Web437_Paradise132_7x16.woff Binary files differnew file mode 100644 index 0000000..2470eed --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Paradise132_7x16.woff diff --git a/moneyjsx/static/fonts/Web437_Paradise132_7x9.woff b/moneyjsx/static/fonts/Web437_Paradise132_7x9.woff Binary files differnew file mode 100644 index 0000000..3c6c103 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Paradise132_7x9.woff diff --git a/moneyjsx/static/fonts/Web437_Philips_YES_G-2x.woff b/moneyjsx/static/fonts/Web437_Philips_YES_G-2x.woff Binary files differnew file mode 100644 index 0000000..ca1e9df --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Philips_YES_G-2x.woff diff --git a/moneyjsx/static/fonts/Web437_Philips_YES_G-2y.woff b/moneyjsx/static/fonts/Web437_Philips_YES_G-2y.woff Binary files differnew file mode 100644 index 0000000..d6c2808 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Philips_YES_G-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Philips_YES_G.woff b/moneyjsx/static/fonts/Web437_Philips_YES_G.woff Binary files differnew file mode 100644 index 0000000..09a7767 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Philips_YES_G.woff diff --git a/moneyjsx/static/fonts/Web437_Philips_YES_T-2y.woff b/moneyjsx/static/fonts/Web437_Philips_YES_T-2y.woff Binary files differnew file mode 100644 index 0000000..ecba3fd --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Philips_YES_T-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Philips_YES_T.woff b/moneyjsx/static/fonts/Web437_Philips_YES_T.woff Binary files differnew file mode 100644 index 0000000..fdc0c83 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Philips_YES_T.woff diff --git a/moneyjsx/static/fonts/Web437_PhoenixEGA_8x14.woff b/moneyjsx/static/fonts/Web437_PhoenixEGA_8x14.woff Binary files differnew file mode 100644 index 0000000..56bf74c --- /dev/null +++ b/moneyjsx/static/fonts/Web437_PhoenixEGA_8x14.woff diff --git a/moneyjsx/static/fonts/Web437_PhoenixEGA_8x16.woff b/moneyjsx/static/fonts/Web437_PhoenixEGA_8x16.woff Binary files differnew file mode 100644 index 0000000..6ff3f0c --- /dev/null +++ b/moneyjsx/static/fonts/Web437_PhoenixEGA_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_PhoenixEGA_8x8-2y.woff b/moneyjsx/static/fonts/Web437_PhoenixEGA_8x8-2y.woff Binary files differnew file mode 100644 index 0000000..8bb59df --- /dev/null +++ b/moneyjsx/static/fonts/Web437_PhoenixEGA_8x8-2y.woff diff --git a/moneyjsx/static/fonts/Web437_PhoenixEGA_8x8.woff b/moneyjsx/static/fonts/Web437_PhoenixEGA_8x8.woff Binary files differnew file mode 100644 index 0000000..9609a47 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_PhoenixEGA_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_PhoenixEGA_9x14.woff b/moneyjsx/static/fonts/Web437_PhoenixEGA_9x14.woff Binary files differnew file mode 100644 index 0000000..1222a9d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_PhoenixEGA_9x14.woff diff --git a/moneyjsx/static/fonts/Web437_PhoenixVGA_8x14.woff b/moneyjsx/static/fonts/Web437_PhoenixVGA_8x14.woff Binary files differnew file mode 100644 index 0000000..5ac2522 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_PhoenixVGA_8x14.woff diff --git a/moneyjsx/static/fonts/Web437_PhoenixVGA_8x16.woff b/moneyjsx/static/fonts/Web437_PhoenixVGA_8x16.woff Binary files differnew file mode 100644 index 0000000..9ac9959 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_PhoenixVGA_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_PhoenixVGA_8x8.woff b/moneyjsx/static/fonts/Web437_PhoenixVGA_8x8.woff Binary files differnew file mode 100644 index 0000000..80bef7d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_PhoenixVGA_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_PhoenixVGA_9x14.woff b/moneyjsx/static/fonts/Web437_PhoenixVGA_9x14.woff Binary files differnew file mode 100644 index 0000000..0aaf954 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_PhoenixVGA_9x14.woff diff --git a/moneyjsx/static/fonts/Web437_PhoenixVGA_9x16.woff b/moneyjsx/static/fonts/Web437_PhoenixVGA_9x16.woff Binary files differnew file mode 100644 index 0000000..644d6fb --- /dev/null +++ b/moneyjsx/static/fonts/Web437_PhoenixVGA_9x16.woff diff --git a/moneyjsx/static/fonts/Web437_PhoenixVGA_9x8.woff b/moneyjsx/static/fonts/Web437_PhoenixVGA_9x8.woff Binary files differnew file mode 100644 index 0000000..0d85e6d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_PhoenixVGA_9x8.woff diff --git a/moneyjsx/static/fonts/Web437_Phoenix_BIOS-2y.woff b/moneyjsx/static/fonts/Web437_Phoenix_BIOS-2y.woff Binary files differnew file mode 100644 index 0000000..e849ae8 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Phoenix_BIOS-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Phoenix_BIOS.woff b/moneyjsx/static/fonts/Web437_Phoenix_BIOS.woff Binary files differnew file mode 100644 index 0000000..75a0b5e --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Phoenix_BIOS.woff diff --git a/moneyjsx/static/fonts/Web437_Portfolio_6x8.woff b/moneyjsx/static/fonts/Web437_Portfolio_6x8.woff Binary files differnew file mode 100644 index 0000000..6f39add --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Portfolio_6x8.woff diff --git a/moneyjsx/static/fonts/Web437_RM_Nimbus-2y.woff b/moneyjsx/static/fonts/Web437_RM_Nimbus-2y.woff Binary files differnew file mode 100644 index 0000000..e6f5173 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_RM_Nimbus-2y.woff diff --git a/moneyjsx/static/fonts/Web437_RM_Nimbus.woff b/moneyjsx/static/fonts/Web437_RM_Nimbus.woff Binary files differnew file mode 100644 index 0000000..12aac90 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_RM_Nimbus.woff diff --git a/moneyjsx/static/fonts/Web437_Rainbow100_re_132.woff b/moneyjsx/static/fonts/Web437_Rainbow100_re_132.woff Binary files differnew file mode 100644 index 0000000..43de2a2 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Rainbow100_re_132.woff diff --git a/moneyjsx/static/fonts/Web437_Rainbow100_re_40.woff b/moneyjsx/static/fonts/Web437_Rainbow100_re_40.woff Binary files differnew file mode 100644 index 0000000..e7203cf --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Rainbow100_re_40.woff diff --git a/moneyjsx/static/fonts/Web437_Rainbow100_re_66.woff b/moneyjsx/static/fonts/Web437_Rainbow100_re_66.woff Binary files differnew file mode 100644 index 0000000..b1d0884 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Rainbow100_re_66.woff diff --git a/moneyjsx/static/fonts/Web437_Rainbow100_re_80.woff b/moneyjsx/static/fonts/Web437_Rainbow100_re_80.woff Binary files differnew file mode 100644 index 0000000..19b6dbb --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Rainbow100_re_80.woff diff --git a/moneyjsx/static/fonts/Web437_Robotron_A7100.woff b/moneyjsx/static/fonts/Web437_Robotron_A7100.woff Binary files differnew file mode 100644 index 0000000..03e311d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Robotron_A7100.woff diff --git a/moneyjsx/static/fonts/Web437_STB_AutoEGA_8x14.woff b/moneyjsx/static/fonts/Web437_STB_AutoEGA_8x14.woff Binary files differnew file mode 100644 index 0000000..7f88003 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_STB_AutoEGA_8x14.woff diff --git a/moneyjsx/static/fonts/Web437_STB_AutoEGA_9x14.woff b/moneyjsx/static/fonts/Web437_STB_AutoEGA_9x14.woff Binary files differnew file mode 100644 index 0000000..5b51b23 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_STB_AutoEGA_9x14.woff diff --git a/moneyjsx/static/fonts/Web437_SanyoMBC16-2y.woff b/moneyjsx/static/fonts/Web437_SanyoMBC16-2y.woff Binary files differnew file mode 100644 index 0000000..9da6d1e --- /dev/null +++ b/moneyjsx/static/fonts/Web437_SanyoMBC16-2y.woff diff --git a/moneyjsx/static/fonts/Web437_SanyoMBC16.woff b/moneyjsx/static/fonts/Web437_SanyoMBC16.woff Binary files differnew file mode 100644 index 0000000..966c868 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_SanyoMBC16.woff diff --git a/moneyjsx/static/fonts/Web437_SanyoMBC55x-2y.woff b/moneyjsx/static/fonts/Web437_SanyoMBC55x-2y.woff Binary files differnew file mode 100644 index 0000000..a3fb0cb --- /dev/null +++ b/moneyjsx/static/fonts/Web437_SanyoMBC55x-2y.woff diff --git a/moneyjsx/static/fonts/Web437_SanyoMBC55x.woff b/moneyjsx/static/fonts/Web437_SanyoMBC55x.woff Binary files differnew file mode 100644 index 0000000..38203b6 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_SanyoMBC55x.woff diff --git a/moneyjsx/static/fonts/Web437_SanyoMBC775-2y.woff b/moneyjsx/static/fonts/Web437_SanyoMBC775-2y.woff Binary files differnew file mode 100644 index 0000000..39ed8fa --- /dev/null +++ b/moneyjsx/static/fonts/Web437_SanyoMBC775-2y.woff diff --git a/moneyjsx/static/fonts/Web437_SanyoMBC775.woff b/moneyjsx/static/fonts/Web437_SanyoMBC775.woff Binary files differnew file mode 100644 index 0000000..4daa0a8 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_SanyoMBC775.woff diff --git a/moneyjsx/static/fonts/Web437_SeequaCm-2y.woff b/moneyjsx/static/fonts/Web437_SeequaCm-2y.woff Binary files differnew file mode 100644 index 0000000..d099ecd --- /dev/null +++ b/moneyjsx/static/fonts/Web437_SeequaCm-2y.woff diff --git a/moneyjsx/static/fonts/Web437_SeequaCm.woff b/moneyjsx/static/fonts/Web437_SeequaCm.woff Binary files differnew file mode 100644 index 0000000..e598bc3 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_SeequaCm.woff diff --git a/moneyjsx/static/fonts/Web437_Sharp_PC3K-2x.woff b/moneyjsx/static/fonts/Web437_Sharp_PC3K-2x.woff Binary files differnew file mode 100644 index 0000000..57e9047 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Sharp_PC3K-2x.woff diff --git a/moneyjsx/static/fonts/Web437_Sharp_PC3K.woff b/moneyjsx/static/fonts/Web437_Sharp_PC3K.woff Binary files differnew file mode 100644 index 0000000..8ba5b50 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Sharp_PC3K.woff diff --git a/moneyjsx/static/fonts/Web437_Sharp_PC3K_Alt-2x.woff b/moneyjsx/static/fonts/Web437_Sharp_PC3K_Alt-2x.woff Binary files differnew file mode 100644 index 0000000..932d65b --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Sharp_PC3K_Alt-2x.woff diff --git a/moneyjsx/static/fonts/Web437_Sharp_PC3K_Alt.woff b/moneyjsx/static/fonts/Web437_Sharp_PC3K_Alt.woff Binary files differnew file mode 100644 index 0000000..32759f1 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Sharp_PC3K_Alt.woff diff --git a/moneyjsx/static/fonts/Web437_Siemens_PC-D.woff b/moneyjsx/static/fonts/Web437_Siemens_PC-D.woff Binary files differnew file mode 100644 index 0000000..8865075 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Siemens_PC-D.woff diff --git a/moneyjsx/static/fonts/Web437_Sigma_RM_8x14.woff b/moneyjsx/static/fonts/Web437_Sigma_RM_8x14.woff Binary files differnew file mode 100644 index 0000000..626a260 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Sigma_RM_8x14.woff diff --git a/moneyjsx/static/fonts/Web437_Sigma_RM_8x16.woff b/moneyjsx/static/fonts/Web437_Sigma_RM_8x16.woff Binary files differnew file mode 100644 index 0000000..de40fdf --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Sigma_RM_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_Sigma_RM_8x8.woff b/moneyjsx/static/fonts/Web437_Sigma_RM_8x8.woff Binary files differnew file mode 100644 index 0000000..d87ce1a --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Sigma_RM_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_Sigma_RM_9x14.woff b/moneyjsx/static/fonts/Web437_Sigma_RM_9x14.woff Binary files differnew file mode 100644 index 0000000..cf7e8c5 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Sigma_RM_9x14.woff diff --git a/moneyjsx/static/fonts/Web437_Sigma_RM_9x16.woff b/moneyjsx/static/fonts/Web437_Sigma_RM_9x16.woff Binary files differnew file mode 100644 index 0000000..83b19c7 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Sigma_RM_9x16.woff diff --git a/moneyjsx/static/fonts/Web437_Sigma_RM_9x8.woff b/moneyjsx/static/fonts/Web437_Sigma_RM_9x8.woff Binary files differnew file mode 100644 index 0000000..10f4346 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Sigma_RM_9x8.woff diff --git a/moneyjsx/static/fonts/Web437_SperryPC_8x16.woff b/moneyjsx/static/fonts/Web437_SperryPC_8x16.woff Binary files differnew file mode 100644 index 0000000..4b92b23 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_SperryPC_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_SperryPC_CGA-2y.woff b/moneyjsx/static/fonts/Web437_SperryPC_CGA-2y.woff Binary files differnew file mode 100644 index 0000000..22fd7fb --- /dev/null +++ b/moneyjsx/static/fonts/Web437_SperryPC_CGA-2y.woff diff --git a/moneyjsx/static/fonts/Web437_SperryPC_CGA.woff b/moneyjsx/static/fonts/Web437_SperryPC_CGA.woff Binary files differnew file mode 100644 index 0000000..f3c629d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_SperryPC_CGA.woff diff --git a/moneyjsx/static/fonts/Web437_Tandy1K-II_200L-2x.woff b/moneyjsx/static/fonts/Web437_Tandy1K-II_200L-2x.woff Binary files differnew file mode 100644 index 0000000..aa5daa6 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Tandy1K-II_200L-2x.woff diff --git a/moneyjsx/static/fonts/Web437_Tandy1K-II_200L-2y.woff b/moneyjsx/static/fonts/Web437_Tandy1K-II_200L-2y.woff Binary files differnew file mode 100644 index 0000000..8b973f6 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Tandy1K-II_200L-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Tandy1K-II_200L.woff b/moneyjsx/static/fonts/Web437_Tandy1K-II_200L.woff Binary files differnew file mode 100644 index 0000000..2bc34fa --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Tandy1K-II_200L.woff diff --git a/moneyjsx/static/fonts/Web437_Tandy1K-II_225L-2y.woff b/moneyjsx/static/fonts/Web437_Tandy1K-II_225L-2y.woff Binary files differnew file mode 100644 index 0000000..261d4de --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Tandy1K-II_225L-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Tandy1K-II_225L.woff b/moneyjsx/static/fonts/Web437_Tandy1K-II_225L.woff Binary files differnew file mode 100644 index 0000000..b7c45f8 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Tandy1K-II_225L.woff diff --git a/moneyjsx/static/fonts/Web437_Tandy1K-II_Mono.woff b/moneyjsx/static/fonts/Web437_Tandy1K-II_Mono.woff Binary files differnew file mode 100644 index 0000000..4c11e44 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Tandy1K-II_Mono.woff diff --git a/moneyjsx/static/fonts/Web437_Tandy1K-I_200L-2x.woff b/moneyjsx/static/fonts/Web437_Tandy1K-I_200L-2x.woff Binary files differnew file mode 100644 index 0000000..e52ddd0 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Tandy1K-I_200L-2x.woff diff --git a/moneyjsx/static/fonts/Web437_Tandy1K-I_200L-2y.woff b/moneyjsx/static/fonts/Web437_Tandy1K-I_200L-2y.woff Binary files differnew file mode 100644 index 0000000..eec2274 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Tandy1K-I_200L-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Tandy1K-I_200L.woff b/moneyjsx/static/fonts/Web437_Tandy1K-I_200L.woff Binary files differnew file mode 100644 index 0000000..cdc9196 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Tandy1K-I_200L.woff diff --git a/moneyjsx/static/fonts/Web437_Tandy1K-I_225L-2y.woff b/moneyjsx/static/fonts/Web437_Tandy1K-I_225L-2y.woff Binary files differnew file mode 100644 index 0000000..6c8e2c1 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Tandy1K-I_225L-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Tandy1K-I_225L.woff b/moneyjsx/static/fonts/Web437_Tandy1K-I_225L.woff Binary files differnew file mode 100644 index 0000000..c7d6dbb --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Tandy1K-I_225L.woff diff --git a/moneyjsx/static/fonts/Web437_Tandy2K-2x.woff b/moneyjsx/static/fonts/Web437_Tandy2K-2x.woff Binary files differnew file mode 100644 index 0000000..8b2f99c --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Tandy2K-2x.woff diff --git a/moneyjsx/static/fonts/Web437_Tandy2K.woff b/moneyjsx/static/fonts/Web437_Tandy2K.woff Binary files differnew file mode 100644 index 0000000..04634bf --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Tandy2K.woff diff --git a/moneyjsx/static/fonts/Web437_Tandy2K_G-2x.woff b/moneyjsx/static/fonts/Web437_Tandy2K_G-2x.woff Binary files differnew file mode 100644 index 0000000..bf62bb3 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Tandy2K_G-2x.woff diff --git a/moneyjsx/static/fonts/Web437_Tandy2K_G-TV.woff b/moneyjsx/static/fonts/Web437_Tandy2K_G-TV.woff Binary files differnew file mode 100644 index 0000000..213bc99 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Tandy2K_G-TV.woff diff --git a/moneyjsx/static/fonts/Web437_Tandy2K_G.woff b/moneyjsx/static/fonts/Web437_Tandy2K_G.woff Binary files differnew file mode 100644 index 0000000..ec4dd96 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Tandy2K_G.woff diff --git a/moneyjsx/static/fonts/Web437_TelePC-2y.woff b/moneyjsx/static/fonts/Web437_TelePC-2y.woff Binary files differnew file mode 100644 index 0000000..3f1da5d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_TelePC-2y.woff diff --git a/moneyjsx/static/fonts/Web437_TelePC.woff b/moneyjsx/static/fonts/Web437_TelePC.woff Binary files differnew file mode 100644 index 0000000..bb25c9c --- /dev/null +++ b/moneyjsx/static/fonts/Web437_TelePC.woff diff --git a/moneyjsx/static/fonts/Web437_Ti_Pro.woff b/moneyjsx/static/fonts/Web437_Ti_Pro.woff Binary files differnew file mode 100644 index 0000000..1d8fb0e --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Ti_Pro.woff diff --git a/moneyjsx/static/fonts/Web437_ToshibaSat_8x14.woff b/moneyjsx/static/fonts/Web437_ToshibaSat_8x14.woff Binary files differnew file mode 100644 index 0000000..2e05675 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ToshibaSat_8x14.woff diff --git a/moneyjsx/static/fonts/Web437_ToshibaSat_8x16.woff b/moneyjsx/static/fonts/Web437_ToshibaSat_8x16.woff Binary files differnew file mode 100644 index 0000000..99735df --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ToshibaSat_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_ToshibaSat_8x8.woff b/moneyjsx/static/fonts/Web437_ToshibaSat_8x8.woff Binary files differnew file mode 100644 index 0000000..92e9dc2 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ToshibaSat_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_ToshibaSat_9x14.woff b/moneyjsx/static/fonts/Web437_ToshibaSat_9x14.woff Binary files differnew file mode 100644 index 0000000..6c6dab6 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ToshibaSat_9x14.woff diff --git a/moneyjsx/static/fonts/Web437_ToshibaSat_9x16.woff b/moneyjsx/static/fonts/Web437_ToshibaSat_9x16.woff Binary files differnew file mode 100644 index 0000000..482da55 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ToshibaSat_9x16.woff diff --git a/moneyjsx/static/fonts/Web437_ToshibaSat_9x8.woff b/moneyjsx/static/fonts/Web437_ToshibaSat_9x8.woff Binary files differnew file mode 100644 index 0000000..1c19f2d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ToshibaSat_9x8.woff diff --git a/moneyjsx/static/fonts/Web437_ToshibaT300_8x16.woff b/moneyjsx/static/fonts/Web437_ToshibaT300_8x16.woff Binary files differnew file mode 100644 index 0000000..2a93b1f --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ToshibaT300_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_ToshibaT300_8x8-2y.woff b/moneyjsx/static/fonts/Web437_ToshibaT300_8x8-2y.woff Binary files differnew file mode 100644 index 0000000..c809330 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ToshibaT300_8x8-2y.woff diff --git a/moneyjsx/static/fonts/Web437_ToshibaT300_8x8.woff b/moneyjsx/static/fonts/Web437_ToshibaT300_8x8.woff Binary files differnew file mode 100644 index 0000000..3b8d7f1 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ToshibaT300_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_ToshibaTxL1_8x16.woff b/moneyjsx/static/fonts/Web437_ToshibaTxL1_8x16.woff Binary files differnew file mode 100644 index 0000000..f900627 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ToshibaTxL1_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_ToshibaTxL1_8x8.woff b/moneyjsx/static/fonts/Web437_ToshibaTxL1_8x8.woff Binary files differnew file mode 100644 index 0000000..cbd7cec --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ToshibaTxL1_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_ToshibaTxL2_8x16.woff b/moneyjsx/static/fonts/Web437_ToshibaTxL2_8x16.woff Binary files differnew file mode 100644 index 0000000..f7e5c74 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ToshibaTxL2_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_ToshibaTxL2_8x8.woff b/moneyjsx/static/fonts/Web437_ToshibaTxL2_8x8.woff Binary files differnew file mode 100644 index 0000000..a472b0b --- /dev/null +++ b/moneyjsx/static/fonts/Web437_ToshibaTxL2_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_TridentEarly_8x11.woff b/moneyjsx/static/fonts/Web437_TridentEarly_8x11.woff Binary files differnew file mode 100644 index 0000000..5474176 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_TridentEarly_8x11.woff diff --git a/moneyjsx/static/fonts/Web437_TridentEarly_8x14.woff b/moneyjsx/static/fonts/Web437_TridentEarly_8x14.woff Binary files differnew file mode 100644 index 0000000..97daa2e --- /dev/null +++ b/moneyjsx/static/fonts/Web437_TridentEarly_8x14.woff diff --git a/moneyjsx/static/fonts/Web437_TridentEarly_8x16.woff b/moneyjsx/static/fonts/Web437_TridentEarly_8x16.woff Binary files differnew file mode 100644 index 0000000..5e71f0e --- /dev/null +++ b/moneyjsx/static/fonts/Web437_TridentEarly_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_TridentEarly_8x8.woff b/moneyjsx/static/fonts/Web437_TridentEarly_8x8.woff Binary files differnew file mode 100644 index 0000000..e116dd3 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_TridentEarly_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_TridentEarly_9x14.woff b/moneyjsx/static/fonts/Web437_TridentEarly_9x14.woff Binary files differnew file mode 100644 index 0000000..293de0a --- /dev/null +++ b/moneyjsx/static/fonts/Web437_TridentEarly_9x14.woff diff --git a/moneyjsx/static/fonts/Web437_TridentEarly_9x16.woff b/moneyjsx/static/fonts/Web437_TridentEarly_9x16.woff Binary files differnew file mode 100644 index 0000000..37d82a0 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_TridentEarly_9x16.woff diff --git a/moneyjsx/static/fonts/Web437_TridentEarly_9x8.woff b/moneyjsx/static/fonts/Web437_TridentEarly_9x8.woff Binary files differnew file mode 100644 index 0000000..3ff88db --- /dev/null +++ b/moneyjsx/static/fonts/Web437_TridentEarly_9x8.woff diff --git a/moneyjsx/static/fonts/Web437_Trident_8x11.woff b/moneyjsx/static/fonts/Web437_Trident_8x11.woff Binary files differnew file mode 100644 index 0000000..d5d52b1 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Trident_8x11.woff diff --git a/moneyjsx/static/fonts/Web437_Trident_8x14.woff b/moneyjsx/static/fonts/Web437_Trident_8x14.woff Binary files differnew file mode 100644 index 0000000..98576fa --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Trident_8x14.woff diff --git a/moneyjsx/static/fonts/Web437_Trident_8x16.woff b/moneyjsx/static/fonts/Web437_Trident_8x16.woff Binary files differnew file mode 100644 index 0000000..708258c --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Trident_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_Trident_8x8.woff b/moneyjsx/static/fonts/Web437_Trident_8x8.woff Binary files differnew file mode 100644 index 0000000..8a7a2bd --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Trident_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_Trident_9x14.woff b/moneyjsx/static/fonts/Web437_Trident_9x14.woff Binary files differnew file mode 100644 index 0000000..3446e73 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Trident_9x14.woff diff --git a/moneyjsx/static/fonts/Web437_Trident_9x16.woff b/moneyjsx/static/fonts/Web437_Trident_9x16.woff Binary files differnew file mode 100644 index 0000000..da3a894 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Trident_9x16.woff diff --git a/moneyjsx/static/fonts/Web437_Trident_9x8.woff b/moneyjsx/static/fonts/Web437_Trident_9x8.woff Binary files differnew file mode 100644 index 0000000..adb4b74 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Trident_9x8.woff diff --git a/moneyjsx/static/fonts/Web437_TsengEVA_132_6x14.woff b/moneyjsx/static/fonts/Web437_TsengEVA_132_6x14.woff Binary files differnew file mode 100644 index 0000000..c90423a --- /dev/null +++ b/moneyjsx/static/fonts/Web437_TsengEVA_132_6x14.woff diff --git a/moneyjsx/static/fonts/Web437_TsengEVA_132_6x8.woff b/moneyjsx/static/fonts/Web437_TsengEVA_132_6x8.woff Binary files differnew file mode 100644 index 0000000..6042cf1 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_TsengEVA_132_6x8.woff diff --git a/moneyjsx/static/fonts/Web437_VTech_BIOS-2y.woff b/moneyjsx/static/fonts/Web437_VTech_BIOS-2y.woff Binary files differnew file mode 100644 index 0000000..3207a4d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_VTech_BIOS-2y.woff diff --git a/moneyjsx/static/fonts/Web437_VTech_BIOS.woff b/moneyjsx/static/fonts/Web437_VTech_BIOS.woff Binary files differnew file mode 100644 index 0000000..7585b4e --- /dev/null +++ b/moneyjsx/static/fonts/Web437_VTech_BIOS.woff diff --git a/moneyjsx/static/fonts/Web437_Verite_8x14.woff b/moneyjsx/static/fonts/Web437_Verite_8x14.woff Binary files differnew file mode 100644 index 0000000..a02281a --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Verite_8x14.woff diff --git a/moneyjsx/static/fonts/Web437_Verite_8x16.woff b/moneyjsx/static/fonts/Web437_Verite_8x16.woff Binary files differnew file mode 100644 index 0000000..00424a9 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Verite_8x16.woff diff --git a/moneyjsx/static/fonts/Web437_Verite_8x8-2y.woff b/moneyjsx/static/fonts/Web437_Verite_8x8-2y.woff Binary files differnew file mode 100644 index 0000000..316c481 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Verite_8x8-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Verite_8x8.woff b/moneyjsx/static/fonts/Web437_Verite_8x8.woff Binary files differnew file mode 100644 index 0000000..e6a3f67 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Verite_8x8.woff diff --git a/moneyjsx/static/fonts/Web437_Verite_9x14.woff b/moneyjsx/static/fonts/Web437_Verite_9x14.woff Binary files differnew file mode 100644 index 0000000..3c4c0bb --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Verite_9x14.woff diff --git a/moneyjsx/static/fonts/Web437_Verite_9x16.woff b/moneyjsx/static/fonts/Web437_Verite_9x16.woff Binary files differnew file mode 100644 index 0000000..c9da6f7 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Verite_9x16.woff diff --git a/moneyjsx/static/fonts/Web437_Verite_9x8.woff b/moneyjsx/static/fonts/Web437_Verite_9x8.woff Binary files differnew file mode 100644 index 0000000..ae2181c --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Verite_9x8.woff diff --git a/moneyjsx/static/fonts/Web437_Wang_Pro_Color-2y.woff b/moneyjsx/static/fonts/Web437_Wang_Pro_Color-2y.woff Binary files differnew file mode 100644 index 0000000..b3306bd --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Wang_Pro_Color-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Wang_Pro_Color.woff b/moneyjsx/static/fonts/Web437_Wang_Pro_Color.woff Binary files differnew file mode 100644 index 0000000..500f461 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Wang_Pro_Color.woff diff --git a/moneyjsx/static/fonts/Web437_Wang_Pro_Mono.woff b/moneyjsx/static/fonts/Web437_Wang_Pro_Mono.woff Binary files differnew file mode 100644 index 0000000..3e9162d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Wang_Pro_Mono.woff diff --git a/moneyjsx/static/fonts/Web437_Wyse700a-2y.woff b/moneyjsx/static/fonts/Web437_Wyse700a-2y.woff Binary files differnew file mode 100644 index 0000000..8bf060d --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Wyse700a-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Wyse700a.woff b/moneyjsx/static/fonts/Web437_Wyse700a.woff Binary files differnew file mode 100644 index 0000000..e1a8e6c --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Wyse700a.woff diff --git a/moneyjsx/static/fonts/Web437_Wyse700b-2y.woff b/moneyjsx/static/fonts/Web437_Wyse700b-2y.woff Binary files differnew file mode 100644 index 0000000..9003597 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Wyse700b-2y.woff diff --git a/moneyjsx/static/fonts/Web437_Wyse700b.woff b/moneyjsx/static/fonts/Web437_Wyse700b.woff Binary files differnew file mode 100644 index 0000000..d3ae560 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Wyse700b.woff diff --git a/moneyjsx/static/fonts/Web437_Zenith_Z-100.woff b/moneyjsx/static/fonts/Web437_Zenith_Z-100.woff Binary files differnew file mode 100644 index 0000000..4fd99a2 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Zenith_Z-100.woff diff --git a/moneyjsx/static/fonts/Web437_Zenith_Z-100_Alt.woff b/moneyjsx/static/fonts/Web437_Zenith_Z-100_Alt.woff Binary files differnew file mode 100644 index 0000000..21f8c33 --- /dev/null +++ b/moneyjsx/static/fonts/Web437_Zenith_Z-100_Alt.woff diff --git a/moneyjsx/static/fonts/WebPlus_AST_PremiumExec.woff b/moneyjsx/static/fonts/WebPlus_AST_PremiumExec.woff Binary files differnew file mode 100644 index 0000000..ea95d23 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_AST_PremiumExec.woff diff --git a/moneyjsx/static/fonts/WebPlus_Amstrad_PC-2y.woff b/moneyjsx/static/fonts/WebPlus_Amstrad_PC-2y.woff Binary files differnew file mode 100644 index 0000000..f0af92f --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_Amstrad_PC-2y.woff diff --git a/moneyjsx/static/fonts/WebPlus_Amstrad_PC.woff b/moneyjsx/static/fonts/WebPlus_Amstrad_PC.woff Binary files differnew file mode 100644 index 0000000..a89bd9c --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_Amstrad_PC.woff diff --git a/moneyjsx/static/fonts/WebPlus_Cordata_PPC-21.woff b/moneyjsx/static/fonts/WebPlus_Cordata_PPC-21.woff Binary files differnew file mode 100644 index 0000000..486cbb9 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_Cordata_PPC-21.woff diff --git a/moneyjsx/static/fonts/WebPlus_Cordata_PPC-400.woff b/moneyjsx/static/fonts/WebPlus_Cordata_PPC-400.woff Binary files differnew file mode 100644 index 0000000..b36d384 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_Cordata_PPC-400.woff diff --git a/moneyjsx/static/fonts/WebPlus_HP_100LX_10x11.woff b/moneyjsx/static/fonts/WebPlus_HP_100LX_10x11.woff Binary files differnew file mode 100644 index 0000000..be23ce0 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_HP_100LX_10x11.woff diff --git a/moneyjsx/static/fonts/WebPlus_HP_100LX_16x12.woff b/moneyjsx/static/fonts/WebPlus_HP_100LX_16x12.woff Binary files differnew file mode 100644 index 0000000..58c37c7 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_HP_100LX_16x12.woff diff --git a/moneyjsx/static/fonts/WebPlus_HP_100LX_6x8-2x.woff b/moneyjsx/static/fonts/WebPlus_HP_100LX_6x8-2x.woff Binary files differnew file mode 100644 index 0000000..0e12806 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_HP_100LX_6x8-2x.woff diff --git a/moneyjsx/static/fonts/WebPlus_HP_100LX_6x8.woff b/moneyjsx/static/fonts/WebPlus_HP_100LX_6x8.woff Binary files differnew file mode 100644 index 0000000..d259282 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_HP_100LX_6x8.woff diff --git a/moneyjsx/static/fonts/WebPlus_HP_100LX_8x8-2x.woff b/moneyjsx/static/fonts/WebPlus_HP_100LX_8x8-2x.woff Binary files differnew file mode 100644 index 0000000..8258270 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_HP_100LX_8x8-2x.woff diff --git a/moneyjsx/static/fonts/WebPlus_HP_100LX_8x8.woff b/moneyjsx/static/fonts/WebPlus_HP_100LX_8x8.woff Binary files differnew file mode 100644 index 0000000..f2dca01 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_HP_100LX_8x8.woff diff --git a/moneyjsx/static/fonts/WebPlus_HP_150_re.woff b/moneyjsx/static/fonts/WebPlus_HP_150_re.woff Binary files differnew file mode 100644 index 0000000..dc2ec33 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_HP_150_re.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_BIOS-2x.woff b/moneyjsx/static/fonts/WebPlus_IBM_BIOS-2x.woff Binary files differnew file mode 100644 index 0000000..ffce1c5 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_BIOS-2x.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_BIOS-2y.woff b/moneyjsx/static/fonts/WebPlus_IBM_BIOS-2y.woff Binary files differnew file mode 100644 index 0000000..c46cbd1 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_BIOS-2y.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_BIOS.woff b/moneyjsx/static/fonts/WebPlus_IBM_BIOS.woff Binary files differnew file mode 100644 index 0000000..a519221 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_BIOS.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_CGA-2y.woff b/moneyjsx/static/fonts/WebPlus_IBM_CGA-2y.woff Binary files differnew file mode 100644 index 0000000..6998020 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_CGA-2y.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_CGA.woff b/moneyjsx/static/fonts/WebPlus_IBM_CGA.woff Binary files differnew file mode 100644 index 0000000..a76d503 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_CGA.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_CGAthin-2y.woff b/moneyjsx/static/fonts/WebPlus_IBM_CGAthin-2y.woff Binary files differnew file mode 100644 index 0000000..92df543 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_CGAthin-2y.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_CGAthin.woff b/moneyjsx/static/fonts/WebPlus_IBM_CGAthin.woff Binary files differnew file mode 100644 index 0000000..cf5ebf6 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_CGAthin.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_EGA_8x14-2x.woff b/moneyjsx/static/fonts/WebPlus_IBM_EGA_8x14-2x.woff Binary files differnew file mode 100644 index 0000000..b7808fd --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_EGA_8x14-2x.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_EGA_8x14.woff b/moneyjsx/static/fonts/WebPlus_IBM_EGA_8x14.woff Binary files differnew file mode 100644 index 0000000..9bc7e08 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_EGA_8x14.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_EGA_8x8-2x.woff b/moneyjsx/static/fonts/WebPlus_IBM_EGA_8x8-2x.woff Binary files differnew file mode 100644 index 0000000..3013cec --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_EGA_8x8-2x.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_EGA_8x8.woff b/moneyjsx/static/fonts/WebPlus_IBM_EGA_8x8.woff Binary files differnew file mode 100644 index 0000000..bb39e9f --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_EGA_8x8.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_EGA_9x14-2x.woff b/moneyjsx/static/fonts/WebPlus_IBM_EGA_9x14-2x.woff Binary files differnew file mode 100644 index 0000000..6e25b86 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_EGA_9x14-2x.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_EGA_9x14.woff b/moneyjsx/static/fonts/WebPlus_IBM_EGA_9x14.woff Binary files differnew file mode 100644 index 0000000..9d81c45 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_EGA_9x14.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_EGA_9x8-2x.woff b/moneyjsx/static/fonts/WebPlus_IBM_EGA_9x8-2x.woff Binary files differnew file mode 100644 index 0000000..46885b2 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_EGA_9x8-2x.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_EGA_9x8.woff b/moneyjsx/static/fonts/WebPlus_IBM_EGA_9x8.woff Binary files differnew file mode 100644 index 0000000..0077442 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_EGA_9x8.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_MDA.woff b/moneyjsx/static/fonts/WebPlus_IBM_MDA.woff Binary files differnew file mode 100644 index 0000000..45639b5 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_MDA.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_VGA_8x14-2x.woff b/moneyjsx/static/fonts/WebPlus_IBM_VGA_8x14-2x.woff Binary files differnew file mode 100644 index 0000000..47cffd4 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_VGA_8x14-2x.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_VGA_8x14.woff b/moneyjsx/static/fonts/WebPlus_IBM_VGA_8x14.woff Binary files differnew file mode 100644 index 0000000..d1ee1c9 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_VGA_8x14.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_VGA_8x16-2x.woff b/moneyjsx/static/fonts/WebPlus_IBM_VGA_8x16-2x.woff Binary files differnew file mode 100644 index 0000000..a589f63 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_VGA_8x16-2x.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_VGA_8x16.woff b/moneyjsx/static/fonts/WebPlus_IBM_VGA_8x16.woff Binary files differnew file mode 100644 index 0000000..466064d --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_VGA_8x16.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_VGA_9x14-2x.woff b/moneyjsx/static/fonts/WebPlus_IBM_VGA_9x14-2x.woff Binary files differnew file mode 100644 index 0000000..8746fdc --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_VGA_9x14-2x.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_VGA_9x14.woff b/moneyjsx/static/fonts/WebPlus_IBM_VGA_9x14.woff Binary files differnew file mode 100644 index 0000000..44cce3e --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_VGA_9x14.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_VGA_9x16-2x.woff b/moneyjsx/static/fonts/WebPlus_IBM_VGA_9x16-2x.woff Binary files differnew file mode 100644 index 0000000..f0ffd03 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_VGA_9x16-2x.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_VGA_9x16.woff b/moneyjsx/static/fonts/WebPlus_IBM_VGA_9x16.woff Binary files differnew file mode 100644 index 0000000..969fb65 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_VGA_9x16.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_VGA_9x8-2x.woff b/moneyjsx/static/fonts/WebPlus_IBM_VGA_9x8-2x.woff Binary files differnew file mode 100644 index 0000000..45326ef --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_VGA_9x8-2x.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_VGA_9x8.woff b/moneyjsx/static/fonts/WebPlus_IBM_VGA_9x8.woff Binary files differnew file mode 100644 index 0000000..44cd4df --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_VGA_9x8.woff diff --git a/moneyjsx/static/fonts/WebPlus_IBM_XGA-AI_12x20.woff b/moneyjsx/static/fonts/WebPlus_IBM_XGA-AI_12x20.woff Binary files differnew file mode 100644 index 0000000..ff642ee --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_IBM_XGA-AI_12x20.woff diff --git a/moneyjsx/static/fonts/WebPlus_Rainbow100_re_132.woff b/moneyjsx/static/fonts/WebPlus_Rainbow100_re_132.woff Binary files differnew file mode 100644 index 0000000..c553760 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_Rainbow100_re_132.woff diff --git a/moneyjsx/static/fonts/WebPlus_Rainbow100_re_40.woff b/moneyjsx/static/fonts/WebPlus_Rainbow100_re_40.woff Binary files differnew file mode 100644 index 0000000..c316398 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_Rainbow100_re_40.woff diff --git a/moneyjsx/static/fonts/WebPlus_Rainbow100_re_66.woff b/moneyjsx/static/fonts/WebPlus_Rainbow100_re_66.woff Binary files differnew file mode 100644 index 0000000..123af39 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_Rainbow100_re_66.woff diff --git a/moneyjsx/static/fonts/WebPlus_Rainbow100_re_80.woff b/moneyjsx/static/fonts/WebPlus_Rainbow100_re_80.woff Binary files differnew file mode 100644 index 0000000..4feb241 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_Rainbow100_re_80.woff diff --git a/moneyjsx/static/fonts/WebPlus_Tandy1K-II_200L-2x.woff b/moneyjsx/static/fonts/WebPlus_Tandy1K-II_200L-2x.woff Binary files differnew file mode 100644 index 0000000..b95844e --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_Tandy1K-II_200L-2x.woff diff --git a/moneyjsx/static/fonts/WebPlus_Tandy1K-II_200L-2y.woff b/moneyjsx/static/fonts/WebPlus_Tandy1K-II_200L-2y.woff Binary files differnew file mode 100644 index 0000000..766fdf5 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_Tandy1K-II_200L-2y.woff diff --git a/moneyjsx/static/fonts/WebPlus_Tandy1K-II_200L.woff b/moneyjsx/static/fonts/WebPlus_Tandy1K-II_200L.woff Binary files differnew file mode 100644 index 0000000..a40ea22 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_Tandy1K-II_200L.woff diff --git a/moneyjsx/static/fonts/WebPlus_Tandy1K-II_225L-2y.woff b/moneyjsx/static/fonts/WebPlus_Tandy1K-II_225L-2y.woff Binary files differnew file mode 100644 index 0000000..2e376dc --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_Tandy1K-II_225L-2y.woff diff --git a/moneyjsx/static/fonts/WebPlus_Tandy1K-II_225L.woff b/moneyjsx/static/fonts/WebPlus_Tandy1K-II_225L.woff Binary files differnew file mode 100644 index 0000000..226bfe4 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_Tandy1K-II_225L.woff diff --git a/moneyjsx/static/fonts/WebPlus_ToshibaSat_8x14.woff b/moneyjsx/static/fonts/WebPlus_ToshibaSat_8x14.woff Binary files differnew file mode 100644 index 0000000..54c3b46 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_ToshibaSat_8x14.woff diff --git a/moneyjsx/static/fonts/WebPlus_ToshibaSat_8x16.woff b/moneyjsx/static/fonts/WebPlus_ToshibaSat_8x16.woff Binary files differnew file mode 100644 index 0000000..1ac5866 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_ToshibaSat_8x16.woff diff --git a/moneyjsx/static/fonts/WebPlus_ToshibaSat_8x8.woff b/moneyjsx/static/fonts/WebPlus_ToshibaSat_8x8.woff Binary files differnew file mode 100644 index 0000000..dc45c25 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_ToshibaSat_8x8.woff diff --git a/moneyjsx/static/fonts/WebPlus_ToshibaSat_9x14.woff b/moneyjsx/static/fonts/WebPlus_ToshibaSat_9x14.woff Binary files differnew file mode 100644 index 0000000..3eac7ac --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_ToshibaSat_9x14.woff diff --git a/moneyjsx/static/fonts/WebPlus_ToshibaSat_9x16.woff b/moneyjsx/static/fonts/WebPlus_ToshibaSat_9x16.woff Binary files differnew file mode 100644 index 0000000..b324de1 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_ToshibaSat_9x16.woff diff --git a/moneyjsx/static/fonts/WebPlus_ToshibaSat_9x8.woff b/moneyjsx/static/fonts/WebPlus_ToshibaSat_9x8.woff Binary files differnew file mode 100644 index 0000000..ac2722c --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_ToshibaSat_9x8.woff diff --git a/moneyjsx/static/fonts/WebPlus_ToshibaTxL1_8x16.woff b/moneyjsx/static/fonts/WebPlus_ToshibaTxL1_8x16.woff Binary files differnew file mode 100644 index 0000000..686cea5 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_ToshibaTxL1_8x16.woff diff --git a/moneyjsx/static/fonts/WebPlus_ToshibaTxL2_8x16.woff b/moneyjsx/static/fonts/WebPlus_ToshibaTxL2_8x16.woff Binary files differnew file mode 100644 index 0000000..0526002 --- /dev/null +++ b/moneyjsx/static/fonts/WebPlus_ToshibaTxL2_8x16.woff diff --git a/moneyjsx/static/highlight.css b/moneyjsx/static/highlight.css new file mode 100644 index 0000000..faa5d4d --- /dev/null +++ b/moneyjsx/static/highlight.css @@ -0,0 +1,7 @@ +/*! + Theme: Synth Midnight Terminal Dark + Author: Michaƫl Ball (http://github.com/michael-ball/) + License: ~ MIT (or more permissive) [via base16-schemes-source] + Maintainer: @highlightjs/core-team + Version: 2021.09.0 +*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#c1c3c4;background:#050608}.hljs ::selection,.hljs::selection{background-color:#28292a;color:#c1c3c4}.hljs-comment{color:#474849}.hljs-tag{color:#a3a5a6}.hljs-operator,.hljs-punctuation,.hljs-subst{color:#c1c3c4}.hljs-operator{opacity:.7}.hljs-bullet,.hljs-deletion,.hljs-name,.hljs-selector-tag,.hljs-template-variable,.hljs-variable{color:#b53b50}.hljs-attr,.hljs-link,.hljs-literal,.hljs-number,.hljs-symbol,.hljs-variable.constant_{color:#ea770d}.hljs-class .hljs-title,.hljs-title,.hljs-title.class_{color:#c9d364}.hljs-strong{font-weight:700;color:#c9d364}.hljs-addition,.hljs-code,.hljs-string,.hljs-title.class_.inherited__{color:#06ea61}.hljs-built_in,.hljs-doctag,.hljs-keyword.hljs-atrule,.hljs-quote,.hljs-regexp{color:#42fff9}.hljs-attribute,.hljs-function .hljs-title,.hljs-section,.hljs-title.function_,.ruby .hljs-property{color:#03aeff}.diff .hljs-meta,.hljs-keyword,.hljs-template-tag,.hljs-type{color:#ea5ce2}.hljs-emphasis{color:#ea5ce2;font-style:italic}.hljs-meta,.hljs-meta .hljs-keyword,.hljs-meta .hljs-string{color:#cd6320}.hljs-meta .hljs-keyword,.hljs-meta-keyword{font-weight:700}
\ No newline at end of file diff --git a/moneyjsx/static/main.css b/moneyjsx/static/main.css new file mode 100644 index 0000000..ad6d85c --- /dev/null +++ b/moneyjsx/static/main.css @@ -0,0 +1,882 @@ +:root { + --back: #18191B; + --front: #E76969; + --green: #69E769; + --site-font: Terminal; +} + +@font-face { + font-family: Terminal; + src: url( /static/fonts/Web437_IBM_PGC.woff ) +} + +@font-face { + font-family: Code; + src: url( /static/fonts/Web437_DOS-V_re_JPN12.woff ) +} + +#moneyjsx-root { + display: flex; + flex-direction: column; + padding: 0; + margin: 0; +} +input[type="radio"] { + appearance: none; + background-color: var( --back ); + margin: 0; + font: inherit; + color: #888; + width: 1em; + height: 1em; + border: 0.15em solid currentColor; + border-radius: 50%; + display: grid; + place-content: center; +} + +input[type="radio"]::before { + content: ""; + width: 0.75em; + height: 0.75em; + border-radius: 50%; + transform: scale(0); + transition: 120ms transform ease-in-out; + box-shadow: inset 1em 1em var(--front); +} + +input[type="radio"]:checked::before { + transform: scale(1); +} + +header { + justify-content: space-between; + flex-direction: row; + align-self: center; + position: relative; + display: flex; + z-index: 1; + width: 98%; + top: 5px; +} + +code { + font-family: Code; + font-size: 12px; + white-space: pre-wrap; +} + +html, body { + height: 100%; + overflow: auto; +} + +input { + background-color: #222; + border: 1px solid var(--front); + color: #888; + font-family: Code; +} + +button { + cursor: pointer; + border: 1px solid var(--front); + background-color: #222; + color: #fff; + font-size: 16px; + font-family: var( --site-font ); +} + +a { text-decoration: underline; color: inherit; } +a:hover { cursor: pointer; } + +body { + background-color: var( --back ); + font-family: var( --site-font ); + font-smooth: never !important; + background-position: center; + background-size: cover; + flex-direction: column; + display: flex; + color: #fff; + margin: 0; +} + +@media (max-width: 768px) { +#ascii-art { + font-size: 6px !important; + line-height: 6px !important; + } +} + +/* chrome rendering fucking sucks */ +@supports (-moz-appearance:none) { + code { + font-size: 12px; + } +} + +#terminal { + box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); + background: rgba(29, 31, 32, 0.85); + position: relative; + min-height: 350px; + min-width: 333px; + max-height: 95%; + max-width: 100%; + width: 650px; + width: 640px; + overflow: hidden; +} + +#model-capabilities { + padding-top: 5px; + color: #555; + filter: drop-shadow( 1px 1px 1px #000 ); +} + +#terminal-header > div { + margin: 0 5px; + display: flex; + align-items: center; + flex-direction: row; + justify-content: space-between; +} + +#terminal-header a { + color: var(--front); + text-decoration: none; +} + +#terminal-inner { + text-align: left; + padding: 0 10px; + overflow: scroll; + height: calc(100% - 30px); +} + +#terminal-resizer { + clip-path: polygon( 0% 100%, 100% 100%, 100% 0% ); + background-color: var( --front ); + position: absolute; + height: 16px; + z-index: 69; + width: 16px; + bottom: 3px; + right: 3px; +} + +#cmd { + border: none; + background: none; + font-family: var(--site-font); + padding-top: 0px; + margin-top: 0px; + width: 100%; + outline: none; + display: block; +} + +#cmd-input { + width: calc( 100% - 20px ); + outline: none; + height: 20px; +} + +.cmd-files { + padding-left: 10px; +} + +.cmd-files-header { + color: #066; +} + +.cmd-file-size { + color: #888; +} + +.chat-error { + color: #f00; +} + +.chat-role-user, +.chat-role-model { + display: inline; +} + +.chat-role-user { + color: var(--front); +} + +.chat-role-model { + color: #888; +} + +.chat-line { + display: block; +} + +#chat-selection { + display: flex; + flex-direction: column; + position: absolute; + bottom: 1px; + left: 0; + z-index: 11; + text-align: left; +} + +#chat-selection-inner { + background-color: #222; + border: 1px solid var( --front ); +} + +#chat-selection-current { + padding: 5px; + padding-left: 10px; + padding-right: 10px; + display: block; +} + +#chat-selection-sidebar { + position: absolute; + bottom: 1px; + left: 0; + text-align: left; + + z-index: 12; + min-height: 50px; + height: fit-content; + max-height: 50vh; + overflow: auto; + width: 230px; + background-color: #222; + border: 1px solid var( --front ); + display: none; + flex-direction: column; + justify-content: end; +} + +.chat-item { + padding-left: 5px; + margin-bottom: 5px; + height: 30px; + display: flex; + cursor: pointer; +} + +.chat-name:hover a { + color: var( --front ); +} + +.chat-name { + width: 200px; +} + +#chat-name { + width: calc(100% - 15px); + text-align: left; + height: 30px; + white-space: pre; + overflow: hidden; + text-overflow: ellipsis; +} + +.chat-delete a { + text-decoration: none; +} + +.chat-delete:hover a { + color: var( --front ); +} + +#terminal-resizer:hover { + background-color: #ccc; +} + +#terminal-header { + -webkit-touch-callout: none; + height: 30px; + line-height: 30px; + background-color: rgba(29, 31, 32, 1.0); + overflow: hidden; +} + +#suggested-prompts { + padding-top: 20px; + padding-left: 20px; +} + +#homepagemain { + justify-content: center; + align-items: flex-start; + flex-direction: row; + text-align: center; + padding: 15px 0 0; + flex-wrap: wrap; + display: flex; + width: 100%; + z-index: 0; + margin: 0; +} + +.red { color: var( --front ); } +.black { color: var( --back ); } +.green { color: var( --green ); } +.btn_close { background: var( --front ); } + +#page-main { + flex-direction: column; + align-items: center; + text-align: center; + padding: 30px 0 0; + overflow-x: clip; + display: flex; + width: 100%; + z-index: 0; + margin: 0; +} + +#ascii-art { + white-space: pre-wrap; + font-family: Code; + font-size: 9px; + overflow:clip; + width: 1200px; + padding-top: 5px; +} + +#ascii-art span { + padding: 0; + margin: 0; +} + +.groupbox { + border: 1px solid var( --front ); + background-color: var( --back ); + justify-content: flex-start; + align-items: flex-start; + flex-direction: column; + height: fit-content; + min-height: 25px; + min-width: 333px; /* may need to change this for mobile */ + max-width: 600px; + display: flex; + margin: 5px; + z-index: 1; + flex: 1; +} +.groupbox > .grouptitle { + background-color: var( --back ); + font-family: inherit; + position: relative; + margin: 0 0 -15px; /* stupid hardcode, but its: ( title font height - 4 ) * -1 */ + padding: 0px 5px; + font-size: 18px; + z-index: 2; + top: -9px; + left: 5px; +} +.groupbody { + width: calc( 100% - 5px ); + height: calc( 100% - 5px ); + text-align: left; + margin: 5px; +} + +#popup-msgbox { + display: none; + justify-content: center; + align-items: center; + position: absolute; + left: 50%; + min-width: 250px; + border: 1px solid var( --front ); + background: var( --back ); + min-height: 120px; + top: 45vh; + transform: translate( -50%, -50% ); +} + +#header-user > button { + background-color: transparent; + text-decoration: underline; + color: white; + border: none; +} + +#header-ctrls { + justify-content: end; + flex-direction: row; + align-items: center; + position: relative; + display: flex; + width: 128px; + padding: 0; + margin: 0; +} + +#header-dropdown-btn { + font-family: inherit; + text-align: center; + line-height: 0px; + font-size: 1.8em; + color: #888; +} + +.dropdown { + background-color: var( --back ); + border-color: var( --front ); + text-align: center; + color: #888; + height: 24px; + color: #fff; +} + +.dropdown-wrapper { + border: 2px inset var( --front ); + background-color: var( --back ); + justify-content: space-evenly; + flex-direction: column; + align-items: center; + position: absolute; + width: 256px; + z-index: 10; + margin-left: 10px; +} + +.dropdown-inner { + height: 30px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-evenly; + border-bottom: 1px solid #333; + cursor: pointer; +} + +#login-username { + border: 1px solid var( --front ); + background-color: transparent; + padding: 3px 6px; + color: white; +} + +#header-login-dropdown button { + background-color: transparent; + text-decoration: underline; + color: white; + border: none; +} + +#header-login-dropdown { + display: flex; + flex-direction: column; +} + +#header-dropdown { + border: 2px inset var( --front ); + background-color: var( --back ); + justify-content: space-evenly; + flex-direction: column; + align-items: center; + position: absolute; + display: flex; + height: 100px; + width: 220px; + top: 24px; + left: 20px; +} + +#login-email { + width: 160px; +} + +#header-dropdown > a { + border-bottom: 1px solid #242424; + border-top: 1px solid #242424; + height: 33.3333333333%; + text-align: center; + line-height: 45px; + width: 100%; + text-decoration: underline; +} +#header-dropdown > a:nth-child( 1 ) { border-top: none; } +#header-dropdown > a:nth-last-child( 1 ) { border-bottom: none; } + +.rolldownlist { + height: fit-content; + position: relative; + width: 100%; + padding: 0; + margin: 0; +} + +.rolldown { + transition: background-color 0.3s ease-in-out; + border-bottom: 1px solid #E76969; + justify-content: space-between; + flex-direction: column; + display: flex; + height: auto; + width: 100%; +} + +.rolldown:nth-of-type( 1 ) { margin-top: -5px; } +.rolldown:nth-last-of-type( 1 ) { border-bottom: none; } +.rolldown:hover { cursor: pointer; } + +.rolldown-collapsed-container { + overflow: hidden; + padding: 10px; + display: flex; + height: auto; + width: 100%; +} + +.rolldown-collapsed { + float: left; + padding: 0; +} + +.rolldown-expanded-container { + text-align: center; + overflow: hidden; + transition: max-height 0.3s linear; + max-height: 0px; + margin: 0; + padding: 0; +} + +.rolldown-expanded-container.active { + display: flex !important; + max-height: 200px; + height: auto; +} + +.rolldown-expanded { + margin: 20px; +} + +.rolldown-expanded a { color: white; } + +.rolldown-icon-container { + margin-right: 15px; + position: relative; + float: left; + height: fit-content; +} + +.rolldown.active .rolldown-icon-container { + transform: rotate( 90deg ); +} + +#notes-popup, +#tokens-popup, +#settings-popup { + border: 1px solid var( --front ); + background-color: var( --back ); + box-shadow: 1px 1px 2px black; + justify-content: center; + align-items: center; + align-self: center; + flex-direction: column; + position: absolute; + max-height: 888px; + max-width: 600px; + min-width: 300px; + display: flex; + padding: 20px; + z-index: 5; + width: 85%; + top: 50%; + left: 50%; + transform: translate( -50%, -50% ); +} + +#tokens-popup, +#notes-popup { + max-width: 650px; +} + +#settings-top { + justify-content: center; + align-items: baseline; + flex-direction: row; + flex-wrap: wrap; + display: flex; + width: 100%; +} + +#settings-top > div { + width: calc(50% - 20px); + margin: 10px; +} + +#settings-spinner-wrapper { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + width: 100%; +} + +#system-prompt { + min-width: 100%; + max-width: 100%; + min-height: 220px; +} + +.settings-btn { + width: calc(50% - 5px); + height: 28px; + display: flex; + justify-content: center; +} + +@media (max-width: 768px) { + #settings-top > div { + width: 100% !important; + } + #settings-top > div > div { + margin: 5px !important; + } +} + +#tokens-inner, +#notes-inner { + padding: 10px; + border: 1px solid var( --front ); + background-color: #000; + box-shadow: 1px 1px 2px black; + width: calc( 100% - 20px ); + max-height: 300px; + overflow: scroll; +} + +.tokens-entry, +.notes-entry { + display: flex; + justify-content: space-between; + border-bottom: 1px solid #222; + margin: 5px 10px; +} + +.tokens-entry span, +.notes-entry span { + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: center; +} + +.tokens-delete, +.notes-delete { + background: none; + border: none; + color: #fff; + margin-left: 5px; + font-size: 24px; +} + +.tokens-delete:hover, +.notes-delete:hover { + color: var(--front); +} + +.popup-msg { + border: 1px solid var( --front ); + background-color: var( --back ); + box-shadow: 1px 1px 2px black; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + z-index: 1000; + padding: 10px; + display: flex; + flex-direction: column; +} + +textarea { + border: 1px solid var( --front ); + background-color: #222; + color: white; +} + +.column { + display: flex; + flex-direction: column; +} + +#chat-name { + width: calc(100% - 15px); + overflow: hidden; + text-overflow: ellipsis; + text-align: left; + height: 30px; +} + +.chat-content { + display: inline; + white-space: pre-line; +} + +.chat-line pre { + padding-top: 0; + padding-bottom: 0; + margin-bottom: 5px; + margin-top: 5px; + background-color: #000; + color: var(--front); +} + +.chat-code-line { + background: #151515; + padding: 3px; + color: #0d0; +} + +.chat-column { + display: flex; + flex-direction: column; + margin-bottom: 5px; +} + +.comment { + color: #888; +} + +#support-container { + width: calc( 100% - 7px ) !important; + justify-content: flex-start; + flex-direction: column; + text-align: center; + padding: 0 0 25px; + display: flex; + height: 100%; + z-index: 0; +} + +#support-container pre { + border: 1px solid #444; + color: var( --front ); + overflow-x: scroll; + background: #000; + width: 100%; +} + +#support-container > div { + min-height: unset !important; + padding: 5px; /* placeholder */ + width: 100%; +} + +#support-container > p { + margin: 5px 0; +} + +hr { + outline: 1px solid var( --front ); + border: 1px solid var( --back ); + border-radius: 25px; + width: 100%; +} + +.tool-call { + background: #050608; + padding: 10px; + font-family: Code; + font-size: 12px; + cursor: pointer; +} + +.tool-call-title-wrapper { + justify-content: space-between; + align-items: center; + display: flex; +} + +.tool-call-collapse { + font-size: 17px; +} + +.tool-call-title { + +} + +.tool-call-list { + overflow: scroll !important; + color: var( --front ); +} + +.reason-output { + overflow: scroll !important; + color: var( --front ); +} + +#page-selector-wrapper { + width: fit-content; + display: grid; + float: right; + clear: both; + margin: 0; + right: 0; +} + +#selector-wrapper { + display: grid; + width: 100%; +} + +#selector-wrapper > .dropdown-wrapper { + justify-self: flex-end !important; + margin-right: 7px !important; +} + +#page-selector-wrapper > .dropdown-wrapper { + justify-self: flex-end !important; + margin-right: 10px !important; + width: 252px !important; +} + +#tutorial-links-box { + border: 1px solid var( --front ); + justify-content: center; + flex-direction: column; + justify-self: flex-end; + align-items: center; + margin: 0 10px 10px; + display: flex; + padding: 5px; + width: 256px; + float: right; + clear: both; +} + +#model-selector { + align-items: flex-start; + justify-self: flex-end; + height: fit-content; + width: fit-content; + margin-right: 7px; + display: flex; +} + +.model-capabilities { + flex-direction: column; + padding: 0 10px 10px; + display: flex; +} + +.model-capabilities > span { + min-width: fit-content; +} + +.model-item > .tool-call { + margin-right: 5px; +} + +#tos-text { + white-space: break-spaces; +} diff --git a/moneyjsx/static/prompts.json b/moneyjsx/static/prompts.json new file mode 100644 index 0000000..b121306 --- /dev/null +++ b/moneyjsx/static/prompts.json @@ -0,0 +1,104 @@ +{ + "prompts": [ + "how do i fix a slow pc?", + "explain quantum computing in simple terms.", + "what is the best pizza topping?", + "recommend me a sci-fi movie.", + "how do i make a website?", + "tell me a fun fact.", + "what is the meaning of life?", + "how can i learn programming fast?", + "suggest a book to read.", + "who is elon musk?", + "explain blockchain.", + "what is the capital of japan?", + "give me a random joke.", + "what is 42 in binary?", + "what is the best coding language to learn?", + "how do you make coffee?", + "explain the concept of ai.", + "what is the weather today?", + "who won the last world cup?", + "tell me about black holes.", + "how do i become a millionaire?", + "best way to learn guitar?", + "what is love?", + "tell me about spacex.", + "give me a motivational quote.", + "explain recursion.", + "who is the president of the usa?", + "define cryptocurrency.", + "how to start a startup?", + "tell me a cool fact about space.", + "what are the benefits of meditation?", + "explain 5g technology.", + "suggest a new hobby.", + "how do i improve my memory?", + "what is 2+2?", + "what is a deep learning model?", + "who is albert einstein?", + "how can i become more productive?", + "what is the best anime series?", + "explain the stock market.", + "who invented the internet?", + "what are some good productivity hacks?", + "tell me a mystery fact.", + "what is dark matter?", + "how do i invest in stocks?", + "what is a good workout routine?", + "explain how electricity works.", + "give me a funny meme idea.", + "what is the history of bitcoin?", + "how do i write a resume?", + "recommend a good tv series.", + "explain the theory of relativity.", + "how do i quit a bad habit?", + "tell me something weird.", + "how can i become rich?", + "explain how nuclear energy works.", + "what is the healthiest diet?", + "how to deal with stress?", + "tell me about mars.", + "what is machine learning?", + "give me a random trivia.", + "how does ai work?", + "what is the best way to relax?", + "tell me something inspirational.", + "who invented computers?", + "explain string theory.", + "what is the biggest animal in the ocean?", + "how do i make friends?", + "tell me a conspiracy theory.", + "what is the fastest car in the world?", + "explain schrodinger's cat.", + "what is the best way to sleep better?", + "who wrote the bible?", + "how do i code in python?", + "what is the longest river in the world?", + "how does the brain work?", + "tell me about the moon landing.", + "what is quantum physics?", + "how to create a business plan?", + "what is an nft?", + "explain evolution.", + "how do i save money?", + "who is stephen hawking?", + "what is the best smartphone?", + "what are black holes?", + "how does the universe end?", + "tell me about tesla.", + "how do vaccines work?", + "what is consciousness?", + "explain time travel theories.", + "what is the best way to learn math?", + "how does google work?", + "what is augmented reality?", + "how do i boost my immune system?", + "what is the best travel destination?", + "tell me about dinosaurs.", + "explain the big bang.", + "how do satellites stay in orbit?", + "what is the difference between ai and ml?", + "how do i write a novel?" + ] +}
\ No newline at end of file diff --git a/moneyjsx/tsconfig.json b/moneyjsx/tsconfig.json new file mode 100644 index 0000000..f2f29fc --- /dev/null +++ b/moneyjsx/tsconfig.json @@ -0,0 +1,120 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + "moduleResolution": "bundler", + "target": "es2020", + "lib": [ + "ES2017", + "DOM", + "DOM.Iterable", + "ScriptHost" + ], + // "lib": [], + "jsx": "react", + // "experimentalDecorators": true, + // "emitDecoratorMetadata": true, + "jsxFactory": "JSX.createElement", + "jsxFragmentFactory": "JSX.createFragment", + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "es2020", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + "baseUrl": ".", + "paths": { + "*": ["types/*"] + }, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + "typeRoots": [ + "./node_modules/@types", + "./types" + ], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "noUncheckedSideEffectImports": true, /* Check side effect imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + //"checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": false, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + "strictNullChecks": false, /* When type checking, take into account 'null' and 'undefined'. */ + "strictFunctionTypes": false, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + "strictBindCallApply": false, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + "strictPropertyInitialization": false, /* Check for class properties that are declared but not set in the constructor. */ + "strictBuiltinIteratorReturn": false, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */ + "noImplicitThis": false, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/moneyjsx/types/custom.d.ts b/moneyjsx/types/custom.d.ts new file mode 100644 index 0000000..b7f740e --- /dev/null +++ b/moneyjsx/types/custom.d.ts @@ -0,0 +1,8 @@ +declare namespace JSX { + type Element = any; + type ElementClass = any; + interface IntrinsicElements { + [elemName: string]: any; + } +} + diff --git a/moneyjsx/webpack-dev.config.cjs b/moneyjsx/webpack-dev.config.cjs new file mode 100644 index 0000000..4fa4b07 --- /dev/null +++ b/moneyjsx/webpack-dev.config.cjs @@ -0,0 +1,45 @@ +const path = require('path'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); + +module.exports = { + mode: 'development', + entry: './src/index-page.tsx', + module: { + rules: [ + { + test: /\.tsx?$/, + use: { + loader: 'ts-loader', + options: { + compilerOptions: { + module: 'es2020' + } + } + }, + exclude: /node_modules/, + } + ], + }, + resolve: { + extensions: ['.tsx', '.jsx', ".js"], + }, + output: { + filename: 'bundle.js', + path: path.resolve(__dirname, 'dist') + }, + plugins: [ + new HtmlWebpackPlugin({ + template: './src/index.html', + }), + new CopyWebpackPlugin({ + patterns: [ + { from: './static/**' } + ] + }) + ], + devServer: { + historyApiFallback: true, + port: 9000, + }, +}; diff --git a/moneyjsx/webpack-prod.config.cjs b/moneyjsx/webpack-prod.config.cjs new file mode 100644 index 0000000..e850468 --- /dev/null +++ b/moneyjsx/webpack-prod.config.cjs @@ -0,0 +1,48 @@ +const path = require('path'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); + +module.exports = { + mode: 'production', + entry: './src/index-page.tsx', + module: { + rules: [ + { + test: /\.tsx?$/, + use: { + loader: 'ts-loader', + options: { + compilerOptions: { + module: 'es2020' + } + } + }, + exclude: /node_modules/, + } + ], + }, + resolve: { + alias: { + jquery: "jquery/slim" + }, + extensions: ['.tsx', '.jsx', ".js"], + }, + output: { + filename: 'bundle.js', + path: path.resolve(__dirname, 'dist'), + }, + plugins: [ + new HtmlWebpackPlugin({ + template: './src/index.html', + }), + new CopyWebpackPlugin({ + patterns: [ + { from: './static/**' } + ] + }) + ], + devServer: { + historyApiFallback: true, + port: 9000, + }, +}; |
