├── .gitattributes ├── .gitignore ├── LICENSE.md ├── README.md ├── assets ├── 512.icns ├── 512.ico ├── WA.svg ├── img │ ├── menubar_iconTemplate.png │ ├── menubar_iconTemplate@2x.png │ ├── menubar_icon_pressed.png │ └── menubar_icon_pressed@2x.png ├── nimback.png └── nimback@2x.png ├── clean-build.sh ├── gulpfile.js ├── index.js ├── package.json └── src ├── css ├── colours │ ├── blue.sass │ ├── bright-yellow.sass │ ├── green.sass │ ├── pink.sass │ ├── purple.sass │ └── red.sass ├── highcontrast.sass └── style.sass ├── index.html └── js ├── script.js └── suggestions.json /.gitattributes: -------------------------------------------------------------------------------- 1 | src/css/colours/* linguist-vendored=true 2 | src/css/highcontrast.sass linguist-vendored=true -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ############ 2 | # Node # 3 | ############ 4 | 5 | # .DS_Store is like that uncle that always shows up at the family gatherings and nobody 6 | # really wants him there but you all know if you don't invite him that there'll be this 7 | # arguments with everybody about the stupidest things and you all wish you hadn't spared 8 | # his feelings and just not invited him 9 | .DS_Store 10 | 11 | # this has caused me pain 12 | key.json 13 | 14 | # Ignore compiled CSS 15 | *.css 16 | 17 | # Logs 18 | logs 19 | *.log 20 | 21 | # Runtime data 22 | pids 23 | *.pid 24 | *.seed 25 | 26 | # Directory for instrumented libs generated by jscoverage/JSCover 27 | lib-cov 28 | 29 | # Coverage directory used by tools like istanbul 30 | coverage 31 | 32 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 33 | .grunt 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (http://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directory 42 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 43 | node_modules 44 | 45 | *.map 46 | 47 | .sass-cache/ 48 | 49 | src/js/key.json 50 | 51 | bugfixes.md 52 | 53 | options.json 54 | 55 | Nimble-darwin-x64 56 | dist 57 | 58 | dev.json 59 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # License 2 | 3 | Nimble is (c) 2016, Maybulb. 4 | 5 | This work is licensed under the Creative Commons Attribution-NonCommercial 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. 6 | 7 | Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 2 | 3 | Seamless Wolfram-Alpha® in your OS X menubar. 4 | 5 | > “The menubar client is every bit as intuitive as the web interface, meaning it’s easy to use...” – [The Next Web](http://thenextweb.com/insider/2016/02/08/nimble-brings-wolfram-alpha-to-your-menubar-on-os-x/) 6 | 7 | > “Nimble can handle pretty much anything you’d normally throw at Wolfram Alpha...” – [Lifehacker](http://lifehacker.com/nimble-crams-wolfram-alpha-into-your-macs-menu-bar-1758071364) 8 | 9 | ## Notice of Deprecation 10 | Nimble is **deprecated as of June 2020.** Within the current version are multiple privacy concerns (BugSnag bug reporting is on by default) and outdated dependencies. Really, we **don't think you should run Nimble as it is today.** If you must run it, compile it at your own risk following the development guide. 11 | 12 | ## Development 13 | Electron and gulp required to be installed on your machine (`npm install -g electron-prebuilt gulp`), as well as the Xcode Command Line Tools. You'll also need a [Wolfram Alpha API Key](http://products.wolframalpha.com/api/). 14 | 15 | Clone the repository, install dependencies, then run gulp. 16 | 17 | ```bash 18 | git clone https://github.com/Maybulb/Nimble.git 19 | 20 | # cd into the directory and install dependencies 21 | cd Nimble && npm install 22 | ``` 23 | 24 | Create `src/js/key.json` for your key. 25 | 26 | ```js 27 | { "api": "KEY" } 28 | ``` 29 | 30 | Run electron in the project directory to get it up and running. 31 | 32 | ``` 33 | # Compiles Sass and starts (gulp && electron .) 34 | npm start 35 | ``` 36 | 37 | ## Packaging/Bundling 38 | If you'd like to package Nimble, you can use our Gulp task for building Nimble. 39 | 40 | ```bash 41 | gulp build # packages and builds Nimble into a ZIP and a DMG 42 | sh clean-build.sh # clean build, reinstalls node modules and such 43 | ``` 44 | 45 | If you're bundling it, make sure to package it beforehand so that the `.app` exists for the disk image. 46 | 47 | ## Contribution 48 | Want to make a contribution? Fork the repo, add your changes, and submit a pull request. Any type of contributions (ideas, bug fixes, fixing typos, etc.) will be appreciated! 49 | 50 | 51 | ## License 52 | Nimble is licensed under [Creative Commons Attribution-NonCommercial 4.0](https://github.com/Maybulb/Nimble/blob/master/LICENSE.md). 53 | -------------------------------------------------------------------------------- /assets/512.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maybulb/Nimble/228af8240750791c7a6d2b092a2038e120838dd3/assets/512.icns -------------------------------------------------------------------------------- /assets/512.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maybulb/Nimble/228af8240750791c7a6d2b092a2038e120838dd3/assets/512.ico -------------------------------------------------------------------------------- /assets/WA.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Untitled 3 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /assets/img/menubar_iconTemplate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maybulb/Nimble/228af8240750791c7a6d2b092a2038e120838dd3/assets/img/menubar_iconTemplate.png -------------------------------------------------------------------------------- /assets/img/menubar_iconTemplate@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maybulb/Nimble/228af8240750791c7a6d2b092a2038e120838dd3/assets/img/menubar_iconTemplate@2x.png -------------------------------------------------------------------------------- /assets/img/menubar_icon_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maybulb/Nimble/228af8240750791c7a6d2b092a2038e120838dd3/assets/img/menubar_icon_pressed.png -------------------------------------------------------------------------------- /assets/img/menubar_icon_pressed@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maybulb/Nimble/228af8240750791c7a6d2b092a2038e120838dd3/assets/img/menubar_icon_pressed@2x.png -------------------------------------------------------------------------------- /assets/nimback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maybulb/Nimble/228af8240750791c7a6d2b092a2038e120838dd3/assets/nimback.png -------------------------------------------------------------------------------- /assets/nimback@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maybulb/Nimble/228af8240750791c7a6d2b092a2038e120838dd3/assets/nimback@2x.png -------------------------------------------------------------------------------- /clean-build.sh: -------------------------------------------------------------------------------- 1 | # clean build 2 | node_version=$(node -v) 3 | echo $node_version 4 | n 5.11.1 5 | node -v 6 | git pull 7 | rm -rf node_modules/ 8 | npm install 9 | gulp build 10 | n "$node_version" -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'), 2 | sass = require('gulp-sass'); 3 | 4 | require('shelljs/global'); 5 | 6 | gulp.task('sass', function() { 7 | gulp.src('src/css/*.sass') 8 | .pipe(sass()) 9 | .pipe(gulp.dest('src/css')) 10 | gulp.src('src/css/colours/*.sass') 11 | .pipe(sass()) 12 | .pipe(gulp.dest('src/css/colours')) 13 | }) 14 | 15 | gulp.task('default', ['sass']); 16 | 17 | // don't work too good 18 | // gulp.task('produce', ['package', 'build']); 19 | 20 | gulp.task('build', function() { 21 | // run this as a script because electron-builder doesn't offer it source 22 | var script = "node_modules/.bin/build --mac"; 23 | exec(script); 24 | }); -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const bugsnag = require('bugsnag'); 2 | const electron = require('electron'); 3 | const app = require('electron').app; 4 | const path = require('path'); 5 | const pjson = require('./package.json'); 6 | 7 | bugsnag.register('b3d3a88f13b0f8e22b4485b8b04939bd', { 8 | releaseStage: process.env.NODE_ENV, 9 | appVersion: pjson.version, 10 | sendCode: true, 11 | projectRoot: path.resolve(app.getPath('exe'), '../..'), // Locates `Content` directory within the .app 12 | metaData: { 13 | process: { 14 | arch: process.arch, 15 | argv: process.argv, 16 | pid: process.pid, 17 | platform: process.platform, 18 | version: process.version, 19 | cwd: process.cwd(), 20 | features: process.features, 21 | uptime: process.uptime(), 22 | versions: process.versions, 23 | } 24 | } 25 | }); 26 | 27 | bugsnag.onBeforeNotify(function () { 28 | // Notifies us of initial startup runtime errors & normal errors when user has specified allowing bugreports 29 | return !global.options || global.options.bugreport === true; 30 | }); 31 | 32 | process.on('unhandledRejection', function (err) { 33 | console.error('Unhandled error: ' + (err && err.stack || err)); 34 | bugsnag.notify(err); 35 | }); 36 | 37 | var ipc = require('electron').ipcMain; 38 | var globalShortcut = require('electron').globalShortcut; 39 | var autoUpdater = require('electron').autoUpdater; 40 | var menubar = require('menubar'); 41 | var fs = require('fs'); 42 | var AutoLaunch = require('auto-launch'); 43 | var os = require('os') 44 | const isDev = require('electron-is-dev'); 45 | 46 | try { 47 | global.options = require(os.homedir() + '/.nimble-options.json'); 48 | } catch (e) { 49 | global.options = { 50 | "mathjs": true, 51 | "startup": true, 52 | "center": false, 53 | "bugreport": true, 54 | "autoupdate": true, 55 | theme: { 56 | "red": false, 57 | "orange": true, 58 | "yellow": false, 59 | "green": false, 60 | "blue": false, 61 | "purple": false, 62 | "pink": false, 63 | "contrast": false 64 | }, 65 | enableDefaultSuggestions: true, 66 | customSuggestions: [] 67 | } 68 | } 69 | 70 | require('shelljs/global'); 71 | 72 | var mb = menubar({ 73 | height: 42, 74 | width: 380, 75 | icon: __dirname + '/assets/img/menubar_iconTemplate.png', 76 | index: 'file://' + __dirname + '/src/index.html', 77 | preloadWindow: true 78 | }); 79 | 80 | ipc.on('resize', function(event, arg) { 81 | 82 | 83 | // this is the animation code that crashes 84 | /* 85 | var h = mb.window.getSize()[1]; 86 | while(h !== arg.height) { 87 | setTimeout(function () { 88 | if(h > arg.height) { 89 | h--; 90 | } else if (h < arg.height) { 91 | h++; 92 | } 93 | 94 | console.log(h) 95 | mb.window.setSize(mb.window.getSize()[0], h) 96 | }, 1) 97 | } 98 | */ 99 | 100 | var finalDim = { 101 | height: null, 102 | width: null 103 | }; 104 | 105 | if (arg.height > 533) { 106 | // if height is way too big, then just set it short and scroll 107 | mb.window.setBounds({ 108 | x: mb.window.getPosition()[0], 109 | y: optfunc.getYValue(), 110 | width: arg.width, 111 | height: 533 112 | }, true); 113 | 114 | finalDim.height = 533; 115 | finalDim.width = arg.width; 116 | } else { 117 | mb.window.setBounds({ 118 | x: mb.window.getPosition()[0], 119 | y: optfunc.getYValue(), 120 | width: arg.width, 121 | height: arg.height 122 | }, true); 123 | 124 | finalDim.height = arg.height; 125 | finalDim.width = arg.width; 126 | } 127 | 128 | optfunc.position(); 129 | 130 | console.log("Resizing window to " + finalDim.width + " x " + finalDim.height + "\n"); 131 | }); 132 | 133 | ipc.on('toggleview', function(event) { 134 | var position = [mb.window.getPosition()[0], mb.window.getPosition()[1]]; 135 | 136 | if(mb.window.isVisible() === true) { 137 | mb.hideWindow(); 138 | } else if (mb.window.isVisible() === false) { 139 | mb.showWindow(); 140 | } 141 | 142 | mb.window.setPosition(position[0], position[1]); 143 | }); 144 | 145 | ipc.on('reset-window', function(event) { 146 | mb.window.setBounds({ 147 | x: mb.window.getPosition()[0], 148 | y: optfunc.getYValue(), 149 | width: 380, 150 | height: 42, 151 | }, true); 152 | 153 | optfunc.position(); 154 | }); 155 | 156 | // console.log handler 157 | ipc.on('node_console', function(event, arg) { 158 | console.log(arg.m + "\n") 159 | }); 160 | 161 | ipc.on('save_options', function(event, arg) { 162 | fs.writeFile(os.homedir() + '/.nimble-options.json', arg, function(err) { 163 | if(err) { 164 | console.log(err); 165 | } 166 | mb.window.webContents.send('did-save-options', !err); 167 | console.log("Options were saved.\n"); 168 | }); 169 | 170 | // make options available here too 171 | global.options = JSON.parse(arg); 172 | 173 | // things to do 174 | optfunc.startup(); 175 | optfunc.position(); 176 | }); 177 | 178 | // various functions that make options work 179 | var optfunc = { 180 | startup: function() { 181 | var nimbleAutoLauncher = new AutoLaunch({ 182 | name: 'Nimble', 183 | path: path.resolve(app.getAppPath(), '../../../') 184 | }); 185 | 186 | // startup? 187 | if (global.options.startup === true) { 188 | nimbleAutoLauncher.enable(); 189 | } else { 190 | nimbleAutoLauncher.disable(); 191 | } 192 | 193 | return null 194 | }, 195 | position: function() { 196 | if(global.options.center === true) { 197 | mb.setOption("window-position", "center"); 198 | mb.positioner.move("center"); 199 | } else if (global.options.center === false) { 200 | mb.setOption("window-position", "trayCenter"); 201 | if (global.bounds) { 202 | mb.positioner.move("trayCenter", global.bounds) 203 | } 204 | } 205 | 206 | return null 207 | }, 208 | getYValue: function() { 209 | try { 210 | if (global.autohide === true && global.options.center === false) { 211 | return 22 212 | } else { 213 | return mb.window.getPosition()[1] 214 | } 215 | } catch (e) { 216 | return mb.window.getPosition()[1] 217 | } 218 | } 219 | } 220 | 221 | ipc.on('quit', function(){ 222 | app.quit(); 223 | }) 224 | 225 | mb.on('after-create-window', function() { 226 | // error/log forwarding 227 | process.on("uncaughtException", function(err) { 228 | mb.window.webContents.send("error", err); 229 | }) 230 | 231 | var _consolelog = console.log.bind(console); 232 | console.log = function log(message) { 233 | mb.window.webContents.send('log', message); 234 | _consolelog(message); 235 | }; 236 | 237 | mb.window.setResizable(false); 238 | mb.tray.setPressedImage(__dirname + '/assets/img/menubar_icon_pressed.png'); 239 | 240 | mb.tray 241 | .on('click', click) 242 | .on('right-click', rightClick) 243 | 244 | // check if menubar is set to autohide 245 | var script = "defaults read NSGlobalDomain _HIHideMenuBar -bool" 246 | var output = exec(script, {async:true}) 247 | 248 | output.stdout.on("data", function(data) { 249 | if (data == 1) { 250 | global.autohide = true 251 | console.log("menubar is set to autohide") 252 | } else if (data == 0) { 253 | global.autohide = false 254 | } else { 255 | global.autohide = false 256 | } 257 | 258 | mb.window.setBounds({ 259 | x: mb.window.getPosition()[0], 260 | y: optfunc.getYValue(), 261 | width: 380, 262 | height: 42 263 | }); 264 | }) 265 | 266 | output.stderr.on("data", function(data) { 267 | console.log("no autohide setting was found, setting to default") 268 | global.autohide = false 269 | 270 | mb.window.setBounds({ 271 | x: mb.window.getPosition()[0], 272 | y: optfunc.getYValue(), 273 | width: 380, 274 | height: 42 275 | }); 276 | }) 277 | 278 | function click(e, bounds) { 279 | if (e.shiftKey) { 280 | mb.window.openDevTools({ 281 | detach: true 282 | }) 283 | } 284 | 285 | global.bounds = bounds; 286 | } 287 | 288 | function rightClick(e, bounds) { 289 | mb.window.webContents.send("tray-rightclick"); 290 | } 291 | 292 | // global hotkey to toggle nimble 293 | globalShortcut.register('CmdOrCtrl+Shift+=', function() { 294 | var position = [mb.window.getPosition()[0], mb.window.getPosition()[1]]; 295 | 296 | if(mb.window.isVisible() === true) { 297 | mb.hideWindow(); 298 | } else if (mb.window.isVisible() === false) { 299 | mb.showWindow(); 300 | } 301 | 302 | mb.window.setPosition(position[0], position[1]); 303 | }); 304 | }); 305 | 306 | mb.on('after-show', function() { 307 | if (mb.window) { 308 | mb.window.webContents.send("window-open"); 309 | mb.window.setPosition(mb.window.getPosition()[0], optfunc.getYValue()); 310 | } 311 | }) 312 | 313 | mb.on('ready', function() { 314 | // screen size 315 | var screen = require('electron').screen; 316 | global.screenSize = screen.getPrimaryDisplay().size; 317 | 318 | // auto update 319 | if (global.options.autoupdate === true && isDev === false) { 320 | var updateFeed = 'https://nimble-autoupdate.herokuapp.com/update/osx/'; 321 | autoUpdater.setFeedURL(updateFeed + pjson.version); 322 | autoUpdater.checkForUpdates(); 323 | 324 | autoUpdater.on('update-available', function() { 325 | console.log('update available and downloading'); 326 | require('electron').dialog.showMessageBox({ 327 | "message": "Update Downloading", 328 | "detail": "A new update is currently available and downloading. Nimble will let you know before it quits to install the update.", 329 | "buttons": [] 330 | }) 331 | }); 332 | 333 | autoUpdater.on('update-downloaded', function(event) { 334 | console.log('update downloaded: ' + event); 335 | require('electron').dialog.showMessageBox({ 336 | "message": "Update Ready To Install", 337 | "detail": "Nimble has downloaded a new update. Would you like to quit Nimble and install it?", 338 | "buttons": ["Yes", "No"], 339 | }, function(response) { 340 | switch(response) { 341 | case 1: 342 | break; 343 | case 0: 344 | autoUpdater.quitAndInstall(); 345 | break; 346 | } 347 | }); 348 | }); 349 | } 350 | }); 351 | 352 | mb.on('will-quit', function() { 353 | globalShortcut.unregisterAll(); 354 | }); 355 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Nimble", 3 | "version": "1.3.3", 4 | "description": "A Wolfram|Alpha® menu bar app", 5 | "main": "index.js", 6 | "dependencies": { 7 | "auto-launch": "^1.1.1", 8 | "bugsnag": "^1.7.0", 9 | "bugsnag-js": "^2.5.0", 10 | "electron-is-dev": "^0.1.1", 11 | "font-awesome": "^4.5.0", 12 | "imagesloaded": "^4.1.0", 13 | "jquery": "~> 3.0.0", 14 | "loaders.css": "^0.1.2", 15 | "mathjs": "~> 3.17.0", 16 | "menubar": "^2.3.0", 17 | "rand-paul": "^2.0.0", 18 | "shelljs": "^0.5.3", 19 | "string-format": "^0.5.0", 20 | "wolfram-alpha": "^0.5.0" 21 | }, 22 | "devDependencies": { 23 | "electron-builder": "^5.12.1", 24 | "electron-prebuilt": "^0.36.0", 25 | "gulp": "^3.9.0", 26 | "gulp-sass": "^2.3.2" 27 | }, 28 | "scripts": { 29 | "start": "gulp && electron ." 30 | }, 31 | "repository": { 32 | "type": "git", 33 | "url": "git+https://github.com/Maybulb/Nimble.git" 34 | }, 35 | "keywords": [ 36 | "wolfram", 37 | "nimble", 38 | "osx", 39 | "menubar" 40 | ], 41 | "author": "Maybulb", 42 | "license": "CC-BY-NC-4.0", 43 | "bugs": { 44 | "url": "https://github.com/Maybulb/Nimble/issues" 45 | }, 46 | "homepage": "https://github.com/Maybulb/Nimble#readme", 47 | "build": { 48 | "mac": { 49 | "target": "default", 50 | "icon": "assets/512.icns" 51 | }, 52 | "dmg": { 53 | "title": "Nimble", 54 | "icon": "assets/512.icns", 55 | "icon-size": 80, 56 | "background": "assets/nimback.png", 57 | "contents": [ 58 | { 59 | "x": 438, 60 | "y": 344, 61 | "type": "link", 62 | "path": "/Applications" 63 | }, 64 | { 65 | "x": 192, 66 | "y": 344, 67 | "type": "file" 68 | } 69 | ] 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/css/colours/blue.sass: -------------------------------------------------------------------------------- 1 | $red: #dc0000 2 | $nimble-orange: #ff8C12 3 | $bright-yellow: #FFCA30 4 | $green: #76be21 5 | $blue: #287ee8 6 | $purple: #b51bf5 7 | $font-family: 'BlinkMacSystemFont', system, -apple-system, ".SFNSDisplay-Regular", "Helvetica Neue", "Lucida Grande" 8 | 9 | 10 | body, html 11 | width: 100% 12 | display: block 13 | padding: 0 14 | margin: 0 15 | border: 0 16 | overflow: hidden 17 | 18 | body 19 | background: white 20 | 21 | div.interpret 22 | background: lighten($blue, 15%) 23 | font-family: $font-family 24 | font-size: 14px 25 | padding: 6px 16px 26 | width: calc(100% - 32px) 27 | color: white 28 | 29 | div#wolfram-credit 30 | background: $blue 31 | font-family: $font-family 32 | font-size: 14px 33 | color: white 34 | padding: 6px 16px 35 | height: 18px 36 | display: block 37 | 38 | span 39 | float: right 40 | height: 100% 41 | opacity: 0.8 42 | span, img 43 | vertical-align: middle 44 | -webkit-user-drag: none 45 | -webkit-user-select: none 46 | span img 47 | height: 100% 48 | 49 | // is it too late now to say sorry 50 | div.sorry 51 | font: normal normal normal 14px/1 FontAwesome 52 | color: $blue 53 | font-size: 72px 54 | text-align: center 55 | margin: 12px 0 6px 0 56 | 57 | p.err 58 | text-align: center 59 | line-height: 1.4 60 | 61 | div.output 62 | display: inline-block 63 | position: relative 64 | border: 0 65 | pointer-events: auto 66 | font-size: 1m 67 | padding: 12px 16px 68 | font-family: $font-family 69 | letter-spacing: 0.5px 70 | outline: none 71 | z-index: 1 72 | overflow-y: scroll 73 | 74 | // 380 is the magic number 75 | max-height: 380px 76 | 77 | // leaving this here for adam 78 | // ::selection 79 | // background: $blue 80 | // color: white 81 | 82 | div.output::-webkit-scrollbar 83 | display: none 84 | 85 | div.input 86 | display: relative 87 | width: 100% 88 | background: $blue 89 | color: white 90 | input[type=text] 91 | display: block 92 | position: relative 93 | background: transparent 94 | border: 0 95 | pointer-events: auto 96 | font-size: 1em 97 | padding: 12px 16px 98 | font-family: $font-family 99 | width: calc(100% - 32px - 42px) 100 | outline: none 101 | z-index: 1 102 | color: white 103 | // making the placeholder text darker than the greyed-out button looks nice af 104 | input[type=text]::-webkit-input-placeholder 105 | opacity: 0.75 106 | color: white 107 | button 108 | font: normal normal normal 14px/1 FontAwesome /* real talk this is weird */ 109 | font-weight: normal 110 | position: absolute 111 | margin: 0 112 | top: 5px 113 | right: 14px 114 | font-size: 14px 115 | border: 0 116 | outline: 0 117 | padding: 8px 118 | width: 30px 119 | max-height: 30px 120 | border-radius: 50% 121 | opacity: 0.7 122 | background: white 123 | transition: 0.25s /* fadey */ 124 | color: $blue 125 | z-index: 2 126 | border: none 127 | overflow: hidden 128 | // leaving this here for adam to touch 129 | // ::selection 130 | // color: $blue 131 | // background: white 132 | 133 | h1 134 | text-align: center 135 | 136 | a 137 | color: $blue 138 | 139 | hr 140 | background: black 141 | border: 1px solid black 142 | 143 | .image-output 144 | display: block 145 | -webkit-user-drag: none 146 | 147 | .animateLoader 148 | -webkit-animation: spin 0.75s ease-in-out infinite alternate 149 | -webkit-transform-origin: center 150 | 151 | @-webkit-keyframes spin 152 | from 153 | -webkit-transform: rotate(0deg) 154 | 155 | to 156 | -webkit-transform: rotate(360deg) 157 | 158 | h3 159 | border-top: 1px solid rgba(0, 0, 0, 0.3) 160 | font-size: 18px 161 | margin-top: 20px 162 | padding-top: 20px 163 | 164 | h3:first-of-type 165 | border: 0 166 | margin-top: 0 167 | padding-top: 0 168 | 169 | h5 170 | font-size: 14px 171 | margin: 0 172 | -------------------------------------------------------------------------------- /src/css/colours/bright-yellow.sass: -------------------------------------------------------------------------------- 1 | $red: #dc0000 2 | $nimble-orange: #ff8C12 3 | $bright-yellow: #FFCA30 4 | $green: #76be21 5 | $blue: #160ede 6 | $purple: #b51bf5 7 | $font-family: 'BlinkMacSystemFont', system, -apple-system, ".SFNSDisplay-Regular", "Helvetica Neue", "Lucida Grande" 8 | 9 | 10 | body, html 11 | width: 100% 12 | display: block 13 | padding: 0 14 | margin: 0 15 | border: 0 16 | overflow: hidden 17 | 18 | body 19 | background: white 20 | 21 | div.interpret 22 | background: darken($bright-yellow, 8%) 23 | font-family: $font-family 24 | font-size: 14px 25 | padding: 6px 16px 26 | width: calc(100% - 32px) 27 | color: white 28 | 29 | div#wolfram-credit 30 | background: $bright-yellow 31 | font-family: $font-family 32 | font-size: 14px 33 | color: white 34 | padding: 6px 16px 35 | height: 18px 36 | display: block 37 | 38 | span 39 | float: right 40 | height: 100% 41 | opacity: 0.8 42 | span, img 43 | vertical-align: middle 44 | -webkit-user-drag: none 45 | -webkit-user-select: none 46 | span img 47 | height: 100% 48 | 49 | // is it too late now to say sorry 50 | div.sorry 51 | font: normal normal normal 14px/1 FontAwesome 52 | color: $bright-yellow 53 | font-size: 72px 54 | text-align: center 55 | margin: 12px 0 6px 0 56 | 57 | p.err 58 | text-align: center 59 | line-height: 1.4 60 | 61 | div.output 62 | display: inline-block 63 | position: relative 64 | border: 0 65 | pointer-events: auto 66 | font-size: 1m 67 | padding: 12px 16px 68 | font-family: $font-family 69 | letter-spacing: 0.5px 70 | outline: none 71 | z-index: 1 72 | overflow-y: scroll 73 | 74 | // 380 is the magic number 75 | max-height: 380px 76 | 77 | // leaving this here for adam 78 | // ::selection 79 | // background: $bright-yellow 80 | // color: white 81 | 82 | div.output::-webkit-scrollbar 83 | display: none 84 | 85 | div.input 86 | display: relative 87 | width: 100% 88 | background: $bright-yellow 89 | color: white 90 | input[type=text] 91 | display: block 92 | position: relative 93 | background: transparent 94 | border: 0 95 | pointer-events: auto 96 | font-size: 1em 97 | padding: 12px 16px 98 | font-family: $font-family 99 | width: calc(100% - 32px - 42px) 100 | outline: none 101 | z-index: 1 102 | color: white 103 | // making the placeholder text darker than the greyed-out button looks nice af 104 | input[type=text]::-webkit-input-placeholder 105 | opacity: 0.75 106 | color: white 107 | button 108 | font: normal normal normal 14px/1 FontAwesome /* real talk this is weird */ 109 | font-weight: normal 110 | position: absolute 111 | margin: 0 112 | top: 5px 113 | right: 14px 114 | font-size: 14px 115 | border: 0 116 | outline: 0 117 | padding: 8px 118 | width: 30px 119 | max-height: 30px 120 | border-radius: 50% 121 | opacity: 0.7 122 | background: white 123 | transition: 0.25s /* fadey */ 124 | color: $bright-yellow 125 | z-index: 2 126 | border: none 127 | overflow: hidden 128 | // leaving this here for adam to touch 129 | // ::selection 130 | // color: $bright-yellow 131 | // background: white 132 | 133 | h1 134 | text-align: center 135 | 136 | a 137 | color: $bright-yellow 138 | 139 | hr 140 | background: black 141 | border: 1px solid black 142 | 143 | .image-output 144 | display: block 145 | -webkit-user-drag: none 146 | 147 | .animateLoader 148 | -webkit-animation: spin 0.75s ease-in-out infinite alternate 149 | -webkit-transform-origin: center 150 | 151 | @-webkit-keyframes spin 152 | from 153 | -webkit-transform: rotate(0deg) 154 | 155 | to 156 | -webkit-transform: rotate(360deg) 157 | 158 | h3 159 | border-top: 1px solid rgba(0, 0, 0, 0.3) 160 | font-size: 18px 161 | margin-top: 20px 162 | padding-top: 20px 163 | 164 | h3:first-of-type 165 | border: 0 166 | margin-top: 0 167 | padding-top: 0 168 | 169 | h5 170 | font-size: 14px 171 | margin: 0 172 | -------------------------------------------------------------------------------- /src/css/colours/green.sass: -------------------------------------------------------------------------------- 1 | $red: #f80a0a 2 | $nimble-orange: #ff8C12 3 | $bright-yellow: #FFCA30 4 | $green: #76be21 5 | $blue: #160ede 6 | $purple: #b51bf5 7 | $font-family: 'BlinkMacSystemFont', system, -apple-system, ".SFNSDisplay-Regular", "Helvetica Neue", "Lucida Grande" 8 | 9 | 10 | body, html 11 | width: 100% 12 | display: block 13 | padding: 0 14 | margin: 0 15 | border: 0 16 | overflow: hidden 17 | 18 | body 19 | background: white 20 | 21 | div.interpret 22 | background: lighten($green, 15%) 23 | font-family: $font-family 24 | font-size: 14px 25 | padding: 6px 16px 26 | width: calc(100% - 32px) 27 | color: white 28 | 29 | div#wolfram-credit 30 | background: $green 31 | font-family: $font-family 32 | font-size: 14px 33 | color: white 34 | padding: 6px 16px 35 | height: 18px 36 | display: block 37 | 38 | span 39 | float: right 40 | height: 100% 41 | opacity: 0.8 42 | span, img 43 | vertical-align: middle 44 | -webkit-user-drag: none 45 | -webkit-user-select: none 46 | span img 47 | height: 100% 48 | 49 | // is it too late now to say sorry 50 | div.sorry 51 | font: normal normal normal 14px/1 FontAwesome 52 | color: $green 53 | font-size: 72px 54 | text-align: center 55 | margin: 12px 0 6px 0 56 | 57 | p.err 58 | text-align: center 59 | line-height: 1.4 60 | 61 | div.output 62 | display: inline-block 63 | position: relative 64 | border: 0 65 | pointer-events: auto 66 | font-size: 1m 67 | padding: 12px 16px 68 | font-family: $font-family 69 | letter-spacing: 0.5px 70 | outline: none 71 | z-index: 1 72 | overflow-y: scroll 73 | 74 | // 380 is the magic number 75 | max-height: 380px 76 | 77 | // leaving this here for adam 78 | // ::selection 79 | // background: $green 80 | // color: white 81 | 82 | div.output::-webkit-scrollbar 83 | display: none 84 | 85 | div.input 86 | display: relative 87 | width: 100% 88 | background: $green 89 | color: white 90 | input[type=text] 91 | display: block 92 | position: relative 93 | background: transparent 94 | border: 0 95 | pointer-events: auto 96 | font-size: 1em 97 | padding: 12px 16px 98 | font-family: $font-family 99 | width: calc(100% - 32px - 42px) 100 | outline: none 101 | z-index: 1 102 | color: white 103 | // making the placeholder text darker than the greyed-out button looks nice af 104 | input[type=text]::-webkit-input-placeholder 105 | opacity: 0.75 106 | color: white 107 | button 108 | font: normal normal normal 14px/1 FontAwesome /* real talk this is weird */ 109 | font-weight: normal 110 | position: absolute 111 | margin: 0 112 | top: 5px 113 | right: 14px 114 | font-size: 14px 115 | border: 0 116 | outline: 0 117 | padding: 8px 118 | width: 30px 119 | max-height: 30px 120 | border-radius: 50% 121 | opacity: 0.7 122 | background: white 123 | transition: 0.25s /* fadey */ 124 | color: $green 125 | z-index: 2 126 | border: none 127 | overflow: hidden 128 | // leaving this here for adam to touch 129 | // ::selection 130 | // color: $green 131 | // background: white 132 | 133 | h1 134 | text-align: center 135 | 136 | a 137 | color: $green 138 | 139 | hr 140 | background: black 141 | border: 1px solid black 142 | 143 | .image-output 144 | display: block 145 | -webkit-user-drag: none 146 | 147 | .animateLoader 148 | -webkit-animation: spin 0.75s ease-in-out infinite alternate 149 | -webkit-transform-origin: center 150 | 151 | @-webkit-keyframes spin 152 | from 153 | -webkit-transform: rotate(0deg) 154 | 155 | to 156 | -webkit-transform: rotate(360deg) 157 | 158 | h3 159 | border-top: 1px solid rgba(0, 0, 0, 0.3) 160 | font-size: 18px 161 | margin-top: 20px 162 | padding-top: 20px 163 | 164 | h3:first-of-type 165 | border: 0 166 | margin-top: 0 167 | padding-top: 0 168 | 169 | h5 170 | font-size: 14px 171 | margin: 0 172 | -------------------------------------------------------------------------------- /src/css/colours/pink.sass: -------------------------------------------------------------------------------- 1 | $red: #dc0000 2 | $nimble-orange: #ff8C12 3 | $bright-yellow: #FFCA30 4 | $green: #76be21 5 | $blue: #287ee8 6 | $purple: #6105b0 7 | $pink: #d205a0 8 | $font-family: 'BlinkMacSystemFont', system, -apple-system, ".SFNSDisplay-Regular", "Helvetica Neue", "Lucida Grande" 9 | 10 | 11 | body, html 12 | width: 100% 13 | display: block 14 | padding: 0 15 | margin: 0 16 | border: 0 17 | overflow: hidden 18 | 19 | body 20 | background: white 21 | 22 | div.interpret 23 | background: lighten($purple, 15%) 24 | font-family: $font-family 25 | font-size: 14px 26 | padding: 6px 16px 27 | width: calc(100% - 32px) 28 | color: white 29 | 30 | div#wolfram-credit 31 | background: $purple 32 | font-family: $font-family 33 | font-size: 14px 34 | color: white 35 | padding: 6px 16px 36 | height: 18px 37 | display: block 38 | 39 | span 40 | float: right 41 | height: 100% 42 | opacity: 0.8 43 | span, img 44 | vertical-align: middle 45 | -webkit-user-drag: none 46 | -webkit-user-select: none 47 | span img 48 | height: 100% 49 | 50 | // is it too late now to say sorry 51 | div.sorry 52 | font: normal normal normal 14px/1 FontAwesome 53 | color: $purple 54 | font-size: 72px 55 | text-align: center 56 | margin: 12px 0 6px 0 57 | 58 | p.err 59 | text-align: center 60 | line-height: 1.4 61 | 62 | div.output 63 | display: inline-block 64 | position: relative 65 | border: 0 66 | pointer-events: auto 67 | font-size: 1m 68 | padding: 12px 16px 69 | font-family: $font-family 70 | letter-spacing: 0.5px 71 | outline: none 72 | z-index: 1 73 | overflow-y: scroll 74 | 75 | // 380 is the magic number 76 | max-height: 380px 77 | 78 | // leaving this here for adam 79 | // ::selection 80 | // background: $purple 81 | // color: white 82 | 83 | div.output::-webkit-scrollbar 84 | display: none 85 | 86 | div.input 87 | display: relative 88 | width: 100% 89 | background: $purple 90 | color: white 91 | input[type=text] 92 | display: block 93 | position: relative 94 | background: transparent 95 | border: 0 96 | pointer-events: auto 97 | font-size: 1em 98 | padding: 12px 16px 99 | font-family: $font-family 100 | width: calc(100% - 32px - 42px) 101 | outline: none 102 | z-index: 1 103 | color: white 104 | // making the placeholder text darker than the greyed-out button looks nice af 105 | input[type=text]::-webkit-input-placeholder 106 | opacity: 0.75 107 | color: white 108 | button 109 | font: normal normal normal 14px/1 FontAwesome /* real talk this is weird */ 110 | font-weight: normal 111 | position: absolute 112 | margin: 0 113 | top: 5px 114 | right: 14px 115 | font-size: 14px 116 | border: 0 117 | outline: 0 118 | padding: 8px 119 | width: 30px 120 | max-height: 30px 121 | border-radius: 50% 122 | opacity: 0.7 123 | background: white 124 | transition: 0.25s /* fadey */ 125 | color: $purple 126 | z-index: 2 127 | border: none 128 | overflow: hidden 129 | // leaving this here for adam to touch 130 | // ::selection 131 | // color: $purple 132 | // background: white 133 | 134 | h1 135 | text-align: center 136 | 137 | a 138 | color: $purple 139 | 140 | hr 141 | background: black 142 | border: 1px solid black 143 | 144 | .image-output 145 | display: block 146 | -webkit-user-drag: none 147 | 148 | .animateLoader 149 | -webkit-animation: spin 0.75s ease-in-out infinite alternate 150 | -webkit-transform-origin: center 151 | 152 | @-webkit-keyframes spin 153 | from 154 | -webkit-transform: rotate(0deg) 155 | 156 | to 157 | -webkit-transform: rotate(360deg) 158 | 159 | h3 160 | border-top: 1px solid rgba(0, 0, 0, 0.3) 161 | font-size: 18px 162 | margin-top: 20px 163 | padding-top: 20px 164 | 165 | h3:first-of-type 166 | border: 0 167 | margin-top: 0 168 | padding-top: 0 169 | 170 | h5 171 | font-size: 14px 172 | margin: 0 173 | -------------------------------------------------------------------------------- /src/css/colours/purple.sass: -------------------------------------------------------------------------------- 1 | $red: #dc0000 2 | $nimble-orange: #ff8C12 3 | $bright-yellow: #FFCA30 4 | $green: #76be21 5 | $blue: #287ee8 6 | $purple: #6105b0 7 | $pink: #d205a0 8 | $font-family: 'BlinkMacSystemFont', system, -apple-system, ".SFNSDisplay-Regular", "Helvetica Neue", "Lucida Grande" 9 | 10 | 11 | body, html 12 | width: 100% 13 | display: block 14 | padding: 0 15 | margin: 0 16 | border: 0 17 | overflow: hidden 18 | 19 | body 20 | background: white 21 | 22 | div.interpret 23 | background: lighten($pink, 15%) 24 | font-family: $font-family 25 | font-size: 14px 26 | padding: 6px 16px 27 | width: calc(100% - 32px) 28 | color: white 29 | 30 | div#wolfram-credit 31 | background: $pink 32 | font-family: $font-family 33 | font-size: 14px 34 | color: white 35 | padding: 6px 16px 36 | height: 18px 37 | display: block 38 | 39 | span 40 | float: right 41 | height: 100% 42 | opacity: 0.8 43 | span, img 44 | vertical-align: middle 45 | -webkit-user-drag: none 46 | -webkit-user-select: none 47 | span img 48 | height: 100% 49 | 50 | // is it too late now to say sorry 51 | div.sorry 52 | font: normal normal normal 14px/1 FontAwesome 53 | color: $pink 54 | font-size: 72px 55 | text-align: center 56 | margin: 12px 0 6px 0 57 | 58 | p.err 59 | text-align: center 60 | line-height: 1.4 61 | 62 | div.output 63 | display: inline-block 64 | position: relative 65 | border: 0 66 | pointer-events: auto 67 | font-size: 1m 68 | padding: 12px 16px 69 | font-family: $font-family 70 | letter-spacing: 0.5px 71 | outline: none 72 | z-index: 1 73 | overflow-y: scroll 74 | 75 | // 380 is the magic number 76 | max-height: 380px 77 | 78 | // leaving this here for adam 79 | // ::selection 80 | // background: $pink 81 | // color: white 82 | 83 | div.output::-webkit-scrollbar 84 | display: none 85 | 86 | div.input 87 | display: relative 88 | width: 100% 89 | background: $pink 90 | color: white 91 | input[type=text] 92 | display: block 93 | position: relative 94 | background: transparent 95 | border: 0 96 | pointer-events: auto 97 | font-size: 1em 98 | padding: 12px 16px 99 | font-family: $font-family 100 | width: calc(100% - 32px - 42px) 101 | outline: none 102 | z-index: 1 103 | color: white 104 | // making the placeholder text darker than the greyed-out button looks nice af 105 | input[type=text]::-webkit-input-placeholder 106 | opacity: 0.75 107 | color: white 108 | button 109 | font: normal normal normal 14px/1 FontAwesome /* real talk this is weird */ 110 | font-weight: normal 111 | position: absolute 112 | margin: 0 113 | top: 5px 114 | right: 14px 115 | font-size: 14px 116 | border: 0 117 | outline: 0 118 | padding: 8px 119 | width: 30px 120 | max-height: 30px 121 | border-radius: 50% 122 | opacity: 0.7 123 | background: white 124 | transition: 0.25s /* fadey */ 125 | color: $pink 126 | z-index: 2 127 | border: none 128 | overflow: hidden 129 | // leaving this here for adam to touch 130 | // ::selection 131 | // color: $pink 132 | // background: white 133 | 134 | h1 135 | text-align: center 136 | 137 | a 138 | color: $pink 139 | 140 | hr 141 | background: black 142 | border: 1px solid black 143 | 144 | .image-output 145 | display: block 146 | -webkit-user-drag: none 147 | 148 | .animateLoader 149 | -webkit-animation: spin 0.75s ease-in-out infinite alternate 150 | -webkit-transform-origin: center 151 | 152 | @-webkit-keyframes spin 153 | from 154 | -webkit-transform: rotate(0deg) 155 | 156 | to 157 | -webkit-transform: rotate(360deg) 158 | 159 | h3 160 | border-top: 1px solid rgba(0, 0, 0, 0.3) 161 | font-size: 18px 162 | margin-top: 20px 163 | padding-top: 20px 164 | 165 | h3:first-of-type 166 | border: 0 167 | margin-top: 0 168 | padding-top: 0 169 | 170 | h5 171 | font-size: 14px 172 | margin: 0 -------------------------------------------------------------------------------- /src/css/colours/red.sass: -------------------------------------------------------------------------------- 1 | $red: #dc0000 2 | $nimble-orange: #ff8C12 3 | $bright-yellow: #FFCA30 4 | $green: #76be21 5 | $blue: #160ede 6 | $purple: #b51bf5 7 | $font-family: 'BlinkMacSystemFont', system, -apple-system, ".SFNSDisplay-Regular", "Helvetica Neue", "Lucida Grande" 8 | 9 | 10 | body, html 11 | width: 100% 12 | display: block 13 | padding: 0 14 | margin: 0 15 | border: 0 16 | overflow: hidden 17 | 18 | body 19 | background: white 20 | 21 | div.interpret 22 | background: lighten($red, 15%) 23 | font-family: $font-family 24 | font-size: 14px 25 | padding: 6px 16px 26 | width: calc(100% - 32px) 27 | color: white 28 | 29 | div#wolfram-credit 30 | background: $red 31 | font-family: $font-family 32 | font-size: 14px 33 | color: white 34 | padding: 6px 16px 35 | height: 18px 36 | display: block 37 | 38 | span 39 | float: right 40 | height: 100% 41 | opacity: 0.8 42 | span, img 43 | vertical-align: middle 44 | -webkit-user-drag: none 45 | -webkit-user-select: none 46 | span img 47 | height: 100% 48 | 49 | // is it too late now to say sorry 50 | div.sorry 51 | font: normal normal normal 14px/1 FontAwesome 52 | color: $red 53 | font-size: 72px 54 | text-align: center 55 | margin: 12px 0 6px 0 56 | 57 | p.err 58 | text-align: center 59 | line-height: 1.4 60 | 61 | div.output 62 | display: inline-block 63 | position: relative 64 | border: 0 65 | pointer-events: auto 66 | font-size: 1m 67 | padding: 12px 16px 68 | font-family: $font-family 69 | letter-spacing: 0.5px 70 | outline: none 71 | z-index: 1 72 | overflow-y: scroll 73 | 74 | // 380 is the magic number 75 | max-height: 380px 76 | 77 | // leaving this here for adam 78 | // ::selection 79 | // background: $red 80 | // color: white 81 | 82 | div.output::-webkit-scrollbar 83 | display: none 84 | 85 | div.input 86 | display: relative 87 | width: 100% 88 | background: $red 89 | color: white 90 | input[type=text] 91 | display: block 92 | position: relative 93 | background: transparent 94 | border: 0 95 | pointer-events: auto 96 | font-size: 1em 97 | padding: 12px 16px 98 | font-family: $font-family 99 | width: calc(100% - 32px - 42px) 100 | outline: none 101 | z-index: 1 102 | color: white 103 | // making the placeholder text darker than the greyed-out button looks nice af 104 | input[type=text]::-webkit-input-placeholder 105 | opacity: 0.75 106 | color: white 107 | button 108 | font: normal normal normal 14px/1 FontAwesome /* real talk this is weird */ 109 | font-weight: normal 110 | position: absolute 111 | margin: 0 112 | top: 5px 113 | right: 14px 114 | font-size: 14px 115 | border: 0 116 | outline: 0 117 | padding: 8px 118 | width: 30px 119 | max-height: 30px 120 | border-radius: 50% 121 | opacity: 0.7 122 | background: white 123 | transition: 0.25s /* fadey */ 124 | color: $red 125 | z-index: 2 126 | border: none 127 | overflow: hidden 128 | // leaving this here for adam to touch 129 | // ::selection 130 | // color: $red 131 | // background: white 132 | 133 | h1 134 | text-align: center 135 | 136 | a 137 | color: $red 138 | 139 | hr 140 | background: black 141 | border: 1px solid black 142 | 143 | .image-output 144 | display: block 145 | -webkit-user-drag: none 146 | 147 | .animateLoader 148 | -webkit-animation: spin 0.75s ease-in-out infinite alternate 149 | -webkit-transform-origin: center 150 | 151 | @-webkit-keyframes spin 152 | from 153 | -webkit-transform: rotate(0deg) 154 | 155 | to 156 | -webkit-transform: rotate(360deg) 157 | 158 | h3 159 | border-top: 1px solid rgba(0, 0, 0, 0.3) 160 | font-size: 18px 161 | margin-top: 20px 162 | padding-top: 20px 163 | 164 | h3:first-of-type 165 | border: 0 166 | margin-top: 0 167 | padding-top: 0 168 | 169 | h5 170 | font-size: 14px 171 | margin: 0 172 | -------------------------------------------------------------------------------- /src/css/highcontrast.sass: -------------------------------------------------------------------------------- 1 | $red: #f80a0a 2 | $nimble-orange: #ff8C12 3 | $bright-yellow: #FFCA30 4 | $green: #76be21 5 | $blue: #160ede 6 | $purple: #b51bf5 7 | $font-family: 'BlinkMacSystemFont', system, -apple-system, ".SFNSDisplay-Regular", "Helvetica Neue", "Lucida Grande" 8 | 9 | 10 | body, html 11 | width: 100% 12 | display: block 13 | padding: 0 14 | margin: 0 15 | border: 0 16 | overflow: hidden 17 | 18 | body 19 | background: white 20 | 21 | div.interpret 22 | background: black 23 | font-family: $font-family 24 | font-size: 14px 25 | padding: 6px 16px 26 | width: calc(100% - 32px) 27 | color: white 28 | border-top: 1px solid rgba(255, 255, 255, 0.5) 29 | 30 | div#wolfram-credit 31 | background: black 32 | font-family: $font-family 33 | font-size: 14px 34 | color: white 35 | padding: 6px 16px 36 | height: 18px 37 | display: block 38 | 39 | span 40 | float: right 41 | height: 100% 42 | span, img 43 | vertical-align: middle 44 | -webkit-user-drag: none 45 | -webkit-user-select: none 46 | span img 47 | height: 100% 48 | 49 | // is it too late now to say sorry 50 | div.sorry 51 | font: normal normal normal 14px/1 FontAwesome 52 | color: #000 53 | font-size: 72px 54 | text-align: center 55 | margin: 12px 0 6px 0 56 | 57 | p.err 58 | text-align: center 59 | line-height: 1.4 60 | 61 | div.output 62 | display: inline-block 63 | position: relative 64 | border: 0 65 | pointer-events: auto 66 | font-size: 1m 67 | padding: 12px 16px 68 | font-family: $font-family 69 | letter-spacing: 0.5px 70 | outline: none 71 | z-index: 1 72 | overflow-y: scroll 73 | max-height: 380px 74 | ::selection 75 | background: white 76 | color: #000 77 | 78 | div.output::-webkit-scrollbar 79 | display: none 80 | 81 | div.input 82 | display: relative 83 | width: 100% 84 | background: #000 85 | color: white 86 | input[type=text] 87 | display: block 88 | position: relative 89 | background: transparent 90 | border: 0 91 | pointer-events: auto 92 | font-size: 1em 93 | padding: 12px 16px 94 | font-family: $font-family 95 | width: calc(100% - 32px - 42px) 96 | outline: none 97 | z-index: 1 98 | color: white 99 | // making the placeholder text darker than the greyed-out button looks nice af 100 | input[type=text]::-webkit-input-placeholder 101 | opacity: 0.75 102 | color: white 103 | button 104 | font: normal normal normal 14px/1 FontAwesome /* real talk this is weird */ 105 | font-weight: normal 106 | position: absolute 107 | margin: 0 108 | top: 5px 109 | right: 14px 110 | font-size: 14px 111 | border: 0 112 | outline: 0 113 | padding: 8px 114 | width: 30px 115 | max-height: 30px 116 | border-radius: 50% 117 | opacity: 0.7 118 | background: white 119 | transition: 0.25s /* fadey */ 120 | color: black 121 | z-index: 2 122 | border: none 123 | overflow: hidden 124 | ::selection 125 | color: white 126 | background: #000 127 | 128 | h1 129 | text-align: center 130 | 131 | a 132 | color: #000 133 | 134 | hr 135 | background: black 136 | border: 1px solid black 137 | 138 | .image-output 139 | display: block 140 | -webkit-user-drag: none 141 | 142 | .animateLoader 143 | -webkit-animation: spin 0.75s ease-in-out infinite alternate 144 | -webkit-transform-origin: center 145 | 146 | @-webkit-keyframes spin 147 | from 148 | -webkit-transform: rotate(0deg) 149 | 150 | to 151 | -webkit-transform: rotate(360deg) 152 | 153 | h3 154 | border-top: 1px solid rgba(0, 0, 0, 0.3) 155 | font-size: 18px 156 | margin-top: 20px 157 | padding-top: 20px 158 | 159 | h3:first-of-type 160 | border: 0 161 | margin-top: 0 162 | padding-top: 0 163 | 164 | h5 165 | font-size: 14px 166 | margin: 0 167 | -------------------------------------------------------------------------------- /src/css/style.sass: -------------------------------------------------------------------------------- 1 | $red: #dc0000 2 | $nimble-orange: #ff8C12 3 | $bright-yellow: #FFCA30 4 | $green: #76be21 5 | $blue: #287ee8 6 | $purple: #6105b0 7 | $pink: #d205a0 8 | $font-family: 'BlinkMacSystemFont', system, -apple-system, ".SFNSDisplay-Regular", "Helvetica Neue", "Lucida Grande" 9 | 10 | 11 | body, html 12 | width: 100% 13 | display: block 14 | padding: 0 15 | margin: 0 16 | border: 0 17 | overflow: hidden 18 | 19 | body 20 | background: white 21 | 22 | div.interpret 23 | background: lighten($nimble-orange, 15%) 24 | font-family: $font-family 25 | font-size: 14px 26 | padding: 6px 16px 27 | width: calc(100% - 32px) 28 | color: white 29 | 30 | div#wolfram-credit 31 | background: $nimble-orange 32 | font-family: $font-family 33 | font-size: 14px 34 | color: white 35 | padding: 6px 16px 36 | height: 18px 37 | display: block 38 | 39 | span 40 | float: right 41 | height: 100% 42 | opacity: 0.8 43 | span, img 44 | vertical-align: middle 45 | -webkit-user-drag: none 46 | -webkit-user-select: none 47 | span img 48 | height: 100% 49 | 50 | // is it too late now to say sorry 51 | div.sorry 52 | font: normal normal normal 14px/1 FontAwesome 53 | color: $nimble-orange 54 | font-size: 72px 55 | text-align: center 56 | margin: 12px 0 6px 0 57 | 58 | p.err 59 | text-align: center 60 | line-height: 1.4 61 | 62 | div.output 63 | display: inline-block 64 | position: relative 65 | border: 0 66 | pointer-events: auto 67 | font-size: 1m 68 | padding: 12px 16px 69 | font-family: $font-family 70 | letter-spacing: 0.5px 71 | outline: none 72 | z-index: 1 73 | overflow-y: scroll 74 | 75 | // 380 is the magic number 76 | max-height: 380px 77 | 78 | // leaving this here for adam 79 | // ::selection 80 | // background: $nimble-orange 81 | // color: white 82 | 83 | div.output::-webkit-scrollbar 84 | display: none 85 | 86 | div.input 87 | display: relative 88 | width: 100% 89 | background: $nimble-orange 90 | color: white 91 | input[type=text] 92 | display: block 93 | position: relative 94 | background: transparent 95 | border: 0 96 | pointer-events: auto 97 | font-size: 1em 98 | padding: 12px 16px 99 | font-family: $font-family 100 | width: calc(100% - 32px - 42px) 101 | outline: none 102 | z-index: 1 103 | color: white 104 | // making the placeholder text darker than the greyed-out button looks nice af 105 | input[type=text]::-webkit-input-placeholder 106 | opacity: 0.75 107 | color: white 108 | button 109 | font: normal normal normal 14px/1 FontAwesome /* real talk this is weird */ 110 | font-weight: normal 111 | position: absolute 112 | margin: 0 113 | top: 5px 114 | right: 14px 115 | font-size: 14px 116 | border: 0 117 | outline: 0 118 | padding: 8px 119 | width: 30px 120 | max-height: 30px 121 | border-radius: 50% 122 | opacity: 0.7 123 | background: white 124 | transition: 0.25s /* fadey */ 125 | color: $nimble-orange 126 | z-index: 2 127 | border: none 128 | overflow: hidden 129 | // leaving this here for adam to touch 130 | // ::selection 131 | // color: $nimble-orange 132 | // background: white 133 | 134 | h1 135 | text-align: center 136 | 137 | a 138 | color: $nimble-orange 139 | 140 | hr 141 | background: black 142 | border: 1px solid black 143 | 144 | .image-output 145 | display: block 146 | -webkit-user-drag: none 147 | 148 | .animateLoader 149 | -webkit-animation: spin 0.75s ease-in-out infinite alternate 150 | -webkit-transform-origin: center 151 | 152 | @-webkit-keyframes spin 153 | from 154 | -webkit-transform: rotate(0deg) 155 | 156 | to 157 | -webkit-transform: rotate(360deg) 158 | 159 | h3 160 | border-top: 1px solid rgba(0, 0, 0, 0.3) 161 | font-size: 18px 162 | margin-top: 20px 163 | padding-top: 20px 164 | 165 | h3:first-of-type 166 | border: 0 167 | margin-top: 0 168 | padding-top: 0 169 | 170 | h5 171 | font-size: 14px 172 | margin: 0 173 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Nimble 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 33 | 34 | 35 | 36 |
37 | 38 | 41 |
42 | 43 |
44 | Interpreted as: query interpretation 45 |
46 | 47 |
48 |
49 | 50 |
51 |
52 | 53 |
54 | powered by 55 |
56 | 57 | 59 | 305 | 306 | 307 | -------------------------------------------------------------------------------- /src/js/script.js: -------------------------------------------------------------------------------- 1 | var $ = require('jquery'), 2 | util = require('util'), 3 | rand = require('rand-paul'), 4 | electron = require('electron'), 5 | format = require('string-format'), 6 | key = require('./js/key.json'), 7 | os = require('os'), 8 | wolfram = require('wolfram-alpha').createClient(key.api, { 9 | width: 348, 10 | maxwidth: 380 11 | }), 12 | math = require("mathjs"), 13 | Shell = electron.shell, 14 | msg = new SpeechSynthesisUtterance(), 15 | clipboard = electron.clipboard, 16 | nativeImage = electron.nativeImage, 17 | ipcRenderer = electron.ipcRenderer, 18 | URL = "https://nimble-backend.herokuapp.com/input?i=%s", 19 | unicode = /(?:\\:)(([a-z]|[0-9])+)/g, 20 | imagesLoaded = require('imagesloaded'), 21 | WebFrame = require('web-frame'); 22 | 23 | window.suggestions = getSuggestions(); 24 | 25 | function getSuggestions() { 26 | var suggestions = []; 27 | var defaultSuggestions = require('./js/suggestions.json'); 28 | suggestions = suggestions.concat(defaultSuggestions); 29 | try { 30 | if (window.options.enableDefaultSuggestions === false) { 31 | suggestions.length = 0; 32 | } 33 | if (window.options.customSuggestions) { 34 | suggestions = suggestions.concat(rc.customSuggestions); 35 | } 36 | } catch(err) { 37 | Bugsnag.notifyException(err); 38 | } 39 | if (!suggestions.length) { 40 | suggestions.push(''); 41 | } 42 | return suggestions; 43 | } 44 | 45 | var clipboardCopy = { 46 | link: function() { 47 | clipboard.writeText(window.links.wolfram); 48 | }, 49 | text: function() { 50 | if ($(".image-output").length) { 51 | clipboard.writeText(backdoor.unicodeRegex(window.json[window.imgHover[0]].subpods[window.imgHover[1]].text)[1]); 52 | } else { 53 | clipboard.writeText($("#output").text()) 54 | } 55 | }, 56 | image: function() { 57 | // send with ipc to index.js, for now a WIP 58 | var image = nativeImage.createFromPath(webContents.downloadURL(window.json[1].subpods[0].image)) 59 | clipboard.writeImage(image); 60 | } 61 | } 62 | 63 | // share buttons 64 | var shareButton = { 65 | twitter: function() { 66 | var tweet = $("#input").val() + ":\n" + window.links.wolfram + " (via @nimbledotapp)"; 67 | Shell.openExternal("https://twitter.com/intent/tweet?text=" + encodeURIComponent(tweet)) 68 | } 69 | } 70 | 71 | function defaults(test, fallback) { 72 | return typeof test !== 'undefined' ? test : fallback; 73 | } 74 | 75 | // options 76 | var preferences = { 77 | save: function() { 78 | var submenu = menuthing.items[menuthing.items.length - 1].submenu.items; 79 | var themeMenu = menuthing.items[menuthing.items.length - 2].submenu.items; 80 | 81 | window.options = { 82 | mathjs: defaults(submenu[0].checked, true), 83 | startup: defaults(submenu[1].checked, true), 84 | center: defaults(submenu[2].checked, false), 85 | bugreport: defaults(submenu[3].checked, true), 86 | autoupdate: defaults(submenu[4].checked, true), 87 | theme: { 88 | "red": themeMenu[0].checked, 89 | "orange": themeMenu[1].checked, 90 | "yellow": themeMenu[2].checked, 91 | "green": themeMenu[3].checked, 92 | "blue": themeMenu[4].checked, 93 | "purple": themeMenu[6].checked, 94 | "pink": themeMenu[5].checked, 95 | "contrast": themeMenu[7].checked 96 | }, 97 | enableDefaultSuggestions: defaults(submenu[5].checked, true), 98 | customSuggestions: defaults(window.options.customSuggestions, []) 99 | }; 100 | 101 | ipcRenderer.send("save_options", JSON.stringify(window.options, null, " ")); 102 | 103 | preferences.theme(); 104 | }, 105 | theme: function() { 106 | if (window.options.theme["red"] === true) { 107 | $("#style").attr("href", "css/colours/red.css") 108 | } else if (window.options.theme["contrast"] === true) { 109 | $("#style").attr("href", "css/highcontrast.css") 110 | } else if (window.options.theme["orange"] === true) { 111 | $("#style").attr("href", "css/style.css") 112 | } else if (window.options.theme["yellow"] === true) { 113 | $("#style").attr("href", "css/colours/bright-yellow.css") 114 | } else if (window.options.theme["green"] === true) { 115 | $("#style").attr("href", "css/colours/green.css") 116 | } else if (window.options.theme["blue"] === true) { 117 | $("#style").attr("href", "css/colours/blue.css") 118 | } else if (window.options.theme["purple"] === true) { 119 | $("#style").attr("href", "css/colours/purple.css") 120 | } else if (window.options.theme["pink"] === true) { 121 | $("#style").attr("href", "css/colours/pink.css") 122 | } 123 | } 124 | }; 125 | 126 | // most misc backdoor/electron/helper functions here 127 | var backdoor = { 128 | resizeWindow: function(error) { 129 | var h = $("body").height(); 130 | var w = $(".output").width() + 32; 131 | 132 | if (w < 380 && error !== true) { 133 | w = 380; 134 | } 135 | 136 | ipcRenderer.send("resize", { 137 | height: h, 138 | width: w 139 | }); 140 | }, 141 | speak: function(text) { 142 | msg.voiceURI = 'native'; 143 | msg.volume = 1; // 0 to 1 144 | msg.rate = 0.8; // 0.1 to 10 145 | msg.pitch = 1; //0 to 2 146 | msg.text = text; 147 | msg.lang = 'en-UK'; 148 | 149 | console.log("Nimble just said \"" + text + "\" using the Speech Synthesizer.") 150 | speechSynthesis.cancel(); 151 | speechSynthesis.speak(msg); 152 | }, 153 | unicodeRegex: function(text) { 154 | // html encoded unicode string (&#unicode;) 155 | var newHtml = text.replace(unicode, function(match, p1, p2) { 156 | return "&#" + parseInt(p1, 16).toString(10) + ";"; 157 | }); 158 | 159 | // plain ol straight unicode string (used for copying to clipboard) 160 | var newText = text.replace(unicode, function(match, p1, p2) { 161 | return String.fromCodePoint(parseInt(p1, 16).toString(10)) 162 | }); 163 | 164 | return [newHtml, newText] 165 | } 166 | } 167 | 168 | var loader = function(state) { 169 | if (state === true) { 170 | $("div.input i").slideUp(200, function() { 171 | $("div.input i").attr("class", "fa fa-refresh").attr("disabled", "disabled").addClass("animateLoader"); 172 | }).slideDown(500); 173 | ipcRenderer.send("reset-window"); 174 | } else { 175 | $("div.input i").slideUp(200, function() { 176 | $("div.input i").attr("class", "fa fa-search").removeAttr("disabled").removeClass("animateLoader"); 177 | }).slideDown(500); 178 | backdoor.resizeWindow(); 179 | } 180 | } 181 | 182 | // error forwarding 183 | var _windowonerror = window.onerror; 184 | window.onerror = function(e) { 185 | ipcRenderer.send('node_console', { 186 | m: e 187 | }); 188 | if (typeof _windowonerror === 'function') { 189 | _windowonerror.apply(this, arguments); 190 | } 191 | } 192 | 193 | var _consolelog = console.log.bind(console); 194 | console.log = function log(message) { 195 | ipcRenderer.send('node_console', {m: message}); 196 | _consolelog(message); 197 | }; 198 | 199 | // check if everything is alright before querying wolfram 200 | function preQuery() { 201 | if ($('#input').val() !== "") { 202 | query(); 203 | } else if ($('#input').val() === "") { 204 | // save current placeholder 205 | var currentPlaceholder = $("#input").attr('placeholder'); 206 | 207 | // ask user to use their words 208 | $("#input").attr('placeholder', "Error: Use your words."); 209 | 210 | // go back to placeholders 211 | window.setTimeout(function() { 212 | $('#input').attr('placeholder', currentPlaceholder); 213 | }, 3000); 214 | } 215 | } 216 | 217 | $(document).keypress(function(event) { 218 | // if the key ya pressed is enter, start to query 219 | if(event.which === 13) { 220 | preQuery(); 221 | } 222 | }); 223 | 224 | $(document).keydown(function(event) { 225 | // placeholder plop 226 | if(event.which === 39 && $("#input").val() === "") { 227 | $("#input").val($("#input").attr("placeholder")) 228 | } 229 | }); 230 | 231 | $(document).ready(function() { 232 | function newPlaceholder() { 233 | // set placeholder 234 | var placeholder = rand.paul(window.suggestions); 235 | $('#input').attr('placeholder', placeholder); 236 | } 237 | 238 | setInterval(newPlaceholder, 10000); 239 | 240 | // search button 241 | $("#input").keyup(function() { 242 | if (this.value == "") { 243 | $(".input button").css("opacity", "0.7"); 244 | } else { 245 | $(".input button").css("opacity", "1"); 246 | } 247 | }); 248 | 249 | // on window open select the input for conveinence 250 | ipcRenderer.on("window-open", function() { 251 | $("#input").focus().select(); 252 | }); 253 | 254 | ipcRenderer.on("log", function(m) { 255 | _consolelog(m) 256 | }) 257 | 258 | ipcRenderer.on("error", function(e) { 259 | _consolelog("Error from backend:" + e) 260 | }) 261 | 262 | ipcRenderer.on("did-save-options", function(e) { 263 | window.suggestions = getSuggestions(); 264 | newPlaceholder(); 265 | }); 266 | 267 | // on right click 268 | ipcRenderer.on("tray-rightclick", function() { 269 | // pop up menu 270 | menuthing.popup(remote.getCurrentWindow()); 271 | }); 272 | 273 | // make image loaded checker a jquery plugin for god's sake 274 | imagesLoaded.makeJQueryPlugin($); 275 | 276 | // set zoom level limits 277 | WebFrame.setZoomLevelLimits(1,1); 278 | 279 | // set theme 280 | preferences.theme(); 281 | }); 282 | 283 | // main shit here boys 284 | var query = function() { 285 | var input = $('#input').val(); 286 | var result; 287 | 288 | var encodedQuery = encodeURIComponent(input); 289 | var queryURL = util.format(URL, encodedQuery); 290 | 291 | window.links = { 292 | wolfram: "http://www.wolframalpha.com/input/?i=" + encodedQuery 293 | }; 294 | 295 | // in this try block, we try mathjs 296 | try { 297 | if (window.options.mathjs === true) { 298 | result = math.eval(input); 299 | if (math.typeof(result) === "Function") { 300 | throw(new Error("Math.js is sending us a function again...")); 301 | } else { 302 | result = result.toString(); 303 | } 304 | } else if (window.options.mathjs === false) { 305 | throw(new Error("Math.js has been disabled by the user.")) 306 | } 307 | 308 | $("#output").html(result); 309 | $(".interpret, #wolfram-credit").css("display", "none"); 310 | backdoor.resizeWindow(); 311 | 312 | // speak result if speech is on 313 | if(window.options.speech === true) { 314 | backdoor.speak($('#output').text()) 315 | } 316 | } catch (e) { 317 | // if input isn't math throw error and use wolfram code 318 | console.log("Input is not math. Using Wolfram|Alpha. If you'd like, the error message given by MathJS is as follows:\n" + e); 319 | var encodedQuery = encodeURIComponent(input); 320 | var queryURL = util.format(URL, encodedQuery); 321 | 322 | window.links = { 323 | // google: "https://www.google.ca/#q=" + encodedQuery, 324 | wolfram: "http://www.wolframalpha.com/input/?i=" + encodedQuery 325 | }; 326 | 327 | // loader 328 | loader(true); 329 | 330 | wolfram.query(input, function(err, queryResult) { 331 | try { 332 | window.json = queryResult; 333 | 334 | var inputInterpretation = backdoor.unicodeRegex(window.json.shift().subpods[0].text)[0]; 335 | 336 | $(".interpret, #wolfram-credit").css("display", "block"); 337 | $("#wolframlink").attr("onclick", "Shell.openExternal(\"" + window.links.wolfram + "\");"); 338 | $("#queryInterpretation").html(inputInterpretation); 339 | 340 | var output = ""; 341 | 342 | // look through each pod 343 | for (i = 0; i !== window.json.length; i++) { 344 | // title each pod 345 | if (window.json.length !== 1) { 346 | output += "

" + window.json[i].title + "

" 347 | } 348 | 349 | // look through the subpods of each pod 350 | for (j = 0; j !== window.json[i].subpods.length; j++) { 351 | // add each subpod 352 | // sidenote: the onmouseover thing is a hacky solution 353 | // that tells the copy plaintext function what 354 | // subpod's text to copy based on what you're hovering over 355 | 356 | output += "\"""; 357 | 358 | // if the for loop hasn't reached it's last subpod, 359 | // remember to put in a line break because the images would just be on one line 360 | 361 | if (j !== window.json[i].subpods.length - 1) { 362 | output += "
"; 363 | } 364 | } 365 | } 366 | 367 | // set the output to inline block because whenever the error shows up it switches to block 368 | // hacky solutions!!! yay! 369 | $(".output").css("display", "inline-block"); 370 | $("#output").html(output) 371 | 372 | // when all images are loaded, remember to resize the window and turn off the loader 373 | $("#output").imagesLoaded(function() { 374 | console.log("Images are ready, resizing window."); 375 | loader(false); 376 | backdoor.resizeWindow(); 377 | }); 378 | } catch (e) { 379 | console.log(e.toString()) 380 | 381 | // try again if error 382 | retry(input) 383 | } 384 | 385 | if (err) { 386 | console.log(err.toString()) 387 | 388 | // try again 389 | retry(input); 390 | } 391 | }); 392 | 393 | console.log('Queried with: ' + queryURL); 394 | } 395 | } 396 | 397 | var retry = function(input) { 398 | var input = $('#input').val(); 399 | var encodedInput = encodeURIComponent(input); 400 | var result; 401 | 402 | console.log("Error was thrown. Attempting to query again..."); 403 | 404 | var errorMsg = format("

Sorry! I can't find the answer.
Try searching it on WolframAlpha.

", window.links.wolfram); 405 | 406 | wolfram.query(input, function(err, queryResult) { 407 | try { 408 | window.json = queryResult; 409 | 410 | var inputInterpretation = backdoor.unicodeRegex(window.json.shift().subpods[0].text)[0]; 411 | 412 | $(".interpret, #wolfram-credit").css("display", "block"); 413 | $("#wolframlink").attr("onclick", "Shell.openExternal(\"" + window.links.wolfram + "\");"); 414 | $("#queryInterpretation").html(inputInterpretation); 415 | 416 | var output = ""; 417 | 418 | // look through each pod 419 | for (i = 0; i !== window.json.length; i++) { 420 | // title each pod 421 | if (window.json.length !== 1) { 422 | output += "

" + window.json[i].title + "

" 423 | } 424 | 425 | // look through the subpods of each pod 426 | for (j = 0; j !== window.json[i].subpods.length; j++) { 427 | // add each subpod 428 | // sidenote: the onmouseover thing is a hacky solution 429 | // that tells the copy plaintext function what 430 | // subpod's text to copy based on what you're hovering over 431 | 432 | output += "\"""; 433 | 434 | // if the for loop hasn't reached it's last subpod, 435 | // remember to put in a line break because the images would just be on one line 436 | 437 | if (j !== window.json[i].subpods.length - 1) { 438 | output += "
"; 439 | } 440 | } 441 | } 442 | 443 | // set the output to inline block because whenever the error shows up it switches to block 444 | // hacky solutions!!! yay! 445 | $(".output").css("display", "inline-block"); 446 | $("#output").html(output) 447 | 448 | // when all images are loaded, remember to resize the window and turn off the loader 449 | $("#output").imagesLoaded(function() { 450 | console.log("Images are ready, resizing window."); 451 | loader(false); 452 | backdoor.resizeWindow(); 453 | }); 454 | } catch (e) { 455 | $(".interpret, #wolfram-credit").css("display", "none"); 456 | $("#output").html(errorMsg) 457 | $(".output").css("display", "block"); 458 | 459 | loader(false); 460 | backdoor.resizeWindow(true); 461 | throw e; 462 | } 463 | 464 | if (err) { 465 | $("#output").html(errorMsg) 466 | // couldn't get the error msg to work on inline block so I just decided to change it back and forth depending on the output 467 | $(".output").css("display", "block"); 468 | 469 | backdoor.resizeWindow(true); 470 | loader(false); 471 | throw err; 472 | } 473 | }); 474 | } 475 | -------------------------------------------------------------------------------- /src/js/suggestions.json: -------------------------------------------------------------------------------- 1 | [ 2 | "256 / 8", 3 | "How big is the Atlantic Ocean?", 4 | "Distance from Earth to Mars", 5 | "Distance of Voyager 1", 6 | "Words that rhyme with bright", 7 | "Where was Donald Trump born?", 8 | "color #FFCA30 in HSL", 9 | "Protons in lithium", 10 | "Ca + H2O", 11 | "UK men's shoe size 12 in US size", 12 | "What is the time in Vancouver, Canada?", 13 | "What is the population of Berlin?", 14 | "Define nimble", 15 | "What is the net worth of Donald Trump?", 16 | "Calories in one teaspoon of Nutella", 17 | "Amount of sugar in 250ml of Coca Cola", 18 | "25 American dollars in Euros", 19 | "What happened in 1989?", 20 | "Tesla Motors stock price", 21 | "Is God real?", 22 | "Solve 3x2 + x - 7 = 4x", 23 | "Plot 3x2 + x - 7 = 4x", 24 | "What movies has Donald Trump been in?", 25 | "Home Alone 2 poster", 26 | "Image of Donald Trump", 27 | "Is it raining in Portland, Oregon?", 28 | "Where is the sun in Walsall, England?", 29 | "What happened in 2009?", 30 | "How long ago did Wolfram|Alpha launch?", 31 | "Who founded Apple?", 32 | "What is the Ruby programming language?", 33 | "What is Node.js?", 34 | "What is Mathematica?", 35 | "Who killed Abraham Lincoln?", 36 | "Did Han Solo shoot first?", 37 | "How tall is Trump Tower in feet?", 38 | "What's Apple's stock price in GBP?", 39 | "Bill Gates' net worth in Euros?", 40 | "Notable facts about Linus Torvalds?", 41 | "Why is a firetruck red?", 42 | "What is the meaning of life?", 43 | "Apply dog vision Donald Trump image", 44 | "Who won the last Trail Blazers game?", 45 | "Phones weighing less than 1 kg", 46 | "Morse code -. .. -- -... .-.. .", 47 | "Nimble in Morse Code", 48 | "Poker probabilities", 49 | "12 sided die example", 50 | "Are you Skynet?", 51 | "Random graph on 12 vertices", 52 | "Sierpinski tetrahedron, 6 iterations", 53 | "Show me the Mandlebrot set", 54 | "Sierpinski gasket, 6 iterations", 55 | "What's the fastest car in the world?", 56 | "21st digit of pi?", 57 | "22 digits of pi?", 58 | "random Turing machine?", 59 | "Evolve Wolfram 2,3 for 25 steps", 60 | "What's the speed of an unladen swallow?", 61 | "Plot the Wolfram logo", 62 | "\\frac{3x^3 - 4x^2 + 3x -1}{2x^2 + 4}" 63 | ] 64 | --------------------------------------------------------------------------------