diff --git a/README.md b/README.md index 451b38d..4cbd781 100644 --- a/README.md +++ b/README.md @@ -11,15 +11,17 @@ **Latest:** -- `Mac`: [ChatGPT_0.1.5_x64.dmg](https://github.com/lencx/ChatGPT/releases/download/v0.1.5/ChatGPT_0.1.5_x64.dmg) -- `Linux`: [chat-gpt_0.1.5_amd64.deb](https://github.com/lencx/ChatGPT/releases/download/v0.1.5/chat-gpt_0.1.5_amd64.deb) -- `Windows`: [ChatGPT_0.1.5_x64_en-US.msi](https://github.com/lencx/ChatGPT/releases/download/v0.1.5/ChatGPT_0.1.5_x64_en-US.msi) +- `Mac`: [ChatGPT_0.1.6_x64.dmg](https://github.com/lencx/ChatGPT/releases/download/v0.1.5/ChatGPT_0.1.6_x64.dmg) +- `Linux`: [chat-gpt_0.1.6_amd64.deb](https://github.com/lencx/ChatGPT/releases/download/v0.1.5/chat-gpt_0.1.6_amd64.deb) +- `Windows`: [ChatGPT_0.1.6_x64_en-US.msi](https://github.com/lencx/ChatGPT/releases/download/v0.1.5/ChatGPT_0.1.6_x64_en-US.msi) [Other version...](https://github.com/lencx/ChatGPT/releases) ## Features - multi-platform: `macOS` `Linux` `Windows` +- export ChatGPT history (PNG, PDF and Share Link) +- always on top (whether the window should always be on top of other windows) - inject script - auto updater - app menu @@ -32,10 +34,9 @@ chat auto update -## TODO +## Related -- [ ] export chat history -- [ ] ... +- [ChatGPT Export and Share](https://github.com/liady/ChatGPT-pdf) - A Chrome extension for downloading your ChatGPT history to PNG, PDF or creating a sharable link ## FAQ diff --git a/assets/chat.png b/assets/chat.png index 917817b..efdd6ab 100644 Binary files a/assets/chat.png and b/assets/chat.png differ diff --git a/src-tauri/src/app/cmd.rs b/src-tauri/src/app/cmd.rs index a653177..1003ce1 100644 --- a/src-tauri/src/app/cmd.rs +++ b/src-tauri/src/app/cmd.rs @@ -1,12 +1,14 @@ -use tauri::Manager; +use crate::utils; +use std::fs; +use tauri::{api, command, AppHandle, Manager}; -#[tauri::command] -pub fn drag_window(app: tauri::AppHandle) { +#[command] +pub fn drag_window(app: AppHandle) { app.get_window("core").unwrap().start_dragging().unwrap(); } -#[tauri::command] -pub fn fullscreen(app: tauri::AppHandle) { +#[command] +pub fn fullscreen(app: AppHandle) { let win = app.get_window("core").unwrap(); if win.is_fullscreen().unwrap() { win.set_fullscreen(false).unwrap(); @@ -14,3 +16,15 @@ pub fn fullscreen(app: tauri::AppHandle) { win.set_fullscreen(true).unwrap(); } } + +#[command] +pub fn download(_app: AppHandle, name: String, blob: Vec) { + let path = api::path::download_dir().unwrap().join(name); + fs::write(&path, blob).unwrap(); + utils::open_file(path); +} + +#[command] +pub fn open_link(app: AppHandle, url: String) { + api::shell::open(&app.shell_scope(), url, None).unwrap(); +} diff --git a/src-tauri/src/app/menu.rs b/src-tauri/src/app/menu.rs index 2aed48f..605b202 100644 --- a/src-tauri/src/app/menu.rs +++ b/src-tauri/src/app/menu.rs @@ -1,22 +1,17 @@ -use crate::utils; +use crate::{conf, utils}; use tauri::{ utils::assets::EmbeddedAssets, AboutMetadata, AppHandle, Context, CustomMenuItem, Manager, - Menu, MenuItem, Submenu, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem, - WindowMenuEvent, + Menu, MenuItem, Submenu, SystemTray, SystemTrayEvent, SystemTrayMenu, WindowMenuEvent, }; // --- Menu -pub fn init(context: &Context) -> Menu { +pub fn init(chat_conf: &conf::ChatConfJson, context: &Context) -> Menu { let name = &context.package_info().name; let app_menu = Submenu::new( name, Menu::new() .add_native_item(MenuItem::About(name.into(), AboutMetadata::default())) .add_native_item(MenuItem::Separator) - .add_item( - CustomMenuItem::new("inject_script".to_string(), "Inject Script") - .accelerator("CmdOrCtrl+J"), - ) .add_native_item(MenuItem::Separator) .add_native_item(MenuItem::Hide) .add_native_item(MenuItem::HideOthers) @@ -25,6 +20,28 @@ pub fn init(context: &Context) -> Menu { .add_native_item(MenuItem::Quit), ); + let always_on_top = CustomMenuItem::new("always_on_top".to_string(), "Always On Top") + .accelerator("CmdOrCtrl+T"); + + let preferences_menu = Submenu::new( + "Preferences", + Menu::new() + .add_item( + CustomMenuItem::new("inject_script".to_string(), "Inject Script") + .accelerator("CmdOrCtrl+J"), + ) + .add_item(if chat_conf.always_on_top { + always_on_top.selected() + } else { + always_on_top + }) + .add_native_item(MenuItem::Separator) + .add_item( + CustomMenuItem::new("awesome".to_string(), "Awesome ChatGPT") + .accelerator("CmdOrCtrl+Z"), + ), + ); + let edit_menu = Submenu::new( "Edit", Menu::new() @@ -74,6 +91,7 @@ pub fn init(context: &Context) -> Menu { Menu::new() .add_submenu(app_menu) + .add_submenu(preferences_menu) .add_submenu(edit_menu) .add_submenu(view_menu) .add_submenu(help_menu) @@ -83,12 +101,27 @@ pub fn init(context: &Context) -> Menu { pub fn menu_handler(event: WindowMenuEvent) { let win = Some(event.window()).unwrap(); let app = win.app_handle(); + let state: tauri::State = app.state(); let script_path = utils::script_path().to_string_lossy().to_string(); - let issues_url = "https://github.com/lencx/ChatGPT/issues".to_string(); + let menu_id = event.menu_item_id(); - match event.menu_item_id() { - // App - "inject_script" => inject_script(&app, script_path), + let core_window = app.get_window("core").unwrap(); + let menu_handle = core_window.menu_handle(); + + match menu_id { + // Preferences + "inject_script" => open(&app, script_path), + "awesome" => open(&app, conf::AWESOME_URL.to_string()), + "always_on_top" => { + let mut always_on_top = state.always_on_top.lock().unwrap(); + *always_on_top = !*always_on_top; + menu_handle + .get_item(menu_id) + .set_selected(*always_on_top) + .unwrap(); + win.set_always_on_top(*always_on_top).unwrap(); + conf::ChatConfJson::update_chat_conf(*always_on_top); + } // View "reload" => win.eval("window.location.reload()").unwrap(), "go_back" => win.eval("window.history.go(-1)").unwrap(), @@ -111,7 +144,7 @@ pub fn menu_handler(event: WindowMenuEvent) { ) .unwrap(), // Help - "report_bug" => inject_script(&app, issues_url), + "report_bug" => open(&app, conf::ISSUES_URL.to_string()), "dev_tools" => { win.open_devtools(); win.close_devtools(); @@ -122,35 +155,24 @@ pub fn menu_handler(event: WindowMenuEvent) { // --- SystemTray Menu pub fn tray_menu() -> SystemTray { - SystemTray::new().with_menu( - SystemTrayMenu::new() - .add_item(CustomMenuItem::new("show".to_string(), "Show ChatGPT")) - .add_item(CustomMenuItem::new("hide".to_string(), "Hide ChatGPT")) - .add_item(CustomMenuItem::new( - "inject_script".to_string(), - "Inject Script", - )) - .add_native_item(SystemTrayMenuItem::Separator) - .add_item(CustomMenuItem::new("quit".to_string(), "Quit ChatGPT")), - ) + SystemTray::new().with_menu(SystemTrayMenu::new()) } // --- SystemTray Event pub fn tray_handler(app: &AppHandle, event: SystemTrayEvent) { - let script_path = utils::script_path().to_string_lossy().to_string(); let win = app.get_window("core").unwrap(); - if let SystemTrayEvent::MenuItemClick { id, .. } = event { - match id.as_str() { - "quit" => std::process::exit(0), - "show" => win.show().unwrap(), - "hide" => win.hide().unwrap(), - "inject_script" => inject_script(app, script_path), - _ => (), + if let SystemTrayEvent::LeftClick { .. } = event { + // TODO: tray window + if win.is_visible().unwrap() { + win.hide().unwrap(); + } else { + win.show().unwrap(); + win.set_focus().unwrap(); } } } -pub fn inject_script(app: &AppHandle, path: String) { +pub fn open(app: &AppHandle, path: String) { tauri::api::shell::open(&app.shell_scope(), path, None).unwrap(); } diff --git a/src-tauri/src/app/setup.rs b/src-tauri/src/app/setup.rs index baf0aea..65c9668 100644 --- a/src-tauri/src/app/setup.rs +++ b/src-tauri/src/app/setup.rs @@ -1,10 +1,13 @@ -use crate::utils; +use crate::{conf, utils}; use tauri::{utils::config::WindowUrl, window::WindowBuilder, App}; #[cfg(target_os = "macos")] use tauri::TitleBarStyle; -pub fn init(app: &mut App) -> std::result::Result<(), Box> { +pub fn init( + app: &mut App, + chat_conf: conf::ChatConfJson, +) -> std::result::Result<(), Box> { let conf = utils::get_tauri_conf().unwrap(); let url = conf.build.dev_path.to_string(); @@ -15,12 +18,13 @@ pub fn init(app: &mut App) -> std::result::Result<(), Box .inner_size(800.0, 600.0) .hidden_title(true) .title_bar_style(TitleBarStyle::Overlay) + .always_on_top(chat_conf.always_on_top) .initialization_script(&utils::user_script()) .initialization_script(include_str!("../assets/html2canvas.js")) .initialization_script(include_str!("../assets/jspdf.js")) .initialization_script(include_str!("../assets/core.js")) .initialization_script(include_str!("../assets/import.js")) - .user_agent("5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36") + .user_agent(conf::USER_AGENT) .build()?; #[cfg(not(target_os = "macos"))] @@ -29,12 +33,13 @@ pub fn init(app: &mut App) -> std::result::Result<(), Box .resizable(true) .fullscreen(false) .inner_size(800.0, 600.0) + .always_on_top(chat_conf.always_on_top) .initialization_script(&utils::user_script()) .initialization_script(include_str!("../assets/html2canvas.js")) .initialization_script(include_str!("../assets/jspdf.js")) .initialization_script(include_str!("../assets/core.js")) .initialization_script(include_str!("../assets/import.js")) - .user_agent("5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36") + .user_agent(conf::USER_AGENT) .build()?; Ok(()) diff --git a/src-tauri/src/assets/core.js b/src-tauri/src/assets/core.js index bfcd22d..bb95bae 100644 --- a/src-tauri/src/assets/core.js +++ b/src-tauri/src/assets/core.js @@ -1,41 +1,45 @@ // *** Core Script - IPC *** -document.addEventListener('DOMContentLoaded', async () => { - const uid = () => window.crypto.getRandomValues(new Uint32Array(1))[0]; - function transformCallback(callback = () => {}, once = false) { - const identifier = uid(); - const prop = `_${identifier}`; - Object.defineProperty(window, prop, { - value: (result) => { - if (once) { - Reflect.deleteProperty(window, prop); - } - return callback(result) - }, - writable: false, - configurable: true, - }) - return identifier; - } - async function invoke(cmd, args) { - return new Promise((resolve, reject) => { - if (!window.__TAURI_POST_MESSAGE__) reject('__TAURI_POST_MESSAGE__ does not exist!'); - const callback = transformCallback((e) => { - resolve(e); - Reflect.deleteProperty(window, `_${error}`); - }, true) - const error = transformCallback((e) => { - reject(e); - Reflect.deleteProperty(window, `_${callback}`); - }, true) - window.__TAURI_POST_MESSAGE__({ - cmd, - callback, - error, - ...args - }); +const uid = () => window.crypto.getRandomValues(new Uint32Array(1))[0]; +function transformCallback(callback = () => {}, once = false) { + const identifier = uid(); + const prop = `_${identifier}`; + Object.defineProperty(window, prop, { + value: (result) => { + if (once) { + Reflect.deleteProperty(window, prop); + } + return callback(result) + }, + writable: false, + configurable: true, + }) + return identifier; +} +async function invoke(cmd, args) { + return new Promise((resolve, reject) => { + if (!window.__TAURI_POST_MESSAGE__) reject('__TAURI_POST_MESSAGE__ does not exist!'); + const callback = transformCallback((e) => { + resolve(e); + Reflect.deleteProperty(window, `_${error}`); + }, true) + const error = transformCallback((e) => { + reject(e); + Reflect.deleteProperty(window, `_${callback}`); + }, true) + window.__TAURI_POST_MESSAGE__({ + cmd, + callback, + error, + ...args }); - } + }); +} +window.uid = uid; +window.invoke = invoke; +window.transformCallback = transformCallback; + +async function init() { async function platform() { return invoke('platform', { __tauriModule: 'Os', @@ -74,4 +78,13 @@ document.addEventListener('DOMContentLoaded', async () => { } } }); -}) +} + +if ( + document.readyState === "complete" || + document.readyState === "interactive" +) { + init(); +} else { + document.addEventListener("DOMContentLoaded", init); +} \ No newline at end of file diff --git a/src-tauri/src/assets/import.js b/src-tauri/src/assets/import.js index fdf25b7..9c30beb 100644 --- a/src-tauri/src/assets/import.js +++ b/src-tauri/src/assets/import.js @@ -109,15 +109,7 @@ function handleImg(imgData) { for (let i = 0; i < binaryData.length; i++) { data.push(binaryData.charCodeAt(i)); } - const blob = new Blob([new Uint8Array(data)], { type: "image/png" }); - const url = URL.createObjectURL(blob); - - // window.open(url, "_blank"); - - // const a = document.createElement("a"); - // a.href = url; - // a.download = "chat-gpt-image.png"; - // a.click(); + invoke('download', { name: `chatgpt-${Date.now()}.png`, blob: Array.from(new Uint8Array(data)) }); } function handlePdf(imgData, canvas, pixelRatio) { @@ -130,7 +122,9 @@ function handlePdf(imgData, canvas, pixelRatio) { var pdfWidth = pdf.internal.pageSize.getWidth(); var pdfHeight = pdf.internal.pageSize.getHeight(); pdf.addImage(imgData, "PNG", 0, 0, pdfWidth, pdfHeight); - pdf.save("chat-gpt.pdf"); + + const data = pdf.__private__.getArrayBuffer(pdf.__private__.buildDocument()); + invoke('download', { name: `chatgpt-${Date.now()}.pdf`, blob: Array.from(new Uint8Array(data)) }); } class Elements { @@ -206,7 +200,7 @@ async function sendRequest() { }) .then((response) => response.json()) .then((data) => { - window.open(data.url, "_blank"); + invoke('open_link', { url: data.url }); }); } diff --git a/src-tauri/src/assets/jspdf.js b/src-tauri/src/assets/jspdf.js index 03b518b..5b20557 100644 --- a/src-tauri/src/assets/jspdf.js +++ b/src-tauri/src/assets/jspdf.js @@ -394,5 +394,4 @@ * Unicode Bidi Engine based on the work of Alex Shensis (@asthensis) * MIT License */ - function(t){t.__bidiEngine__=t.prototype.__bidiEngine__=function(t){var r,n,i,a,o,s,c,u=e,l=[[0,3,0,1,0,0,0],[0,3,0,1,2,2,0],[0,3,0,17,2,0,1],[0,3,5,5,4,1,0],[0,3,21,21,4,0,1],[0,3,5,5,4,2,0]],h=[[2,0,1,1,0,1,0],[2,0,1,1,0,2,0],[2,0,2,1,3,2,0],[2,0,2,33,3,1,1]],f={L:0,R:1,EN:2,AN:3,N:4,B:5,S:6},d={0:0,5:1,6:2,7:3,32:4,251:5,254:6,255:7},p=["(",")","(","<",">","<","[","]","[","{","}","{","«","»","«","‹","›","‹","⁅","⁆","⁅","⁽","⁾","⁽","₍","₎","₍","≤","≥","≤","〈","〉","〈","﹙","﹚","﹙","﹛","﹜","﹛","﹝","﹞","﹝","﹤","﹥","﹤"],g=new RegExp(/^([1-4|9]|1[0-9]|2[0-9]|3[0168]|4[04589]|5[012]|7[78]|159|16[0-9]|17[0-2]|21[569]|22[03489]|250)$/),m=!1,v=0;this.__bidiEngine__={};var b=function(t){var e=t.charCodeAt(),r=e>>8,n=d[r];return void 0!==n?u[256*n+(255&e)]:252===r||253===r?"AL":g.test(r)?"L":8===r?"R":"N"},y=function(t){for(var e,r=0;r=e.length||"EN"!==(c=o[s-1])&&"AN"!==c||"EN"!==(u=e[s+1])&&"AN"!==u?f="N":m&&(u="AN"),f=u===c?u:"N";break;case"ES":f="EN"===(c=s>0?o[s-1]:"B")&&s+10&&"EN"===o[s-1]){f="EN";break}if(m){f="N";break}for(l=s+1,h=e.length;l=1425&&d<=2303||64286===d;if(c=e[l],p&&("R"===c||"AL"===c)){f="R";break}}}f=s<1||"B"===(c=e[s-1])?"N":o[s-1];break;case"B":m=!1,r=!0,f=v;break;case"S":n=!0,f="N";break;case"LRE":case"RLE":case"LRO":case"RLO":case"PDF":m=!1;break;case"BN":f="N"}return f},N=function(t,e,r){var n=t.split("");return r&&L(n,r,{hiLevel:v}),n.reverse(),e&&e.reverse(),n.join("")},L=function(t,e,i){var a,o,s,c,u,d=-1,p=t.length,g=0,y=[],N=v?h:l,L=[];for(m=!1,r=!1,n=!1,o=0;o0)if(16===a){for(o=d;o-1){for(o=d;o=0&&"WS"===t[i];i--)e[i]=v}}(L,e,p)},A=function(t,e,n,i,a){if(!(a.hiLevel=t){for(c=h+1;c=t;)c++;for(u=h,s=c-1;u=0&&(t[i]=p[n+1])}(n,r,i),A(2,n,e,r,i),A(1,n,e,r,i),n.join("")};return this.__bidiEngine__.doBidiReorder=function(t,e,r){if(function(t,e){if(e)for(var r=0;r>16))&&(e=-(1+(65535^e))),this.italicAngle=+(e+"."+r)):this.italicAngle=0,this.ascender=Math.round(this.ascender*this.scaleFactor),this.decender=Math.round(this.decender*this.scaleFactor),this.lineGap=Math.round(this.lineGap*this.scaleFactor),this.capHeight=this.os2.exists&&this.os2.capHeight||this.ascender,this.xHeight=this.os2.exists&&this.os2.xHeight||0,this.familyClass=(this.os2.exists&&this.os2.familyClass||0)>>8,this.isSerif=1===(i=this.familyClass)||2===i||3===i||4===i||5===i||7===i,this.isScript=10===this.familyClass,this.flags=0,this.post.isFixedPitch&&(this.flags|=1),this.isSerif&&(this.flags|=2),this.isScript&&(this.flags|=8),0!==this.italicAngle&&(this.flags|=64),this.flags|=32,!this.cmap.unicode)throw new Error("No unicode cmap for font")},t.prototype.characterToGlyph=function(t){var e;return(null!=(e=this.cmap.unicode)?e.codeMap[t]:void 0)||0},t.prototype.widthOfGlyph=function(t){var e;return e=1e3/this.head.unitsPerEm,this.hmtx.forGlyph(t).advance*e},t.prototype.widthOfString=function(t,e,r){var n,i,a,o;for(a=0,i=0,o=(t=""+t).length;0<=o?io;i=0<=o?++i:--i)n=t.charCodeAt(i),a+=this.widthOfGlyph(this.characterToGlyph(n))+r*(1e3/e)||0;return a*(e/1e3)},t.prototype.lineHeight=function(t,e){var r;return null==e&&(e=!1),r=e?this.lineGap:0,(this.ascender+r-this.decender)/1e3*t},t}();var Re,Te=function(){function t(t){this.data=null!=t?t:[],this.pos=0,this.length=this.data.length}return t.prototype.readByte=function(){return this.data[this.pos++]},t.prototype.writeByte=function(t){return this.data[this.pos++]=t},t.prototype.readUInt32=function(){return 16777216*this.readByte()+(this.readByte()<<16)+(this.readByte()<<8)+this.readByte()},t.prototype.writeUInt32=function(t){return this.writeByte(t>>>24&255),this.writeByte(t>>16&255),this.writeByte(t>>8&255),this.writeByte(255&t)},t.prototype.readInt32=function(){var t;return(t=this.readUInt32())>=2147483648?t-4294967296:t},t.prototype.writeInt32=function(t){return t<0&&(t+=4294967296),this.writeUInt32(t)},t.prototype.readUInt16=function(){return this.readByte()<<8|this.readByte()},t.prototype.writeUInt16=function(t){return this.writeByte(t>>8&255),this.writeByte(255&t)},t.prototype.readInt16=function(){var t;return(t=this.readUInt16())>=32768?t-65536:t},t.prototype.writeInt16=function(t){return t<0&&(t+=65536),this.writeUInt16(t)},t.prototype.readString=function(t){var e,r;for(r=[],e=0;0<=t?et;e=0<=t?++e:--e)r[e]=String.fromCharCode(this.readByte());return r.join("")},t.prototype.writeString=function(t){var e,r,n;for(n=[],e=0,r=t.length;0<=r?er;e=0<=r?++e:--e)n.push(this.writeByte(t.charCodeAt(e)));return n},t.prototype.readShort=function(){return this.readInt16()},t.prototype.writeShort=function(t){return this.writeInt16(t)},t.prototype.readLongLong=function(){var t,e,r,n,i,a,o,s;return t=this.readByte(),e=this.readByte(),r=this.readByte(),n=this.readByte(),i=this.readByte(),a=this.readByte(),o=this.readByte(),s=this.readByte(),128&t?-1*(72057594037927940*(255^t)+281474976710656*(255^e)+1099511627776*(255^r)+4294967296*(255^n)+16777216*(255^i)+65536*(255^a)+256*(255^o)+(255^s)+1):72057594037927940*t+281474976710656*e+1099511627776*r+4294967296*n+16777216*i+65536*a+256*o+s},t.prototype.writeLongLong=function(t){var e,r;return e=Math.floor(t/4294967296),r=4294967295&t,this.writeByte(e>>24&255),this.writeByte(e>>16&255),this.writeByte(e>>8&255),this.writeByte(255&e),this.writeByte(r>>24&255),this.writeByte(r>>16&255),this.writeByte(r>>8&255),this.writeByte(255&r)},t.prototype.readInt=function(){return this.readInt32()},t.prototype.writeInt=function(t){return this.writeInt32(t)},t.prototype.read=function(t){var e,r;for(e=[],r=0;0<=t?rt;r=0<=t?++r:--r)e.push(this.readByte());return e},t.prototype.write=function(t){var e,r,n,i;for(i=[],r=0,n=t.length;rn;r=0<=n?++r:--r)e={tag:t.readString(4),checksum:t.readInt(),offset:t.readInt(),length:t.readInt()},this.tables[e.tag]=e}return e.prototype.encode=function(e){var r,n,i,a,o,s,c,u,l,h,f,d,p;for(p in f=Object.keys(e).length,s=Math.log(2),l=16*Math.floor(Math.log(f)/s),a=Math.floor(l/s),u=16*f-l,(n=new Te).writeInt(this.scalarType),n.writeShort(f),n.writeShort(l),n.writeShort(a),n.writeShort(u),i=16*f,c=n.pos+i,o=null,d=[],e)for(h=e[p],n.writeString(p),n.writeInt(t(h)),n.writeInt(c),n.writeInt(h.length),d=d.concat(h),"head"===p&&(o=c),c+=h.length;c%4;)d.push(0),c++;return n.write(d),r=2981146554-t(n.data),n.pos=o+8,n.writeUInt32(r),n.data},t=function(t){var e,r,n,i;for(t=tr.call(t);t.length%4;)t.push(0);for(n=new Te(t),r=0,e=0,i=t.length;eh;s=0<=h?++e:--e)r.push(t.readUInt16());return r}(),t.pos+=2,p=function(){var e,r;for(r=[],s=e=0;0<=h?eh;s=0<=h?++e:--e)r.push(t.readUInt16());return r}(),c=function(){var e,r;for(r=[],s=e=0;0<=h?eh;s=0<=h?++e:--e)r.push(t.readUInt16());return r}(),u=function(){var e,r;for(r=[],s=e=0;0<=h?eh;s=0<=h?++e:--e)r.push(t.readUInt16());return r}(),n=(this.length-t.pos+this.offset)/2,o=function(){var e,r;for(r=[],s=e=0;0<=n?en;s=0<=n?++e:--e)r.push(t.readUInt16());return r}(),s=m=0,b=i.length;m=g;r=d<=g?++v:--v)0===u[s]?a=r+c[s]:0!==(a=o[u[s]/2+(r-d)-(h-s)]||0)&&(a+=c[s]),this.codeMap[r]=65535&a}t.pos=l}return t.encode=function(t,e){var r,n,i,a,o,s,c,u,l,h,f,d,p,g,m,v,b,y,w,N,L,A,x,S,_,P,k,F,I,C,j,O,B,M,E,q,D,R,T,U,z,H,W,V,G,Y;switch(F=new Te,a=Object.keys(t).sort((function(t,e){return t-e})),e){case"macroman":for(p=0,g=function(){var t=[];for(d=0;d<256;++d)t.push(0);return t}(),v={0:0},i={},I=0,B=a.length;I=32768)for(s.push(0),N.push(2*(f.length+x-d)),n=O=_;_<=u?O<=u:O>=u;n=_<=u?++O:--O)f.push(r[n].new);else s.push(k-_),N.push(0)}for(F.writeUInt16(3),F.writeUInt16(1),F.writeUInt32(12),F.writeUInt16(4),F.writeUInt16(16+8*x+2*f.length),F.writeUInt16(0),F.writeUInt16(S),F.writeUInt16(A),F.writeUInt16(h),F.writeUInt16(L),z=0,q=l.length;zn;r=0<=n?++r:--r)e=new Ve(t,this.offset),this.tables.push(e),e.isUnicode&&null==this.unicode&&(this.unicode=e);return!0},e.encode=function(t,e){var r,n;return null==e&&(e="macroman"),r=Ve.encode(t,e),(n=new Te).writeUInt16(0),n.writeUInt16(1),r.table=n.data.concat(r.subtable),r},e}(Re),Ye=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return He(e,t),e.prototype.tag="hhea",e.prototype.parse=function(t){return t.pos=this.offset,this.version=t.readInt(),this.ascender=t.readShort(),this.decender=t.readShort(),this.lineGap=t.readShort(),this.advanceWidthMax=t.readShort(),this.minLeftSideBearing=t.readShort(),this.minRightSideBearing=t.readShort(),this.xMaxExtent=t.readShort(),this.caretSlopeRise=t.readShort(),this.caretSlopeRun=t.readShort(),this.caretOffset=t.readShort(),t.pos+=8,this.metricDataFormat=t.readShort(),this.numberOfMetrics=t.readUInt16()},e}(Re),Je=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return He(e,t),e.prototype.tag="OS/2",e.prototype.parse=function(t){if(t.pos=this.offset,this.version=t.readUInt16(),this.averageCharWidth=t.readShort(),this.weightClass=t.readUInt16(),this.widthClass=t.readUInt16(),this.type=t.readShort(),this.ySubscriptXSize=t.readShort(),this.ySubscriptYSize=t.readShort(),this.ySubscriptXOffset=t.readShort(),this.ySubscriptYOffset=t.readShort(),this.ySuperscriptXSize=t.readShort(),this.ySuperscriptYSize=t.readShort(),this.ySuperscriptXOffset=t.readShort(),this.ySuperscriptYOffset=t.readShort(),this.yStrikeoutSize=t.readShort(),this.yStrikeoutPosition=t.readShort(),this.familyClass=t.readShort(),this.panose=function(){var e,r;for(r=[],e=0;e<10;++e)r.push(t.readByte());return r}(),this.charRange=function(){var e,r;for(r=[],e=0;e<4;++e)r.push(t.readInt());return r}(),this.vendorID=t.readString(4),this.selection=t.readShort(),this.firstCharIndex=t.readShort(),this.lastCharIndex=t.readShort(),this.version>0&&(this.ascent=t.readShort(),this.descent=t.readShort(),this.lineGap=t.readShort(),this.winAscent=t.readShort(),this.winDescent=t.readShort(),this.codePageRange=function(){var e,r;for(r=[],e=0;e<2;e=++e)r.push(t.readInt());return r}(),this.version>1))return this.xHeight=t.readShort(),this.capHeight=t.readShort(),this.defaultChar=t.readShort(),this.breakChar=t.readShort(),this.maxContext=t.readShort()},e}(Re),Xe=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return He(e,t),e.prototype.tag="post",e.prototype.parse=function(t){var e,r,n;switch(t.pos=this.offset,this.format=t.readInt(),this.italicAngle=t.readInt(),this.underlinePosition=t.readShort(),this.underlineThickness=t.readShort(),this.isFixedPitch=t.readInt(),this.minMemType42=t.readInt(),this.maxMemType42=t.readInt(),this.minMemType1=t.readInt(),this.maxMemType1=t.readInt(),this.format){case 65536:break;case 131072:var i;for(r=t.readUInt16(),this.glyphNameIndex=[],i=0;0<=r?ir;i=0<=r?++i:--i)this.glyphNameIndex.push(t.readUInt16());for(this.names=[],n=[];t.posr;i=0<=r?++e:--e)n.push(t.readUInt32());return n}.call(this)}},e}(Re),Ke=function(t,e){this.raw=t,this.length=t.length,this.platformID=e.platformID,this.encodingID=e.encodingID,this.languageID=e.languageID},Ze=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return He(e,t),e.prototype.tag="name",e.prototype.parse=function(t){var e,r,n,i,a,o,s,c,u,l,h;for(t.pos=this.offset,t.readShort(),e=t.readShort(),o=t.readShort(),r=[],i=0;0<=e?ie;i=0<=e?++i:--i)r.push({platformID:t.readShort(),encodingID:t.readShort(),languageID:t.readShort(),nameID:t.readShort(),length:t.readShort(),offset:this.offset+o+t.readShort()});for(s={},i=u=0,l=r.length;uo;e=0<=o?++e:--e)this.metrics.push({advance:t.readUInt16(),lsb:t.readInt16()});for(n=this.file.maxp.numGlyphs-this.file.hhea.numberOfMetrics,this.leftSideBearings=function(){var r,i;for(i=[],e=r=0;0<=n?rn;e=0<=n?++r:--r)i.push(t.readInt16());return i}(),this.widths=function(){var t,e,r,n;for(n=[],t=0,e=(r=this.metrics).length;tn;e=0<=n?++a:--a)s.push(this.widths.push(r));return s},e.prototype.forGlyph=function(t){return t in this.metrics?this.metrics[t]:{advance:this.metrics[this.metrics.length-1].advance,lsb:this.leftSideBearings[t-this.metrics.length]}},e}(Re),tr=[].slice,er=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return He(e,t),e.prototype.tag="glyf",e.prototype.parse=function(){return this.cache={}},e.prototype.glyphFor=function(t){var e,r,n,i,a,o,s,c,u,l;return t in this.cache?this.cache[t]:(i=this.file.loca,e=this.file.contents,r=i.indexOf(t),0===(n=i.lengthOf(t))?this.cache[t]=null:(e.pos=this.offset+r,a=(o=new Te(e.read(n))).readShort(),c=o.readShort(),l=o.readShort(),s=o.readShort(),u=o.readShort(),this.cache[t]=-1===a?new nr(o,c,l,s,u):new rr(o,a,c,l,s,u),this.cache[t]))},e.prototype.encode=function(t,e,r){var n,i,a,o,s;for(a=[],i=[],o=0,s=e.length;o0&&(n+=s)}for(var c=new Array(4*r.length),u=0;u>8,c[4*u+1]=(16711680&r[u])>>16,c[4*u]=(4278190080&r[u])>>24;return c},e}(Re),ar=function(){function t(t){this.font=t,this.subset={},this.unicodes={},this.next=33}return t.prototype.generateCmap=function(){var t,e,r,n,i;for(e in n=this.font.cmap.tables[0].codeMap,t={},i=this.subset)r=i[e],t[e]=n[r];return t},t.prototype.glyphsFor=function(t){var e,r,n,i,a,o,s;for(n={},a=0,o=t.length;a0)for(i in s=this.glyphsFor(e))r=s[i],n[i]=r;return n},t.prototype.encode=function(t,e){var r,n,i,a,o,s,c,u,l,h,f,d,p,g,m;for(n in r=Ge.encode(this.generateCmap(),"unicode"),a=this.glyphsFor(t),f={0:0},m=r.charMap)f[(s=m[n]).old]=s.new;for(d in h=r.maxGlyphID,a)d in f||(f[d]=h++);return u=function(t){var e,r;for(e in r={},t)r[t[e]]=e;return r}(f),l=Object.keys(u).sort((function(t,e){return t-e})),p=function(){var t,e,r;for(r=[],t=0,e=l.length;t>"),a.join("\n")}return""+r},e}(),t.AcroForm=xt,t.AcroFormAppearance=Lt,t.AcroFormButton=gt,t.AcroFormCheckBox=yt,t.AcroFormChoiceField=ht,t.AcroFormComboBox=dt,t.AcroFormEditBox=pt,t.AcroFormListBox=ft,t.AcroFormPasswordField=Nt,t.AcroFormPushButton=mt,t.AcroFormRadioButton=vt,t.AcroFormTextField=wt,t.GState=C,t.ShadingPattern=O,t.TilingPattern=B,t.default=M,t.jsPDF=M,Object.defineProperty(t,"__esModule",{value:!0})})); - //# sourceMappingURL=jspdf.umd.min.js.map \ No newline at end of file + function(t){t.__bidiEngine__=t.prototype.__bidiEngine__=function(t){var r,n,i,a,o,s,c,u=e,l=[[0,3,0,1,0,0,0],[0,3,0,1,2,2,0],[0,3,0,17,2,0,1],[0,3,5,5,4,1,0],[0,3,21,21,4,0,1],[0,3,5,5,4,2,0]],h=[[2,0,1,1,0,1,0],[2,0,1,1,0,2,0],[2,0,2,1,3,2,0],[2,0,2,33,3,1,1]],f={L:0,R:1,EN:2,AN:3,N:4,B:5,S:6},d={0:0,5:1,6:2,7:3,32:4,251:5,254:6,255:7},p=["(",")","(","<",">","<","[","]","[","{","}","{","«","»","«","‹","›","‹","⁅","⁆","⁅","⁽","⁾","⁽","₍","₎","₍","≤","≥","≤","〈","〉","〈","﹙","﹚","﹙","﹛","﹜","﹛","﹝","﹞","﹝","﹤","﹥","﹤"],g=new RegExp(/^([1-4|9]|1[0-9]|2[0-9]|3[0168]|4[04589]|5[012]|7[78]|159|16[0-9]|17[0-2]|21[569]|22[03489]|250)$/),m=!1,v=0;this.__bidiEngine__={};var b=function(t){var e=t.charCodeAt(),r=e>>8,n=d[r];return void 0!==n?u[256*n+(255&e)]:252===r||253===r?"AL":g.test(r)?"L":8===r?"R":"N"},y=function(t){for(var e,r=0;r=e.length||"EN"!==(c=o[s-1])&&"AN"!==c||"EN"!==(u=e[s+1])&&"AN"!==u?f="N":m&&(u="AN"),f=u===c?u:"N";break;case"ES":f="EN"===(c=s>0?o[s-1]:"B")&&s+10&&"EN"===o[s-1]){f="EN";break}if(m){f="N";break}for(l=s+1,h=e.length;l=1425&&d<=2303||64286===d;if(c=e[l],p&&("R"===c||"AL"===c)){f="R";break}}}f=s<1||"B"===(c=e[s-1])?"N":o[s-1];break;case"B":m=!1,r=!0,f=v;break;case"S":n=!0,f="N";break;case"LRE":case"RLE":case"LRO":case"RLO":case"PDF":m=!1;break;case"BN":f="N"}return f},N=function(t,e,r){var n=t.split("");return r&&L(n,r,{hiLevel:v}),n.reverse(),e&&e.reverse(),n.join("")},L=function(t,e,i){var a,o,s,c,u,d=-1,p=t.length,g=0,y=[],N=v?h:l,L=[];for(m=!1,r=!1,n=!1,o=0;o0)if(16===a){for(o=d;o-1){for(o=d;o=0&&"WS"===t[i];i--)e[i]=v}}(L,e,p)},A=function(t,e,n,i,a){if(!(a.hiLevel=t){for(c=h+1;c=t;)c++;for(u=h,s=c-1;u=0&&(t[i]=p[n+1])}(n,r,i),A(2,n,e,r,i),A(1,n,e,r,i),n.join("")};return this.__bidiEngine__.doBidiReorder=function(t,e,r){if(function(t,e){if(e)for(var r=0;r>16))&&(e=-(1+(65535^e))),this.italicAngle=+(e+"."+r)):this.italicAngle=0,this.ascender=Math.round(this.ascender*this.scaleFactor),this.decender=Math.round(this.decender*this.scaleFactor),this.lineGap=Math.round(this.lineGap*this.scaleFactor),this.capHeight=this.os2.exists&&this.os2.capHeight||this.ascender,this.xHeight=this.os2.exists&&this.os2.xHeight||0,this.familyClass=(this.os2.exists&&this.os2.familyClass||0)>>8,this.isSerif=1===(i=this.familyClass)||2===i||3===i||4===i||5===i||7===i,this.isScript=10===this.familyClass,this.flags=0,this.post.isFixedPitch&&(this.flags|=1),this.isSerif&&(this.flags|=2),this.isScript&&(this.flags|=8),0!==this.italicAngle&&(this.flags|=64),this.flags|=32,!this.cmap.unicode)throw new Error("No unicode cmap for font")},t.prototype.characterToGlyph=function(t){var e;return(null!=(e=this.cmap.unicode)?e.codeMap[t]:void 0)||0},t.prototype.widthOfGlyph=function(t){var e;return e=1e3/this.head.unitsPerEm,this.hmtx.forGlyph(t).advance*e},t.prototype.widthOfString=function(t,e,r){var n,i,a,o;for(a=0,i=0,o=(t=""+t).length;0<=o?io;i=0<=o?++i:--i)n=t.charCodeAt(i),a+=this.widthOfGlyph(this.characterToGlyph(n))+r*(1e3/e)||0;return a*(e/1e3)},t.prototype.lineHeight=function(t,e){var r;return null==e&&(e=!1),r=e?this.lineGap:0,(this.ascender+r-this.decender)/1e3*t},t}();var Re,Te=function(){function t(t){this.data=null!=t?t:[],this.pos=0,this.length=this.data.length}return t.prototype.readByte=function(){return this.data[this.pos++]},t.prototype.writeByte=function(t){return this.data[this.pos++]=t},t.prototype.readUInt32=function(){return 16777216*this.readByte()+(this.readByte()<<16)+(this.readByte()<<8)+this.readByte()},t.prototype.writeUInt32=function(t){return this.writeByte(t>>>24&255),this.writeByte(t>>16&255),this.writeByte(t>>8&255),this.writeByte(255&t)},t.prototype.readInt32=function(){var t;return(t=this.readUInt32())>=2147483648?t-4294967296:t},t.prototype.writeInt32=function(t){return t<0&&(t+=4294967296),this.writeUInt32(t)},t.prototype.readUInt16=function(){return this.readByte()<<8|this.readByte()},t.prototype.writeUInt16=function(t){return this.writeByte(t>>8&255),this.writeByte(255&t)},t.prototype.readInt16=function(){var t;return(t=this.readUInt16())>=32768?t-65536:t},t.prototype.writeInt16=function(t){return t<0&&(t+=65536),this.writeUInt16(t)},t.prototype.readString=function(t){var e,r;for(r=[],e=0;0<=t?et;e=0<=t?++e:--e)r[e]=String.fromCharCode(this.readByte());return r.join("")},t.prototype.writeString=function(t){var e,r,n;for(n=[],e=0,r=t.length;0<=r?er;e=0<=r?++e:--e)n.push(this.writeByte(t.charCodeAt(e)));return n},t.prototype.readShort=function(){return this.readInt16()},t.prototype.writeShort=function(t){return this.writeInt16(t)},t.prototype.readLongLong=function(){var t,e,r,n,i,a,o,s;return t=this.readByte(),e=this.readByte(),r=this.readByte(),n=this.readByte(),i=this.readByte(),a=this.readByte(),o=this.readByte(),s=this.readByte(),128&t?-1*(72057594037927940*(255^t)+281474976710656*(255^e)+1099511627776*(255^r)+4294967296*(255^n)+16777216*(255^i)+65536*(255^a)+256*(255^o)+(255^s)+1):72057594037927940*t+281474976710656*e+1099511627776*r+4294967296*n+16777216*i+65536*a+256*o+s},t.prototype.writeLongLong=function(t){var e,r;return e=Math.floor(t/4294967296),r=4294967295&t,this.writeByte(e>>24&255),this.writeByte(e>>16&255),this.writeByte(e>>8&255),this.writeByte(255&e),this.writeByte(r>>24&255),this.writeByte(r>>16&255),this.writeByte(r>>8&255),this.writeByte(255&r)},t.prototype.readInt=function(){return this.readInt32()},t.prototype.writeInt=function(t){return this.writeInt32(t)},t.prototype.read=function(t){var e,r;for(e=[],r=0;0<=t?rt;r=0<=t?++r:--r)e.push(this.readByte());return e},t.prototype.write=function(t){var e,r,n,i;for(i=[],r=0,n=t.length;rn;r=0<=n?++r:--r)e={tag:t.readString(4),checksum:t.readInt(),offset:t.readInt(),length:t.readInt()},this.tables[e.tag]=e}return e.prototype.encode=function(e){var r,n,i,a,o,s,c,u,l,h,f,d,p;for(p in f=Object.keys(e).length,s=Math.log(2),l=16*Math.floor(Math.log(f)/s),a=Math.floor(l/s),u=16*f-l,(n=new Te).writeInt(this.scalarType),n.writeShort(f),n.writeShort(l),n.writeShort(a),n.writeShort(u),i=16*f,c=n.pos+i,o=null,d=[],e)for(h=e[p],n.writeString(p),n.writeInt(t(h)),n.writeInt(c),n.writeInt(h.length),d=d.concat(h),"head"===p&&(o=c),c+=h.length;c%4;)d.push(0),c++;return n.write(d),r=2981146554-t(n.data),n.pos=o+8,n.writeUInt32(r),n.data},t=function(t){var e,r,n,i;for(t=tr.call(t);t.length%4;)t.push(0);for(n=new Te(t),r=0,e=0,i=t.length;eh;s=0<=h?++e:--e)r.push(t.readUInt16());return r}(),t.pos+=2,p=function(){var e,r;for(r=[],s=e=0;0<=h?eh;s=0<=h?++e:--e)r.push(t.readUInt16());return r}(),c=function(){var e,r;for(r=[],s=e=0;0<=h?eh;s=0<=h?++e:--e)r.push(t.readUInt16());return r}(),u=function(){var e,r;for(r=[],s=e=0;0<=h?eh;s=0<=h?++e:--e)r.push(t.readUInt16());return r}(),n=(this.length-t.pos+this.offset)/2,o=function(){var e,r;for(r=[],s=e=0;0<=n?en;s=0<=n?++e:--e)r.push(t.readUInt16());return r}(),s=m=0,b=i.length;m=g;r=d<=g?++v:--v)0===u[s]?a=r+c[s]:0!==(a=o[u[s]/2+(r-d)-(h-s)]||0)&&(a+=c[s]),this.codeMap[r]=65535&a}t.pos=l}return t.encode=function(t,e){var r,n,i,a,o,s,c,u,l,h,f,d,p,g,m,v,b,y,w,N,L,A,x,S,_,P,k,F,I,C,j,O,B,M,E,q,D,R,T,U,z,H,W,V,G,Y;switch(F=new Te,a=Object.keys(t).sort((function(t,e){return t-e})),e){case"macroman":for(p=0,g=function(){var t=[];for(d=0;d<256;++d)t.push(0);return t}(),v={0:0},i={},I=0,B=a.length;I=32768)for(s.push(0),N.push(2*(f.length+x-d)),n=O=_;_<=u?O<=u:O>=u;n=_<=u?++O:--O)f.push(r[n].new);else s.push(k-_),N.push(0)}for(F.writeUInt16(3),F.writeUInt16(1),F.writeUInt32(12),F.writeUInt16(4),F.writeUInt16(16+8*x+2*f.length),F.writeUInt16(0),F.writeUInt16(S),F.writeUInt16(A),F.writeUInt16(h),F.writeUInt16(L),z=0,q=l.length;zn;r=0<=n?++r:--r)e=new Ve(t,this.offset),this.tables.push(e),e.isUnicode&&null==this.unicode&&(this.unicode=e);return!0},e.encode=function(t,e){var r,n;return null==e&&(e="macroman"),r=Ve.encode(t,e),(n=new Te).writeUInt16(0),n.writeUInt16(1),r.table=n.data.concat(r.subtable),r},e}(Re),Ye=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return He(e,t),e.prototype.tag="hhea",e.prototype.parse=function(t){return t.pos=this.offset,this.version=t.readInt(),this.ascender=t.readShort(),this.decender=t.readShort(),this.lineGap=t.readShort(),this.advanceWidthMax=t.readShort(),this.minLeftSideBearing=t.readShort(),this.minRightSideBearing=t.readShort(),this.xMaxExtent=t.readShort(),this.caretSlopeRise=t.readShort(),this.caretSlopeRun=t.readShort(),this.caretOffset=t.readShort(),t.pos+=8,this.metricDataFormat=t.readShort(),this.numberOfMetrics=t.readUInt16()},e}(Re),Je=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return He(e,t),e.prototype.tag="OS/2",e.prototype.parse=function(t){if(t.pos=this.offset,this.version=t.readUInt16(),this.averageCharWidth=t.readShort(),this.weightClass=t.readUInt16(),this.widthClass=t.readUInt16(),this.type=t.readShort(),this.ySubscriptXSize=t.readShort(),this.ySubscriptYSize=t.readShort(),this.ySubscriptXOffset=t.readShort(),this.ySubscriptYOffset=t.readShort(),this.ySuperscriptXSize=t.readShort(),this.ySuperscriptYSize=t.readShort(),this.ySuperscriptXOffset=t.readShort(),this.ySuperscriptYOffset=t.readShort(),this.yStrikeoutSize=t.readShort(),this.yStrikeoutPosition=t.readShort(),this.familyClass=t.readShort(),this.panose=function(){var e,r;for(r=[],e=0;e<10;++e)r.push(t.readByte());return r}(),this.charRange=function(){var e,r;for(r=[],e=0;e<4;++e)r.push(t.readInt());return r}(),this.vendorID=t.readString(4),this.selection=t.readShort(),this.firstCharIndex=t.readShort(),this.lastCharIndex=t.readShort(),this.version>0&&(this.ascent=t.readShort(),this.descent=t.readShort(),this.lineGap=t.readShort(),this.winAscent=t.readShort(),this.winDescent=t.readShort(),this.codePageRange=function(){var e,r;for(r=[],e=0;e<2;e=++e)r.push(t.readInt());return r}(),this.version>1))return this.xHeight=t.readShort(),this.capHeight=t.readShort(),this.defaultChar=t.readShort(),this.breakChar=t.readShort(),this.maxContext=t.readShort()},e}(Re),Xe=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return He(e,t),e.prototype.tag="post",e.prototype.parse=function(t){var e,r,n;switch(t.pos=this.offset,this.format=t.readInt(),this.italicAngle=t.readInt(),this.underlinePosition=t.readShort(),this.underlineThickness=t.readShort(),this.isFixedPitch=t.readInt(),this.minMemType42=t.readInt(),this.maxMemType42=t.readInt(),this.minMemType1=t.readInt(),this.maxMemType1=t.readInt(),this.format){case 65536:break;case 131072:var i;for(r=t.readUInt16(),this.glyphNameIndex=[],i=0;0<=r?ir;i=0<=r?++i:--i)this.glyphNameIndex.push(t.readUInt16());for(this.names=[],n=[];t.posr;i=0<=r?++e:--e)n.push(t.readUInt32());return n}.call(this)}},e}(Re),Ke=function(t,e){this.raw=t,this.length=t.length,this.platformID=e.platformID,this.encodingID=e.encodingID,this.languageID=e.languageID},Ze=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return He(e,t),e.prototype.tag="name",e.prototype.parse=function(t){var e,r,n,i,a,o,s,c,u,l,h;for(t.pos=this.offset,t.readShort(),e=t.readShort(),o=t.readShort(),r=[],i=0;0<=e?ie;i=0<=e?++i:--i)r.push({platformID:t.readShort(),encodingID:t.readShort(),languageID:t.readShort(),nameID:t.readShort(),length:t.readShort(),offset:this.offset+o+t.readShort()});for(s={},i=u=0,l=r.length;uo;e=0<=o?++e:--e)this.metrics.push({advance:t.readUInt16(),lsb:t.readInt16()});for(n=this.file.maxp.numGlyphs-this.file.hhea.numberOfMetrics,this.leftSideBearings=function(){var r,i;for(i=[],e=r=0;0<=n?rn;e=0<=n?++r:--r)i.push(t.readInt16());return i}(),this.widths=function(){var t,e,r,n;for(n=[],t=0,e=(r=this.metrics).length;tn;e=0<=n?++a:--a)s.push(this.widths.push(r));return s},e.prototype.forGlyph=function(t){return t in this.metrics?this.metrics[t]:{advance:this.metrics[this.metrics.length-1].advance,lsb:this.leftSideBearings[t-this.metrics.length]}},e}(Re),tr=[].slice,er=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return He(e,t),e.prototype.tag="glyf",e.prototype.parse=function(){return this.cache={}},e.prototype.glyphFor=function(t){var e,r,n,i,a,o,s,c,u,l;return t in this.cache?this.cache[t]:(i=this.file.loca,e=this.file.contents,r=i.indexOf(t),0===(n=i.lengthOf(t))?this.cache[t]=null:(e.pos=this.offset+r,a=(o=new Te(e.read(n))).readShort(),c=o.readShort(),l=o.readShort(),s=o.readShort(),u=o.readShort(),this.cache[t]=-1===a?new nr(o,c,l,s,u):new rr(o,a,c,l,s,u),this.cache[t]))},e.prototype.encode=function(t,e,r){var n,i,a,o,s;for(a=[],i=[],o=0,s=e.length;o0&&(n+=s)}for(var c=new Array(4*r.length),u=0;u>8,c[4*u+1]=(16711680&r[u])>>16,c[4*u]=(4278190080&r[u])>>24;return c},e}(Re),ar=function(){function t(t){this.font=t,this.subset={},this.unicodes={},this.next=33}return t.prototype.generateCmap=function(){var t,e,r,n,i;for(e in n=this.font.cmap.tables[0].codeMap,t={},i=this.subset)r=i[e],t[e]=n[r];return t},t.prototype.glyphsFor=function(t){var e,r,n,i,a,o,s;for(n={},a=0,o=t.length;a0)for(i in s=this.glyphsFor(e))r=s[i],n[i]=r;return n},t.prototype.encode=function(t,e){var r,n,i,a,o,s,c,u,l,h,f,d,p,g,m;for(n in r=Ge.encode(this.generateCmap(),"unicode"),a=this.glyphsFor(t),f={0:0},m=r.charMap)f[(s=m[n]).old]=s.new;for(d in h=r.maxGlyphID,a)d in f||(f[d]=h++);return u=function(t){var e,r;for(e in r={},t)r[t[e]]=e;return r}(f),l=Object.keys(u).sort((function(t,e){return t-e})),p=function(){var t,e,r;for(r=[],t=0,e=l.length;t>"),a.join("\n")}return""+r},e}(),t.AcroForm=xt,t.AcroFormAppearance=Lt,t.AcroFormButton=gt,t.AcroFormCheckBox=yt,t.AcroFormChoiceField=ht,t.AcroFormComboBox=dt,t.AcroFormEditBox=pt,t.AcroFormListBox=ft,t.AcroFormPasswordField=Nt,t.AcroFormPushButton=mt,t.AcroFormRadioButton=vt,t.AcroFormTextField=wt,t.GState=C,t.ShadingPattern=O,t.TilingPattern=B,t.default=M,t.jsPDF=M,Object.defineProperty(t,"__esModule",{value:!0})})); \ No newline at end of file diff --git a/src-tauri/src/conf.rs b/src-tauri/src/conf.rs new file mode 100644 index 0000000..12efb5a --- /dev/null +++ b/src-tauri/src/conf.rs @@ -0,0 +1,66 @@ +use crate::utils::{chat_root, create_file, exists}; +use std::fs; +use std::path::PathBuf; +use std::sync::Mutex; + +pub const USER_AGENT: &str = "5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"; +pub const ISSUES_URL: &str = "https://github.com/lencx/ChatGPT/issues"; +pub const AWESOME_URL: &str = "https://github.com/lencx/ChatGPT/blob/main/AWESOME.md"; + +pub struct ChatState { + pub always_on_top: Mutex, +} + +impl ChatState { + pub fn default(chat_conf: &ChatConfJson) -> Self { + ChatState { + always_on_top: Mutex::new(chat_conf.always_on_top), + } + } +} + +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)] +pub struct ChatConfJson { + pub always_on_top: bool, +} + +impl ChatConfJson { + /// init chat.conf.json + /// path: ~/.chatgpt/chat.conf.json + pub fn init() -> PathBuf { + let conf_file = ChatConfJson::conf_path(); + if !exists(&conf_file) { + create_file(&conf_file).unwrap(); + fs::write(&conf_file, r#"{"always_on_top": false}"#).unwrap(); + } + conf_file + } + + pub fn conf_path() -> PathBuf { + chat_root().join("chat.conf.json") + } + + pub fn get_chat_conf() -> Self { + let config_file = fs::read_to_string(ChatConfJson::conf_path()).unwrap(); + let config: serde_json::Value = + serde_json::from_str(&config_file).expect("failed to parse chat.conf.json"); + serde_json::from_value(config).unwrap_or_else(|_| ChatConfJson::chat_conf_default()) + } + + pub fn update_chat_conf(always_on_top: bool) { + let mut conf = ChatConfJson::get_chat_conf(); + conf.always_on_top = always_on_top; + fs::write( + ChatConfJson::conf_path(), + serde_json::to_string(&conf).unwrap(), + ) + .unwrap(); + } + + pub fn chat_conf_default() -> Self { + serde_json::from_value(serde_json::json!({ + "always_on_top": false, + })) + .unwrap() + } +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 5f07551..034ebf2 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -4,20 +4,41 @@ )] mod app; +mod conf; mod utils; use app::{cmd, menu, setup}; +use conf::ChatConfJson; fn main() { + ChatConfJson::init(); let context = tauri::generate_context!(); + let chat_conf = ChatConfJson::get_chat_conf(); + let chat_conf2 = chat_conf.clone(); tauri::Builder::default() - .invoke_handler(tauri::generate_handler![cmd::drag_window, cmd::fullscreen]) - .setup(setup::init) - .menu(menu::init(&context)) + .manage(conf::ChatState::default(&chat_conf)) + .invoke_handler(tauri::generate_handler![ + cmd::drag_window, + cmd::fullscreen, + cmd::download, + cmd::open_link + ]) + .setup(|app| setup::init(app, chat_conf2)) + .menu(menu::init(&chat_conf, &context)) .system_tray(menu::tray_menu()) .on_menu_event(menu::menu_handler) .on_system_tray_event(menu::tray_handler) + .on_window_event(|event| { + // https://github.com/tauri-apps/tauri/discussions/2684 + if let tauri::WindowEvent::CloseRequested { api, .. } = event.event() { + // TODO: https://github.com/tauri-apps/tauri/issues/3084 + // event.window().hide().unwrap(); + // https://github.com/tauri-apps/tao/pull/517 + event.window().minimize().unwrap(); + api.prevent_close(); + } + }) .run(context) .expect("error while running ChatGPT application"); } diff --git a/src-tauri/src/utils.rs b/src-tauri/src/utils.rs index cdbe2f4..15e80a8 100644 --- a/src-tauri/src/utils.rs +++ b/src-tauri/src/utils.rs @@ -1,8 +1,15 @@ use anyhow::Result; -use std::fs::{self, File}; -use std::path::{Path, PathBuf}; +use std::{ + fs::{self, File}, + path::{Path, PathBuf}, + process::Command, +}; use tauri::utils::config::Config; +pub fn chat_root() -> PathBuf { + tauri::api::path::home_dir().unwrap().join(".chatgpt") +} + pub fn get_tauri_conf() -> Option { let config_file = include_str!("../tauri.conf.json"); let config: Config = @@ -22,8 +29,7 @@ pub fn create_file(path: &Path) -> Result { } pub fn script_path() -> PathBuf { - let root = tauri::api::path::home_dir().unwrap().join(".chatgpt"); - let script_file = root.join("main.js"); + let script_file = chat_root().join("main.js"); if !exists(&script_file) { create_file(&script_file).unwrap(); fs::write(&script_file, format!("// *** ChatGPT User Script ***\n// @github: https://github.com/lencx/ChatGPT \n// @path: {}\n\nconsole.log('🤩 Hello ChatGPT!!!');", &script_file.to_string_lossy())).unwrap(); @@ -39,3 +45,19 @@ pub fn user_script() -> String { user_script_content ) } + +pub fn open_file(path: PathBuf) { + #[cfg(target_os = "macos")] + Command::new("open").arg("-R").arg(path).spawn().unwrap(); + + #[cfg(target_os = "windows")] + Command::new("explorer") + .arg("/select,") + .arg(path) + .spawn() + .unwrap(); + + // https://askubuntu.com/a/31071 + #[cfg(target_os = "linux")] + Command::new("xdg-open").arg(path).spawn().unwrap(); +} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 61be2aa..4ea4c14 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -44,6 +44,10 @@ "shortDescription": "ChatGPT", "targets": "all", "windows": { + "webviewInstallMode": { + "silent": true, + "type": "downloadBootstrapper" + }, "certificateThumbprint": null, "digestAlgorithm": "sha256", "timestampUrl": ""