Commit 91d524eb authored by NGPixel's avatar NGPixel

Merged main & websocket server, refactored libs, image uploads fixes

parent 6ea243e8
......@@ -12,7 +12,7 @@ global.PROCNAME = 'AGENT';
// ----------------------------------------
var _isDebug = process.env.NODE_ENV === 'development';
global.winston = require('./lib/winston')(_isDebug);
global.winston = require('./libs/winston')(_isDebug);
// ----------------------------------------
// Fetch internal handshake key
......@@ -30,13 +30,13 @@ global.WSInternalKey = process.argv[2];
winston.info('[AGENT] Background Agent is initializing...');
var appconfig = require('./models/config')('./config.yml');
global.db = require('./models/mongo').init(appconfig);
global.upl = require('./models/agent/uploads').init(appconfig);
global.git = require('./models/git').init(appconfig);
global.entries = require('./models/entries').init(appconfig);
global.mark = require('./models/markdown');
global.ws = require('socket.io-client')('http://localhost:' + appconfig.wsPort, { reconnectionAttempts: 10 });
var appconfig = require('./libs/config')('./config.yml');
global.db = require('./libs/mongo').init(appconfig);
global.upl = require('./libs/uploads-agent').init(appconfig);
global.git = require('./libs/git').init(appconfig);
global.entries = require('./libs/entries').init(appconfig);
global.mark = require('./libs/markdown');
global.ws = require('socket.io-client')('http://localhost:' + appconfig.port, { reconnectionAttempts: 10 });
// ----------------------------------------
// Load modules
......@@ -205,10 +205,10 @@ ws.on('connect', function () {
});
ws.on('connect_error', function () {
winston.warn('[AGENT] Unable to connect to WebSocket server! Retrying...');
winston.warn('[AGENT] Unable to connect to main server! Retrying...');
});
ws.on('reconnect_failed', function () {
winston.error('[AGENT] Failed to reconnect to WebSocket server too many times! Stopping agent...');
winston.error('[AGENT] Failed to reconnect to main server too many times! Stopping agent...');
process.exit(1);
});
......
"use strict";function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function setInputSelection(e,t,o){if(e.focus(),"undefined"!=typeof e.selectionStart)e.selectionStart=t,e.selectionEnd=o;else if(document.selection&&document.selection.createRange){e.select();var a=document.selection.createRange();a.collapse(!0),a.moveEnd("character",o),a.moveStart("character",t),a.select()}}function makeSafePath(e){var t=_.split(_.trim(e),"/");return t=_.map(t,function(e){return _.kebabCase(_.deburr(_.trim(e)))}),_.join(_.filter(t,function(e){return!_.isEmpty(e)}),"/")}var _createClass=function(){function e(e,t){for(var o=0;o<t.length;o++){var a=t[o];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,a.key,a)}}return function(t,o,a){return o&&e(t.prototype,o),a&&e(t,a),t}}();jQuery(document).ready(function(e){e("a").smoothScroll({speed:400,offset:-70});new Sticky(".stickyscroll");e(window).bind("beforeunload",function(){e("#notifload").addClass("active")}),e(document).ajaxSend(function(){e("#notifload").addClass("active")}).ajaxComplete(function(){e("#notifload").removeClass("active")});var t=new Alerts;alertsData&&_.forEach(alertsData,function(e){t.push(e)});var o=io(ioHost);if(jQuery(document).ready(function(e){if(e("#search-input").length){e("#search-input").focus(),e(".searchresults").css("display","block");var t=new Vue({el:"#header-container",data:{searchq:"",searchres:[],searchsuggest:[],searchload:0,searchactive:!1,searchmoveidx:0,searchmovekey:"",searchmovearr:[]},watch:{searchq:function(e,a){t.searchmoveidx=0,e.length>=3?(t.searchactive=!0,t.searchload++,o.emit("search",{terms:e},function(e){t.searchres=e.match,t.searchsuggest=e.suggest,t.searchmovearr=_.concat([],t.searchres,t.searchsuggest),t.searchload>0&&t.searchload--})):(t.searchactive=!1,t.searchres=[],t.searchsuggest=[],t.searchmovearr=[],t.searchload=0)},searchmoveidx:function(e,o){e>0?t.searchmovekey=t.searchmovearr[e-1]?"res."+t.searchmovearr[e-1]._id:"sug."+t.searchmovearr[e-1]:t.searchmovekey=""}},methods:{useSuggestion:function(e){t.searchq=e},closeSearch:function(){t.searchq=""},moveSelectSearch:function(){if(!(t.searchmoveidx<1)){var e=t.searchmoveidx-1;t.searchmovearr[e]?window.location.assign("/"+t.searchmovearr[e]._id):t.searchq=t.searchmovearr[e]}},moveDownSearch:function(){t.searchmoveidx<t.searchmovearr.length&&t.searchmoveidx++},moveUpSearch:function(){t.searchmoveidx>0&&t.searchmoveidx--}}});e("main").on("click",t.closeSearch)}}),e("#page-type-view").length&&!function(){var o="home"!==e("#page-type-view").data("entrypath")?e("#page-type-view").data("entrypath"):"",a=o+"/new-page";e(".btn-create-prompt").on("click",function(t){e("#txt-create-prompt").val(a),e("#modal-create-prompt").toggleClass("is-active"),setInputSelection(e("#txt-create-prompt").get(0),o.length+1,a.length),e("#txt-create-prompt").removeClass("is-danger").next().addClass("is-hidden")}),e("#txt-create-prompt").on("keypress",function(t){13===t.which&&e(".btn-create-go").trigger("click")}),e(".btn-create-go").on("click",function(t){var o=makeSafePath(e("#txt-create-prompt").val());_.isEmpty(o)?e("#txt-create-prompt").addClass("is-danger").next().removeClass("is-hidden"):(e("#txt-create-prompt").parent().addClass("is-loading"),window.location.assign("/create/"+o))}),""!==o&&e(".btn-move-prompt").removeClass("is-hidden");var n=_.lastIndexOf(o,"/")+1;e(".btn-move-prompt").on("click",function(t){e("#txt-move-prompt").val(o),e("#modal-move-prompt").toggleClass("is-active"),setInputSelection(e("#txt-move-prompt").get(0),n,o.length),e("#txt-move-prompt").removeClass("is-danger").next().addClass("is-hidden")}),e("#txt-move-prompt").on("keypress",function(t){13===t.which&&e(".btn-move-go").trigger("click")}),e(".btn-move-go").on("click",function(a){var n=makeSafePath(e("#txt-move-prompt").val());_.isEmpty(n)||n===o||"home"===n?e("#txt-move-prompt").addClass("is-danger").next().removeClass("is-hidden"):(e("#txt-move-prompt").parent().addClass("is-loading"),e.ajax(window.location.href,{data:{move:n},dataType:"json",method:"PUT"}).then(function(e,o,a){e.ok?window.location.assign("/"+n):t.pushError("Something went wrong",e.error)},function(e,o,a){t.pushError("Something went wrong","Save operation failed.")}))})}(),e("#page-type-create").length){var a;!function(){var n=e("#page-type-create").data("entrypath");e(".btn-create-discard").on("click",function(t){e("#modal-create-discard").toggleClass("is-active")}),1===e("#mk-editor").length&&!function(){var n=!1;Vue.filter("filesize",function(e){return _.toUpper(filesize(e))});var i=new Vue({el:"#modal-editor-image",data:{isLoading:!1,isLoadingText:"",newFolderName:"",newFolderShow:!1,newFolderError:!1,fetchFromUrlURL:"",fetchFromUrlShow:!1,folders:[],currentFolder:"",currentImage:"",currentAlign:"left",images:[],uploadSucceeded:!1,postUploadChecks:0},methods:{open:function(){n=!0,e("#modal-editor-image").slideDown(),i.refreshFolders()},cancel:function(t){n=!1,e("#modal-editor-image").slideUp()},insertImage:function(e){a.codemirror.doc.somethingSelected()&&a.codemirror.execCommand("singleSelection");var t=_.find(i.images,["uid",i.currentImage]);t.normalizedPath=""===t.folder?t.filename:t.folder+"/"+t.filename,t.titleGuess=_.startCase(t.basename);var o="!["+t.titleGuess+"](/uploads/"+t.normalizedPath+' "'+t.titleGuess+'")';switch(i.currentAlign){case"center":o+="{.align-center}";break;case"right":o+="{.align-right}";break;case"logo":o+="{.pagelogo}"}a.codemirror.doc.replaceSelection(o),i.cancel()},newFolder:function(t){i.newFolderName="",i.newFolderError=!1,i.newFolderShow=!0,_.delay(function(){e("#txt-editor-newfoldername").focus()},400)},newFolderDiscard:function(e){i.newFolderShow=!1},newFolderCreate:function(e){var t=new RegExp("^[a-z0-9][a-z0-9-]*[a-z0-9]$");return i.newFolderName=_.kebabCase(_.trim(i.newFolderName)),_.isEmpty(i.newFolderName)||!t.test(i.newFolderName)?void(i.newFolderError=!0):(i.newFolderDiscard(),i.isLoading=!0,i.isLoadingText="Creating new folder...",void Vue.nextTick(function(){o.emit("uploadsCreateFolder",{foldername:i.newFolderName},function(e){i.folders=e,i.currentFolder=i.newFolderName,i.images=[],i.isLoading=!1})}))},fetchFromUrl:function(e){i.fetchFromUrlShow=!0},fetchFromUrlDiscard:function(e){i.fetchFromUrlShow=!1},selectFolder:function(e){i.currentFolder=e,i.loadImages()},refreshFolders:function(){i.isLoading=!0,i.isLoadingText="Fetching folders list...",i.currentFolder="",i.currentImage="",Vue.nextTick(function(){o.emit("uploadsGetFolders",{},function(e){i.folders=e,i.loadImages()})})},loadImages:function(e){e||(i.isLoading=!0,i.isLoadingText="Fetching images..."),Vue.nextTick(function(){o.emit("uploadsGetImages",{folder:i.currentFolder},function(t){i.images=t,e||(i.isLoading=!1),i.attachContextMenus()})})},selectImage:function(e){i.currentImage=e},selectAlignment:function(e){i.currentAlign=e},attachContextMenus:function(){var t=_.map(i.folders,function(e){return{name:""!==e?e:"/ (root)",icon:"fa-folder"}});e.contextMenu("destroy",".editor-modal-imagechoices > figure"),e.contextMenu({selector:".editor-modal-imagechoices > figure",appendTo:".editor-modal-imagechoices",position:function(t,o,a){e(t.$trigger).addClass("is-contextopen");var n=e(t.$trigger).position(),i={w:e(t.$trigger).width()/2,h:e(t.$trigger).height()/2};t.$menu.css({top:n.top+i.h,left:n.left+i.w})},events:{hide:function(t){e(t.$trigger).removeClass("is-contextopen")}},items:{rename:{name:"Rename",icon:"fa-edit",callback:function(e,t){alert("Clicked on "+e)}},move:{name:"Move to...",icon:"fa-folder-open-o",items:t},delete:{name:"Delete",icon:"fa-trash",callback:function(e,t){alert("Clicked on "+e)}}}})},waitUploadComplete:function(){i.postUploadChecks++,i.isLoadingText="Processing uploads...";var e=i.images.length;i.loadImages(!0),Vue.nextTick(function(){_.delay(function(){e!==i.images.length?(i.postUploadChecks=0,i.isLoading=!1):i.postUploadChecks>5?(i.postUploadChecks=0,i.isLoading=!1,t.pushError("Unable to fetch new uploads","Try again later")):i.waitUploadComplete()},2e3)})}}});e("#btn-editor-uploadimage input").on("change",function(o){e(o.currentTarget).simpleUpload("/uploads/img",{name:"imgfile",data:{folder:i.currentFolder},limit:20,expect:"json",allowedExts:["jpg","jpeg","gif","png","webp"],allowedTypes:["image/png","image/jpeg","image/gif","image/webp"],maxFileSize:3145728,init:function(e){i.uploadSucceeded=!1,i.isLoading=!0,i.isLoadingText="Preparing to upload..."},progress:function(e){i.isLoadingText="Uploading..."+Math.round(e)+"%"},success:function(e){if(e.ok){var o=_.filter(e.results,["ok",!1]);o.length?(_.forEach(o,function(e){t.pushError("Upload error",e.msg)}),o.length<e.results.length&&(t.push({title:"Some uploads succeeded",message:"Files that are not mentionned in the errors above were uploaded successfully."}),i.uploadSucceeded=!0)):i.uploadSucceeded=!0}else t.pushError("Upload error",e.msg)},error:function(e){t.pushError(e.message,this.upload.file.name)},finish:function(){i.uploadSucceeded?i.waitUploadComplete():i.isLoading=!1}})});var r=ace.edit("codeblock-editor");r.setTheme("ace/theme/tomorrow_night"),r.getSession().setMode("ace/mode/markdown"),r.setOption("fontSize","14px"),r.setOption("hScrollBarAlwaysVisible",!1),r.setOption("wrap",!0);var l=ace.require("ace/ext/modelist"),c=new Vue({el:"#modal-editor-codeblock",data:{modes:l.modesByName,modeSelected:"text"},watch:{modeSelected:function(e,t){d(e).done(function(){ace.require("ace/mode/"+e),r.getSession().setMode("ace/mode/"+e)})}},methods:{cancel:function(t){n=!1,e("#modal-editor-codeblock").slideUp()},insertCode:function(e){a.codemirror.doc.somethingSelected()&&a.codemirror.execCommand("singleSelection");var t="\n```"+c.modeSelected+"\n"+r.getValue()+"\n```\n";a.codemirror.doc.replaceSelection(t),c.cancel()}}}),s=[],d=function(t){return e.ajax({url:"/js/ace/mode-"+t+".js",dataType:"script",cache:!0,beforeSend:function(){if(_.includes(s,t))return!1},success:function(){s.push(t)}})};a=new SimpleMDE({autofocus:!0,autoDownloadFontAwesome:!1,element:e("#mk-editor").get(0),placeholder:"Enter Markdown formatted content here...",spellChecker:!1,status:!1,toolbar:[{name:"bold",action:SimpleMDE.toggleBold,className:"fa fa-bold",title:"Bold"},{name:"italic",action:SimpleMDE.toggleItalic,className:"fa fa-italic",title:"Italic"},{name:"strikethrough",action:SimpleMDE.toggleStrikethrough,className:"fa fa-strikethrough",title:"Strikethrough"},"|",{name:"heading-1",action:SimpleMDE.toggleHeading1,className:"fa fa-header fa-header-x fa-header-1",title:"Big Heading"},{name:"heading-2",action:SimpleMDE.toggleHeading2,className:"fa fa-header fa-header-x fa-header-2",title:"Medium Heading"},{name:"heading-3",action:SimpleMDE.toggleHeading3,className:"fa fa-header fa-header-x fa-header-3",title:"Small Heading"},{name:"quote",action:SimpleMDE.toggleBlockquote,className:"fa fa-quote-left",title:"Quote"},"|",{name:"unordered-list",action:SimpleMDE.toggleUnorderedList,className:"fa fa-list-ul",title:"Bullet List"},{name:"ordered-list",action:SimpleMDE.toggleOrderedList,className:"fa fa-list-ol",title:"Numbered List"},"|",{name:"link",action:function(t){n||(n=!0,e("#modal-editor-link").slideToggle())},className:"fa fa-link",title:"Insert Link"},{name:"image",action:function(e){n||i.open()},className:"fa fa-image",title:"Insert Image"},{name:"file",action:function(e){},className:"fa fa-file-text-o",title:"Insert File"},"|",{name:"inline-code",action:function(e){if(!e.codemirror.doc.somethingSelected())return t.pushError("Invalid selection","You must select at least 1 character first.");var o=e.codemirror.doc.getSelections();o=_.map(o,function(e){return"`"+e+"`"}),e.codemirror.doc.replaceSelections(o)},className:"fa fa-terminal",title:"Inline Code"},{name:"code-block",action:function(t){n||(n=!0,a.codemirror.doc.somethingSelected()?r.setValue(a.codemirror.doc.getSelection()):r.setValue(""),e("#modal-editor-codeblock").slideDown(400,function(){r.resize(),r.focus()}))},className:"fa fa-code",title:"Code Block"},"|",{name:"table",action:function(e){},className:"fa fa-table",title:"Insert Table"},{name:"horizontal-rule",action:SimpleMDE.drawHorizontalRule,className:"fa fa-minus",title:"Horizontal Rule"}],shortcuts:{toggleBlockquote:null,toggleFullScreen:null}})}(),e(".btn-edit-save, .btn-create-save").on("click",function(o){e.ajax(window.location.href,{data:{markdown:a.value()},dataType:"json",method:"PUT"}).then(function(e,o,a){e.ok?window.location.assign("/"+n):t.pushError("Something went wrong",e.error)},function(e,o,a){t.pushError("Something went wrong","Save operation failed.")})})}()}if(e("#page-type-edit").length){var a;!function(){var n=e("#page-type-edit").data("entrypath");e(".btn-edit-discard").on("click",function(t){e("#modal-edit-discard").toggleClass("is-active")}),1===e("#mk-editor").length&&!function(){var n=!1;Vue.filter("filesize",function(e){return _.toUpper(filesize(e))});var i=new Vue({el:"#modal-editor-image",data:{isLoading:!1,isLoadingText:"",newFolderName:"",newFolderShow:!1,newFolderError:!1,fetchFromUrlURL:"",fetchFromUrlShow:!1,folders:[],currentFolder:"",currentImage:"",currentAlign:"left",images:[],uploadSucceeded:!1,postUploadChecks:0},methods:{open:function(){n=!0,e("#modal-editor-image").slideDown(),i.refreshFolders()},cancel:function(t){n=!1,e("#modal-editor-image").slideUp()},insertImage:function(e){a.codemirror.doc.somethingSelected()&&a.codemirror.execCommand("singleSelection");var t=_.find(i.images,["uid",i.currentImage]);t.normalizedPath=""===t.folder?t.filename:t.folder+"/"+t.filename,t.titleGuess=_.startCase(t.basename);var o="!["+t.titleGuess+"](/uploads/"+t.normalizedPath+' "'+t.titleGuess+'")';switch(i.currentAlign){case"center":o+="{.align-center}";break;case"right":o+="{.align-right}";break;case"logo":o+="{.pagelogo}"}a.codemirror.doc.replaceSelection(o),i.cancel()},newFolder:function(t){i.newFolderName="",i.newFolderError=!1,i.newFolderShow=!0,_.delay(function(){e("#txt-editor-newfoldername").focus()},400)},newFolderDiscard:function(e){i.newFolderShow=!1},newFolderCreate:function(e){var t=new RegExp("^[a-z0-9][a-z0-9-]*[a-z0-9]$");return i.newFolderName=_.kebabCase(_.trim(i.newFolderName)),_.isEmpty(i.newFolderName)||!t.test(i.newFolderName)?void(i.newFolderError=!0):(i.newFolderDiscard(),i.isLoading=!0,i.isLoadingText="Creating new folder...",void Vue.nextTick(function(){o.emit("uploadsCreateFolder",{foldername:i.newFolderName},function(e){i.folders=e,i.currentFolder=i.newFolderName,i.images=[],i.isLoading=!1})}))},fetchFromUrl:function(e){i.fetchFromUrlShow=!0},fetchFromUrlDiscard:function(e){i.fetchFromUrlShow=!1},selectFolder:function(e){i.currentFolder=e,i.loadImages()},refreshFolders:function(){i.isLoading=!0,i.isLoadingText="Fetching folders list...",i.currentFolder="",i.currentImage="",Vue.nextTick(function(){o.emit("uploadsGetFolders",{},function(e){i.folders=e,i.loadImages()})})},loadImages:function(e){e||(i.isLoading=!0,i.isLoadingText="Fetching images..."),Vue.nextTick(function(){o.emit("uploadsGetImages",{folder:i.currentFolder},function(t){i.images=t,e||(i.isLoading=!1),i.attachContextMenus()})})},selectImage:function(e){i.currentImage=e},selectAlignment:function(e){i.currentAlign=e},attachContextMenus:function(){var t=_.map(i.folders,function(e){return{name:""!==e?e:"/ (root)",icon:"fa-folder"}});e.contextMenu("destroy",".editor-modal-imagechoices > figure"),e.contextMenu({selector:".editor-modal-imagechoices > figure",appendTo:".editor-modal-imagechoices",position:function(t,o,a){e(t.$trigger).addClass("is-contextopen");var n=e(t.$trigger).position(),i={w:e(t.$trigger).width()/2,h:e(t.$trigger).height()/2};t.$menu.css({top:n.top+i.h,left:n.left+i.w})},events:{hide:function(t){e(t.$trigger).removeClass("is-contextopen")}},items:{rename:{name:"Rename",icon:"fa-edit",callback:function(e,t){alert("Clicked on "+e)}},move:{name:"Move to...",icon:"fa-folder-open-o",items:t},delete:{name:"Delete",icon:"fa-trash",callback:function(e,t){alert("Clicked on "+e)}}}})},waitUploadComplete:function(){i.postUploadChecks++,i.isLoadingText="Processing uploads...";var e=i.images.length;i.loadImages(!0),Vue.nextTick(function(){_.delay(function(){e!==i.images.length?(i.postUploadChecks=0,i.isLoading=!1):i.postUploadChecks>5?(i.postUploadChecks=0,i.isLoading=!1,t.pushError("Unable to fetch new uploads","Try again later")):i.waitUploadComplete()},2e3)})}}});e("#btn-editor-uploadimage input").on("change",function(o){e(o.currentTarget).simpleUpload("/uploads/img",{name:"imgfile",data:{folder:i.currentFolder},limit:20,expect:"json",allowedExts:["jpg","jpeg","gif","png","webp"],allowedTypes:["image/png","image/jpeg","image/gif","image/webp"],maxFileSize:3145728,init:function(e){i.uploadSucceeded=!1,i.isLoading=!0,i.isLoadingText="Preparing to upload..."},progress:function(e){i.isLoadingText="Uploading..."+Math.round(e)+"%"},success:function(e){if(e.ok){var o=_.filter(e.results,["ok",!1]);o.length?(_.forEach(o,function(e){t.pushError("Upload error",e.msg)}),o.length<e.results.length&&(t.push({title:"Some uploads succeeded",message:"Files that are not mentionned in the errors above were uploaded successfully."}),i.uploadSucceeded=!0)):i.uploadSucceeded=!0}else t.pushError("Upload error",e.msg)},error:function(e){t.pushError(e.message,this.upload.file.name)},finish:function(){i.uploadSucceeded?i.waitUploadComplete():i.isLoading=!1}})});var r=ace.edit("codeblock-editor");r.setTheme("ace/theme/tomorrow_night"),r.getSession().setMode("ace/mode/markdown"),r.setOption("fontSize","14px"),r.setOption("hScrollBarAlwaysVisible",!1),r.setOption("wrap",!0);var l=ace.require("ace/ext/modelist"),c=new Vue({el:"#modal-editor-codeblock",data:{modes:l.modesByName,modeSelected:"text"},watch:{modeSelected:function(e,t){d(e).done(function(){ace.require("ace/mode/"+e),r.getSession().setMode("ace/mode/"+e)})}},methods:{cancel:function(t){n=!1,e("#modal-editor-codeblock").slideUp()},insertCode:function(e){a.codemirror.doc.somethingSelected()&&a.codemirror.execCommand("singleSelection");var t="\n```"+c.modeSelected+"\n"+r.getValue()+"\n```\n";a.codemirror.doc.replaceSelection(t),c.cancel()}}}),s=[],d=function(t){return e.ajax({url:"/js/ace/mode-"+t+".js",dataType:"script",cache:!0,beforeSend:function(){if(_.includes(s,t))return!1},success:function(){s.push(t)}})};a=new SimpleMDE({autofocus:!0,autoDownloadFontAwesome:!1,element:e("#mk-editor").get(0),placeholder:"Enter Markdown formatted content here...",spellChecker:!1,status:!1,toolbar:[{name:"bold",action:SimpleMDE.toggleBold,className:"fa fa-bold",title:"Bold"},{name:"italic",action:SimpleMDE.toggleItalic,className:"fa fa-italic",title:"Italic"},{name:"strikethrough",action:SimpleMDE.toggleStrikethrough,className:"fa fa-strikethrough",title:"Strikethrough"},"|",{name:"heading-1",action:SimpleMDE.toggleHeading1,className:"fa fa-header fa-header-x fa-header-1",title:"Big Heading"},{name:"heading-2",action:SimpleMDE.toggleHeading2,className:"fa fa-header fa-header-x fa-header-2",title:"Medium Heading"},{name:"heading-3",action:SimpleMDE.toggleHeading3,className:"fa fa-header fa-header-x fa-header-3",title:"Small Heading"},{name:"quote",action:SimpleMDE.toggleBlockquote,className:"fa fa-quote-left",title:"Quote"},"|",{name:"unordered-list",action:SimpleMDE.toggleUnorderedList,className:"fa fa-list-ul",title:"Bullet List"},{name:"ordered-list",action:SimpleMDE.toggleOrderedList,className:"fa fa-list-ol",title:"Numbered List"},"|",{name:"link",action:function(t){n||(n=!0,e("#modal-editor-link").slideToggle())},className:"fa fa-link",title:"Insert Link"},{name:"image",action:function(e){n||i.open()},className:"fa fa-image",title:"Insert Image"},{name:"file",action:function(e){},className:"fa fa-file-text-o",title:"Insert File"},"|",{name:"inline-code",action:function(e){if(!e.codemirror.doc.somethingSelected())return t.pushError("Invalid selection","You must select at least 1 character first.");var o=e.codemirror.doc.getSelections();o=_.map(o,function(e){return"`"+e+"`"}),e.codemirror.doc.replaceSelections(o)},className:"fa fa-terminal",title:"Inline Code"},{name:"code-block",action:function(t){n||(n=!0,a.codemirror.doc.somethingSelected()?r.setValue(a.codemirror.doc.getSelection()):r.setValue(""),e("#modal-editor-codeblock").slideDown(400,function(){r.resize(),r.focus()}))},className:"fa fa-code",title:"Code Block"},"|",{name:"table",action:function(e){},className:"fa fa-table",title:"Insert Table"},{name:"horizontal-rule",action:SimpleMDE.drawHorizontalRule,className:"fa fa-minus",title:"Horizontal Rule"}],shortcuts:{toggleBlockquote:null,toggleFullScreen:null}})}(),e(".btn-edit-save, .btn-create-save").on("click",function(o){e.ajax(window.location.href,{data:{markdown:a.value()},dataType:"json",method:"PUT"}).then(function(e,o,a){e.ok?window.location.assign("/"+n):t.pushError("Something went wrong",e.error)},function(e,o,a){t.pushError("Something went wrong","Save operation failed.")})})}()}if(e("#page-type-source").length){var n;!function(){n=ace.edit("source-display"),n.setTheme("ace/theme/tomorrow_night"),n.getSession().setMode("ace/mode/markdown"),n.setReadOnly(!0),n.renderer.updateFull();var o="home"!==e("#page-type-source").data("entrypath")?e("#page-type-source").data("entrypath"):"",a=o+"/new-page";e(".btn-create-prompt").on("click",function(t){e("#txt-create-prompt").val(a),e("#modal-create-prompt").toggleClass("is-active"),setInputSelection(e("#txt-create-prompt").get(0),o.length+1,a.length),e("#txt-create-prompt").removeClass("is-danger").next().addClass("is-hidden")}),e("#txt-create-prompt").on("keypress",function(t){13===t.which&&e(".btn-create-go").trigger("click")}),e(".btn-create-go").on("click",function(t){var o=makeSafePath(e("#txt-create-prompt").val());_.isEmpty(o)?e("#txt-create-prompt").addClass("is-danger").next().removeClass("is-hidden"):(e("#txt-create-prompt").parent().addClass("is-loading"),window.location.assign("/create/"+o))}),""!==o&&e(".btn-move-prompt").removeClass("is-hidden");var i=_.lastIndexOf(o,"/")+1;e(".btn-move-prompt").on("click",function(t){e("#txt-move-prompt").val(o),e("#modal-move-prompt").toggleClass("is-active"),setInputSelection(e("#txt-move-prompt").get(0),i,o.length),e("#txt-move-prompt").removeClass("is-danger").next().addClass("is-hidden")}),e("#txt-move-prompt").on("keypress",function(t){13===t.which&&e(".btn-move-go").trigger("click")}),e(".btn-move-go").on("click",function(a){var n=makeSafePath(e("#txt-move-prompt").val());_.isEmpty(n)||n===o||"home"===n?e("#txt-move-prompt").addClass("is-danger").next().removeClass("is-hidden"):(e("#txt-move-prompt").parent().addClass("is-loading"),e.ajax(window.location.href,{data:{move:n},dataType:"json",method:"PUT"}).then(function(e,o,a){e.ok?window.location.assign("/"+n):t.pushError("Something went wrong",e.error)},function(e,o,a){t.pushError("Something went wrong","Save operation failed.")}))})}()}});var Alerts=function(){function e(){_classCallCheck(this,e);var t=this;t.mdl=new Vue({el:"#alerts",data:{children:[]},methods:{acknowledge:function(e){t.close(e)}}}),t.uidNext=1}return _createClass(e,[{key:"push",value:function(e){var t=this,o=_.defaults(e,{_uid:t.uidNext,class:"is-info",message:"---",sticky:!1,title:"---"});t.mdl.children.push(o),o.sticky||_.delay(function(){t.close(o._uid)},5e3),t.uidNext++}},{key:"pushError",value:function(e,t){this.push({class:"is-danger",message:t,sticky:!1,title:e})}},{key:"pushSuccess",value:function(e,t){this.push({class:"is-success",message:t,sticky:!1,title:e})}},{key:"close",value:function(e){var t=this,o=_.findIndex(t.mdl.children,["_uid",e]),a=_.nth(t.mdl.children,o);o>=0&&a&&(a.class+=" exit",Vue.set(t.mdl.children,o,a),_.delay(function(){t.mdl.children.splice(o,1)},500))}}]),e}();
\ No newline at end of file
"use strict";function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function setInputSelection(e,t,o){if(e.focus(),"undefined"!=typeof e.selectionStart)e.selectionStart=t,e.selectionEnd=o;else if(document.selection&&document.selection.createRange){e.select();var a=document.selection.createRange();a.collapse(!0),a.moveEnd("character",o),a.moveStart("character",t),a.select()}}function makeSafePath(e){var t=_.split(_.trim(e),"/");return t=_.map(t,function(e){return _.kebabCase(_.deburr(_.trim(e)))}),_.join(_.filter(t,function(e){return!_.isEmpty(e)}),"/")}var _createClass=function(){function e(e,t){for(var o=0;o<t.length;o++){var a=t[o];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,a.key,a)}}return function(t,o,a){return o&&e(t.prototype,o),a&&e(t,a),t}}();jQuery(document).ready(function(e){e("a").smoothScroll({speed:400,offset:-70});new Sticky(".stickyscroll");e(window).bind("beforeunload",function(){e("#notifload").addClass("active")}),e(document).ajaxSend(function(){e("#notifload").addClass("active")}).ajaxComplete(function(){e("#notifload").removeClass("active")});var t=new Alerts;alertsData&&_.forEach(alertsData,function(e){t.push(e)});var o=io(ioHost);if(e("#search-input").length){e("#search-input").focus(),e(".searchresults").css("display","block");var a=new Vue({el:"#header-container",data:{searchq:"",searchres:[],searchsuggest:[],searchload:0,searchactive:!1,searchmoveidx:0,searchmovekey:"",searchmovearr:[]},watch:{searchq:function(e,t){a.searchmoveidx=0,e.length>=3?(a.searchactive=!0,a.searchload++,o.emit("search",{terms:e},function(e){a.searchres=e.match,a.searchsuggest=e.suggest,a.searchmovearr=_.concat([],a.searchres,a.searchsuggest),a.searchload>0&&a.searchload--})):(a.searchactive=!1,a.searchres=[],a.searchsuggest=[],a.searchmovearr=[],a.searchload=0)},searchmoveidx:function(e,t){e>0?a.searchmovekey=a.searchmovearr[e-1]?"res."+a.searchmovearr[e-1]._id:"sug."+a.searchmovearr[e-1]:a.searchmovekey=""}},methods:{useSuggestion:function(e){a.searchq=e},closeSearch:function(){a.searchq=""},moveSelectSearch:function(){if(!(a.searchmoveidx<1)){var e=a.searchmoveidx-1;a.searchmovearr[e]?window.location.assign("/"+a.searchmovearr[e]._id):a.searchq=a.searchmovearr[e]}},moveDownSearch:function(){a.searchmoveidx<a.searchmovearr.length&&a.searchmoveidx++},moveUpSearch:function(){a.searchmoveidx>0&&a.searchmoveidx--}}});e("main").on("click",a.closeSearch)}if(e("#page-type-view").length&&!function(){var o="home"!==e("#page-type-view").data("entrypath")?e("#page-type-view").data("entrypath"):"",a=o+"/new-page";e(".btn-create-prompt").on("click",function(t){e("#txt-create-prompt").val(a),e("#modal-create-prompt").toggleClass("is-active"),setInputSelection(e("#txt-create-prompt").get(0),o.length+1,a.length),e("#txt-create-prompt").removeClass("is-danger").next().addClass("is-hidden")}),e("#txt-create-prompt").on("keypress",function(t){13===t.which&&e(".btn-create-go").trigger("click")}),e(".btn-create-go").on("click",function(t){var o=makeSafePath(e("#txt-create-prompt").val());_.isEmpty(o)?e("#txt-create-prompt").addClass("is-danger").next().removeClass("is-hidden"):(e("#txt-create-prompt").parent().addClass("is-loading"),window.location.assign("/create/"+o))}),""!==o&&e(".btn-move-prompt").removeClass("is-hidden");var n=_.lastIndexOf(o,"/")+1;e(".btn-move-prompt").on("click",function(t){e("#txt-move-prompt").val(o),e("#modal-move-prompt").toggleClass("is-active"),setInputSelection(e("#txt-move-prompt").get(0),n,o.length),e("#txt-move-prompt").removeClass("is-danger").next().addClass("is-hidden")}),e("#txt-move-prompt").on("keypress",function(t){13===t.which&&e(".btn-move-go").trigger("click")}),e(".btn-move-go").on("click",function(a){var n=makeSafePath(e("#txt-move-prompt").val());_.isEmpty(n)||n===o||"home"===n?e("#txt-move-prompt").addClass("is-danger").next().removeClass("is-hidden"):(e("#txt-move-prompt").parent().addClass("is-loading"),e.ajax(window.location.href,{data:{move:n},dataType:"json",method:"PUT"}).then(function(e,o,a){e.ok?window.location.assign("/"+n):t.pushError("Something went wrong",e.error)},function(e,o,a){t.pushError("Something went wrong","Save operation failed.")}))})}(),e("#page-type-create").length){var n;!function(){var a=e("#page-type-create").data("entrypath");e(".btn-create-discard").on("click",function(t){e("#modal-create-discard").toggleClass("is-active")}),1===e("#mk-editor").length&&!function(){var a=!1;Vue.filter("filesize",function(e){return _.toUpper(filesize(e))});var i=new Vue({el:"#modal-editor-image",data:{isLoading:!1,isLoadingText:"",newFolderName:"",newFolderShow:!1,newFolderError:!1,fetchFromUrlURL:"",fetchFromUrlShow:!1,folders:[],currentFolder:"",currentImage:"",currentAlign:"left",images:[],uploadSucceeded:!1,postUploadChecks:0,deleteImageShow:!1,deleteImageId:0,deleteImageFilename:""},methods:{open:function(){a=!0,e("#modal-editor-image").slideDown(),i.refreshFolders()},cancel:function(t){a=!1,e("#modal-editor-image").slideUp()},insertImage:function(e){n.codemirror.doc.somethingSelected()&&n.codemirror.execCommand("singleSelection");var t=_.find(i.images,["_id",i.currentImage]);t.normalizedPath="f:"===t.folder?t.filename:t.folder.slice(2)+"/"+t.filename,t.titleGuess=_.startCase(t.basename);var o="!["+t.titleGuess+"](/uploads/"+t.normalizedPath+' "'+t.titleGuess+'")';switch(i.currentAlign){case"center":o+="{.align-center}";break;case"right":o+="{.align-right}";break;case"logo":o+="{.pagelogo}"}n.codemirror.doc.replaceSelection(o),i.cancel()},newFolder:function(t){i.newFolderName="",i.newFolderError=!1,i.newFolderShow=!0,_.delay(function(){e("#txt-editor-newfoldername").focus()},400)},newFolderDiscard:function(e){i.newFolderShow=!1},newFolderCreate:function(e){var t=new RegExp("^[a-z0-9][a-z0-9-]*[a-z0-9]$");return i.newFolderName=_.kebabCase(_.trim(i.newFolderName)),_.isEmpty(i.newFolderName)||!t.test(i.newFolderName)?void(i.newFolderError=!0):(i.newFolderDiscard(),i.isLoading=!0,i.isLoadingText="Creating new folder...",void Vue.nextTick(function(){o.emit("uploadsCreateFolder",{foldername:i.newFolderName},function(e){i.folders=e,i.currentFolder=i.newFolderName,i.images=[],i.isLoading=!1})}))},fetchFromUrl:function(e){i.fetchFromUrlShow=!0},fetchFromUrlDiscard:function(e){i.fetchFromUrlShow=!1},fetchFromUrlFetch:function(e){},selectFolder:function(e){i.currentFolder=e,i.loadImages()},refreshFolders:function(){i.isLoading=!0,i.isLoadingText="Fetching folders list...",i.currentFolder="",i.currentImage="",Vue.nextTick(function(){o.emit("uploadsGetFolders",{},function(e){i.folders=e,i.loadImages()})})},loadImages:function(e){e||(i.isLoading=!0,i.isLoadingText="Fetching images..."),Vue.nextTick(function(){o.emit("uploadsGetImages",{folder:i.currentFolder},function(t){i.images=t,e||(i.isLoading=!1),i.attachContextMenus()})})},selectImage:function(e){i.currentImage=e},selectAlignment:function(e){i.currentAlign=e},attachContextMenus:function(){var t=_.map(i.folders,function(e){return{name:""!==e?e:"/ (root)",icon:"fa-folder"}});e.contextMenu("destroy",".editor-modal-imagechoices > figure"),e.contextMenu({selector:".editor-modal-imagechoices > figure",appendTo:".editor-modal-imagechoices",position:function(t,o,a){e(t.$trigger).addClass("is-contextopen");var n=e(t.$trigger).position(),i={w:e(t.$trigger).width()/2,h:e(t.$trigger).height()/2};t.$menu.css({top:n.top+i.h,left:n.left+i.w})},events:{hide:function(t){e(t.$trigger).removeClass("is-contextopen")}},items:{rename:{name:"Rename",icon:"fa-edit",callback:function(e,t){alert("Clicked on "+e)}},move:{name:"Move to...",icon:"fa-folder-open-o",items:t},delete:{name:"Delete",icon:"fa-trash",callback:function(t,o){i.deleteImageId=_.toString(e(o.$trigger).data("uid")),i.deleteImageWarn(!0)}}}})},deleteImageWarn:function(e){e&&(i.deleteImageFilename=_.find(i.images,["_id",i.deleteImageId]).filename),i.deleteImageShow=e},deleteImageGo:function(){i.deleteImageWarn(!1),i.isLoadingText="Deleting image...",i.isLoading=!0,Vue.nextTick(function(){o.emit("uploadsDeleteFile",{uid:i.deleteImageId},function(e){i.loadImages()})})},waitUploadComplete:function(){i.postUploadChecks++,i.isLoadingText="Processing...";var e=i.images.length;i.loadImages(!0),Vue.nextTick(function(){_.delay(function(){e!==i.images.length?(i.postUploadChecks=0,i.isLoading=!1):i.postUploadChecks>5?(i.postUploadChecks=0,i.isLoading=!1,t.pushError("Unable to fetch new listing","Try again later")):i.waitUploadComplete()},2e3)})}}});e("#btn-editor-uploadimage input").on("change",function(o){e(o.currentTarget).simpleUpload("/uploads/img",{name:"imgfile",data:{folder:i.currentFolder},limit:20,expect:"json",allowedExts:["jpg","jpeg","gif","png","webp"],allowedTypes:["image/png","image/jpeg","image/gif","image/webp"],maxFileSize:3145728,init:function(e){i.uploadSucceeded=!1,i.isLoading=!0,i.isLoadingText="Preparing to upload..."},progress:function(e){i.isLoadingText="Uploading..."+Math.round(e)+"%"},success:function(e){if(e.ok){var o=_.filter(e.results,["ok",!1]);o.length?(_.forEach(o,function(e){t.pushError("Upload error",e.msg)}),o.length<e.results.length&&(t.push({title:"Some uploads succeeded",message:"Files that are not mentionned in the errors above were uploaded successfully."}),i.uploadSucceeded=!0)):i.uploadSucceeded=!0}else t.pushError("Upload error",e.msg)},error:function(e){t.pushError(e.message,this.upload.file.name)},finish:function(){i.uploadSucceeded?i.waitUploadComplete():i.isLoading=!1}})});var r=ace.edit("codeblock-editor");r.setTheme("ace/theme/tomorrow_night"),r.getSession().setMode("ace/mode/markdown"),r.setOption("fontSize","14px"),r.setOption("hScrollBarAlwaysVisible",!1),r.setOption("wrap",!0);var l=ace.require("ace/ext/modelist"),c=new Vue({el:"#modal-editor-codeblock",data:{modes:l.modesByName,modeSelected:"text"},watch:{modeSelected:function(e,t){d(e).done(function(){ace.require("ace/mode/"+e),r.getSession().setMode("ace/mode/"+e)})}},methods:{cancel:function(t){a=!1,e("#modal-editor-codeblock").slideUp()},insertCode:function(e){n.codemirror.doc.somethingSelected()&&n.codemirror.execCommand("singleSelection");var t="\n```"+c.modeSelected+"\n"+r.getValue()+"\n```\n";n.codemirror.doc.replaceSelection(t),c.cancel()}}}),s=[],d=function(t){return e.ajax({url:"/js/ace/mode-"+t+".js",dataType:"script",cache:!0,beforeSend:function(){if(_.includes(s,t))return!1},success:function(){s.push(t)}})};n=new SimpleMDE({autofocus:!0,autoDownloadFontAwesome:!1,element:e("#mk-editor").get(0),placeholder:"Enter Markdown formatted content here...",spellChecker:!1,status:!1,toolbar:[{name:"bold",action:SimpleMDE.toggleBold,className:"fa fa-bold",title:"Bold"},{name:"italic",action:SimpleMDE.toggleItalic,className:"fa fa-italic",title:"Italic"},{name:"strikethrough",action:SimpleMDE.toggleStrikethrough,className:"fa fa-strikethrough",title:"Strikethrough"},"|",{name:"heading-1",action:SimpleMDE.toggleHeading1,className:"fa fa-header fa-header-x fa-header-1",title:"Big Heading"},{name:"heading-2",action:SimpleMDE.toggleHeading2,className:"fa fa-header fa-header-x fa-header-2",title:"Medium Heading"},{name:"heading-3",action:SimpleMDE.toggleHeading3,className:"fa fa-header fa-header-x fa-header-3",title:"Small Heading"},{name:"quote",action:SimpleMDE.toggleBlockquote,className:"fa fa-quote-left",title:"Quote"},"|",{name:"unordered-list",action:SimpleMDE.toggleUnorderedList,className:"fa fa-list-ul",title:"Bullet List"},{name:"ordered-list",action:SimpleMDE.toggleOrderedList,className:"fa fa-list-ol",title:"Numbered List"},"|",{name:"link",action:function(t){a||(a=!0,e("#modal-editor-link").slideToggle())},className:"fa fa-link",title:"Insert Link"},{name:"image",action:function(e){a||i.open()},className:"fa fa-image",title:"Insert Image"},{name:"file",action:function(e){},className:"fa fa-file-text-o",title:"Insert File"},"|",{name:"inline-code",action:function(e){if(!e.codemirror.doc.somethingSelected())return t.pushError("Invalid selection","You must select at least 1 character first.");var o=e.codemirror.doc.getSelections();o=_.map(o,function(e){return"`"+e+"`"}),e.codemirror.doc.replaceSelections(o)},className:"fa fa-terminal",title:"Inline Code"},{name:"code-block",action:function(t){a||(a=!0,n.codemirror.doc.somethingSelected()?r.setValue(n.codemirror.doc.getSelection()):r.setValue(""),e("#modal-editor-codeblock").slideDown(400,function(){r.resize(),r.focus()}))},className:"fa fa-code",title:"Code Block"},"|",{name:"table",action:function(e){},className:"fa fa-table",title:"Insert Table"},{name:"horizontal-rule",action:SimpleMDE.drawHorizontalRule,className:"fa fa-minus",title:"Horizontal Rule"}],shortcuts:{toggleBlockquote:null,toggleFullScreen:null}})}(),e(".btn-edit-save, .btn-create-save").on("click",function(o){e.ajax(window.location.href,{data:{markdown:n.value()},dataType:"json",method:"PUT"}).then(function(e,o,n){e.ok?window.location.assign("/"+a):t.pushError("Something went wrong",e.error)},function(e,o,a){t.pushError("Something went wrong","Save operation failed.")})})}()}if(e("#page-type-edit").length){var n;!function(){var a=e("#page-type-edit").data("entrypath");e(".btn-edit-discard").on("click",function(t){e("#modal-edit-discard").toggleClass("is-active")}),1===e("#mk-editor").length&&!function(){var a=!1;Vue.filter("filesize",function(e){return _.toUpper(filesize(e))});var i=new Vue({el:"#modal-editor-image",data:{isLoading:!1,isLoadingText:"",newFolderName:"",newFolderShow:!1,newFolderError:!1,fetchFromUrlURL:"",fetchFromUrlShow:!1,folders:[],currentFolder:"",currentImage:"",currentAlign:"left",images:[],uploadSucceeded:!1,postUploadChecks:0,deleteImageShow:!1,deleteImageId:0,deleteImageFilename:""},methods:{open:function(){a=!0,e("#modal-editor-image").slideDown(),i.refreshFolders()},cancel:function(t){a=!1,e("#modal-editor-image").slideUp()},insertImage:function(e){n.codemirror.doc.somethingSelected()&&n.codemirror.execCommand("singleSelection");var t=_.find(i.images,["_id",i.currentImage]);t.normalizedPath="f:"===t.folder?t.filename:t.folder.slice(2)+"/"+t.filename,t.titleGuess=_.startCase(t.basename);var o="!["+t.titleGuess+"](/uploads/"+t.normalizedPath+' "'+t.titleGuess+'")';switch(i.currentAlign){case"center":o+="{.align-center}";break;case"right":o+="{.align-right}";break;case"logo":o+="{.pagelogo}"}n.codemirror.doc.replaceSelection(o),i.cancel()},newFolder:function(t){i.newFolderName="",i.newFolderError=!1,i.newFolderShow=!0,_.delay(function(){e("#txt-editor-newfoldername").focus()},400)},newFolderDiscard:function(e){i.newFolderShow=!1},newFolderCreate:function(e){var t=new RegExp("^[a-z0-9][a-z0-9-]*[a-z0-9]$");return i.newFolderName=_.kebabCase(_.trim(i.newFolderName)),_.isEmpty(i.newFolderName)||!t.test(i.newFolderName)?void(i.newFolderError=!0):(i.newFolderDiscard(),i.isLoading=!0,i.isLoadingText="Creating new folder...",void Vue.nextTick(function(){o.emit("uploadsCreateFolder",{foldername:i.newFolderName},function(e){i.folders=e,i.currentFolder=i.newFolderName,i.images=[],i.isLoading=!1})}))},fetchFromUrl:function(e){i.fetchFromUrlShow=!0},fetchFromUrlDiscard:function(e){i.fetchFromUrlShow=!1},fetchFromUrlFetch:function(e){},selectFolder:function(e){i.currentFolder=e,i.loadImages()},refreshFolders:function(){i.isLoading=!0,i.isLoadingText="Fetching folders list...",i.currentFolder="",i.currentImage="",Vue.nextTick(function(){o.emit("uploadsGetFolders",{},function(e){i.folders=e,i.loadImages()})})},loadImages:function(e){e||(i.isLoading=!0,i.isLoadingText="Fetching images..."),Vue.nextTick(function(){o.emit("uploadsGetImages",{folder:i.currentFolder},function(t){i.images=t,e||(i.isLoading=!1),i.attachContextMenus()})})},selectImage:function(e){i.currentImage=e},selectAlignment:function(e){i.currentAlign=e},attachContextMenus:function(){var t=_.map(i.folders,function(e){return{name:""!==e?e:"/ (root)",icon:"fa-folder"}});e.contextMenu("destroy",".editor-modal-imagechoices > figure"),e.contextMenu({selector:".editor-modal-imagechoices > figure",appendTo:".editor-modal-imagechoices",position:function(t,o,a){e(t.$trigger).addClass("is-contextopen");var n=e(t.$trigger).position(),i={w:e(t.$trigger).width()/2,h:e(t.$trigger).height()/2};t.$menu.css({top:n.top+i.h,left:n.left+i.w})},events:{hide:function(t){e(t.$trigger).removeClass("is-contextopen")}},items:{rename:{name:"Rename",icon:"fa-edit",callback:function(e,t){alert("Clicked on "+e)}},move:{name:"Move to...",icon:"fa-folder-open-o",items:t},delete:{name:"Delete",icon:"fa-trash",callback:function(t,o){i.deleteImageId=_.toString(e(o.$trigger).data("uid")),i.deleteImageWarn(!0)}}}})},deleteImageWarn:function(e){e&&(i.deleteImageFilename=_.find(i.images,["_id",i.deleteImageId]).filename),i.deleteImageShow=e},deleteImageGo:function(){i.deleteImageWarn(!1),i.isLoadingText="Deleting image...",i.isLoading=!0,Vue.nextTick(function(){o.emit("uploadsDeleteFile",{uid:i.deleteImageId},function(e){i.loadImages()})})},waitUploadComplete:function(){i.postUploadChecks++,i.isLoadingText="Processing...";var e=i.images.length;i.loadImages(!0),Vue.nextTick(function(){_.delay(function(){e!==i.images.length?(i.postUploadChecks=0,i.isLoading=!1):i.postUploadChecks>5?(i.postUploadChecks=0,i.isLoading=!1,t.pushError("Unable to fetch new listing","Try again later")):i.waitUploadComplete()},2e3)})}}});e("#btn-editor-uploadimage input").on("change",function(o){e(o.currentTarget).simpleUpload("/uploads/img",{name:"imgfile",data:{folder:i.currentFolder},limit:20,expect:"json",allowedExts:["jpg","jpeg","gif","png","webp"],allowedTypes:["image/png","image/jpeg","image/gif","image/webp"],maxFileSize:3145728,init:function(e){i.uploadSucceeded=!1,i.isLoading=!0,i.isLoadingText="Preparing to upload..."},progress:function(e){i.isLoadingText="Uploading..."+Math.round(e)+"%"},success:function(e){if(e.ok){var o=_.filter(e.results,["ok",!1]);o.length?(_.forEach(o,function(e){t.pushError("Upload error",e.msg)}),o.length<e.results.length&&(t.push({title:"Some uploads succeeded",message:"Files that are not mentionned in the errors above were uploaded successfully."}),i.uploadSucceeded=!0)):i.uploadSucceeded=!0}else t.pushError("Upload error",e.msg)},error:function(e){t.pushError(e.message,this.upload.file.name)},finish:function(){i.uploadSucceeded?i.waitUploadComplete():i.isLoading=!1}})});var r=ace.edit("codeblock-editor");r.setTheme("ace/theme/tomorrow_night"),r.getSession().setMode("ace/mode/markdown"),r.setOption("fontSize","14px"),r.setOption("hScrollBarAlwaysVisible",!1),r.setOption("wrap",!0);var l=ace.require("ace/ext/modelist"),c=new Vue({el:"#modal-editor-codeblock",data:{modes:l.modesByName,modeSelected:"text"},watch:{modeSelected:function(e,t){d(e).done(function(){ace.require("ace/mode/"+e),r.getSession().setMode("ace/mode/"+e)})}},methods:{cancel:function(t){a=!1,e("#modal-editor-codeblock").slideUp()},insertCode:function(e){n.codemirror.doc.somethingSelected()&&n.codemirror.execCommand("singleSelection");var t="\n```"+c.modeSelected+"\n"+r.getValue()+"\n```\n";n.codemirror.doc.replaceSelection(t),c.cancel()}}}),s=[],d=function(t){return e.ajax({url:"/js/ace/mode-"+t+".js",dataType:"script",cache:!0,beforeSend:function(){if(_.includes(s,t))return!1},success:function(){s.push(t)}})};n=new SimpleMDE({autofocus:!0,autoDownloadFontAwesome:!1,element:e("#mk-editor").get(0),placeholder:"Enter Markdown formatted content here...",spellChecker:!1,status:!1,toolbar:[{name:"bold",action:SimpleMDE.toggleBold,className:"fa fa-bold",title:"Bold"},{name:"italic",action:SimpleMDE.toggleItalic,className:"fa fa-italic",title:"Italic"},{name:"strikethrough",action:SimpleMDE.toggleStrikethrough,className:"fa fa-strikethrough",title:"Strikethrough"},"|",{name:"heading-1",action:SimpleMDE.toggleHeading1,className:"fa fa-header fa-header-x fa-header-1",title:"Big Heading"},{name:"heading-2",action:SimpleMDE.toggleHeading2,className:"fa fa-header fa-header-x fa-header-2",title:"Medium Heading"},{name:"heading-3",action:SimpleMDE.toggleHeading3,className:"fa fa-header fa-header-x fa-header-3",title:"Small Heading"},{name:"quote",action:SimpleMDE.toggleBlockquote,className:"fa fa-quote-left",title:"Quote"},"|",{name:"unordered-list",action:SimpleMDE.toggleUnorderedList,className:"fa fa-list-ul",title:"Bullet List"},{name:"ordered-list",action:SimpleMDE.toggleOrderedList,className:"fa fa-list-ol",title:"Numbered List"},"|",{name:"link",action:function(t){a||(a=!0,e("#modal-editor-link").slideToggle())},className:"fa fa-link",title:"Insert Link"},{name:"image",action:function(e){a||i.open()},className:"fa fa-image",title:"Insert Image"},{name:"file",action:function(e){},className:"fa fa-file-text-o",title:"Insert File"},"|",{name:"inline-code",action:function(e){if(!e.codemirror.doc.somethingSelected())return t.pushError("Invalid selection","You must select at least 1 character first.");var o=e.codemirror.doc.getSelections();o=_.map(o,function(e){return"`"+e+"`"}),e.codemirror.doc.replaceSelections(o)},className:"fa fa-terminal",title:"Inline Code"},{name:"code-block",action:function(t){a||(a=!0,n.codemirror.doc.somethingSelected()?r.setValue(n.codemirror.doc.getSelection()):r.setValue(""),e("#modal-editor-codeblock").slideDown(400,function(){r.resize(),r.focus()}))},className:"fa fa-code",title:"Code Block"},"|",{name:"table",action:function(e){},className:"fa fa-table",title:"Insert Table"},{name:"horizontal-rule",action:SimpleMDE.drawHorizontalRule,className:"fa fa-minus",title:"Horizontal Rule"}],shortcuts:{toggleBlockquote:null,toggleFullScreen:null}})}(),e(".btn-edit-save, .btn-create-save").on("click",function(o){e.ajax(window.location.href,{data:{markdown:n.value()},dataType:"json",method:"PUT"}).then(function(e,o,n){e.ok?window.location.assign("/"+a):t.pushError("Something went wrong",e.error)},function(e,o,a){t.pushError("Something went wrong","Save operation failed.")})})}()}if(e("#page-type-source").length){var i;!function(){i=ace.edit("source-display"),i.setTheme("ace/theme/tomorrow_night"),i.getSession().setMode("ace/mode/markdown"),i.setReadOnly(!0),i.renderer.updateFull();var o="home"!==e("#page-type-source").data("entrypath")?e("#page-type-source").data("entrypath"):"",a=o+"/new-page";e(".btn-create-prompt").on("click",function(t){e("#txt-create-prompt").val(a),e("#modal-create-prompt").toggleClass("is-active"),setInputSelection(e("#txt-create-prompt").get(0),o.length+1,a.length),e("#txt-create-prompt").removeClass("is-danger").next().addClass("is-hidden")}),e("#txt-create-prompt").on("keypress",function(t){13===t.which&&e(".btn-create-go").trigger("click")}),e(".btn-create-go").on("click",function(t){var o=makeSafePath(e("#txt-create-prompt").val());_.isEmpty(o)?e("#txt-create-prompt").addClass("is-danger").next().removeClass("is-hidden"):(e("#txt-create-prompt").parent().addClass("is-loading"),window.location.assign("/create/"+o))}),""!==o&&e(".btn-move-prompt").removeClass("is-hidden");var n=_.lastIndexOf(o,"/")+1;e(".btn-move-prompt").on("click",function(t){e("#txt-move-prompt").val(o),e("#modal-move-prompt").toggleClass("is-active"),setInputSelection(e("#txt-move-prompt").get(0),n,o.length),e("#txt-move-prompt").removeClass("is-danger").next().addClass("is-hidden")}),e("#txt-move-prompt").on("keypress",function(t){13===t.which&&e(".btn-move-go").trigger("click")}),e(".btn-move-go").on("click",function(a){var n=makeSafePath(e("#txt-move-prompt").val());_.isEmpty(n)||n===o||"home"===n?e("#txt-move-prompt").addClass("is-danger").next().removeClass("is-hidden"):(e("#txt-move-prompt").parent().addClass("is-loading"),e.ajax(window.location.href,{data:{move:n},dataType:"json",method:"PUT"}).then(function(e,o,a){e.ok?window.location.assign("/"+n):t.pushError("Something went wrong",e.error)},function(e,o,a){t.pushError("Something went wrong","Save operation failed.")}))})}()}});var Alerts=function(){function e(){_classCallCheck(this,e);var t=this;t.mdl=new Vue({el:"#alerts",data:{children:[]},methods:{acknowledge:function(e){t.close(e)}}}),t.uidNext=1}return _createClass(e,[{key:"push",value:function(e){var t=this,o=_.defaults(e,{_uid:t.uidNext,class:"is-info",message:"---",sticky:!1,title:"---"});t.mdl.children.push(o),o.sticky||_.delay(function(){t.close(o._uid)},5e3),t.uidNext++}},{key:"pushError",value:function(e,t){this.push({class:"is-danger",message:t,sticky:!1,title:e})}},{key:"pushSuccess",value:function(e,t){this.push({class:"is-success",message:t,sticky:!1,title:e})}},{key:"close",value:function(e){var t=this,o=_.findIndex(t.mdl.children,["_uid",e]),a=_.nth(t.mdl.children,o);o>=0&&a&&(a.class+=" exit",Vue.set(t.mdl.children,o,a),_.delay(function(){t.mdl.children.splice(o,1)},500))}}]),e}();
\ No newline at end of file
......@@ -15,7 +15,10 @@ let vueImage = new Vue({
currentAlign: 'left',
images: [],
uploadSucceeded: false,
postUploadChecks: 0
postUploadChecks: 0,
deleteImageShow: false,
deleteImageId: 0,
deleteImageFilename: ''
},
methods: {
open: () => {
......@@ -33,8 +36,8 @@ let vueImage = new Vue({
mde.codemirror.execCommand('singleSelection');
}
let selImage = _.find(vueImage.images, ['uid', vueImage.currentImage]);
selImage.normalizedPath = (selImage.folder === '') ? selImage.filename : selImage.folder + '/' + selImage.filename;
let selImage = _.find(vueImage.images, ['_id', vueImage.currentImage]);
selImage.normalizedPath = (selImage.folder === 'f:') ? selImage.filename : selImage.folder.slice(2) + '/' + selImage.filename;
selImage.titleGuess = _.startCase(selImage.basename);
let imageText = '![' + selImage.titleGuess + '](/uploads/' + selImage.normalizedPath + ' "' + selImage.titleGuess + '")';
......@@ -93,6 +96,9 @@ let vueImage = new Vue({
fetchFromUrlDiscard: (ev) => {
vueImage.fetchFromUrlShow = false;
},
fetchFromUrlFetch: (ev) => {
},
/**
* Select a folder
......@@ -210,17 +216,36 @@ let vueImage = new Vue({
name: "Delete",
icon: "fa-trash",
callback: (key, opt) => {
alert("Clicked on " + key);
vueImage.deleteImageId = _.toString($(opt.$trigger).data('uid'));
vueImage.deleteImageWarn(true);
}
}
}
});
},
deleteImageWarn: (show) => {
if(show) {
vueImage.deleteImageFilename = _.find(vueImage.images, ['_id', vueImage.deleteImageId ]).filename;
}
vueImage.deleteImageShow = show;
},
deleteImageGo: () => {
vueImage.deleteImageWarn(false);
vueImage.isLoadingText = 'Deleting image...';
vueImage.isLoading = true;
Vue.nextTick(() => {
socket.emit('uploadsDeleteFile', { uid: vueImage.deleteImageId }, (data) => {
vueImage.loadImages();
});
});
},
waitUploadComplete: () => {
vueImage.postUploadChecks++;
vueImage.isLoadingText = 'Processing uploads...';
vueImage.isLoadingText = 'Processing...';
let currentUplAmount = vueImage.images.length;
vueImage.loadImages(true);
......@@ -233,7 +258,7 @@ let vueImage = new Vue({
} else if(vueImage.postUploadChecks > 5) {
vueImage.postUploadChecks = 0;
vueImage.isLoading = false;
alerts.pushError('Unable to fetch new uploads', 'Try again later');
alerts.pushError('Unable to fetch new listing', 'Try again later');
} else {
vueImage.waitUploadComplete();
}
......
"use strict";
jQuery( document ).ready(function( $ ) {
if($('#search-input').length) {
if($('#search-input').length) {
$('#search-input').focus();
$('#search-input').focus();
$('.searchresults').css('display', 'block');
$('.searchresults').css('display', 'block');
var vueHeader = new Vue({
el: '#header-container',
data: {
searchq: '',
searchres: [],
searchsuggest: [],
searchload: 0,
searchactive: false,
searchmoveidx: 0,
searchmovekey: '',
searchmovearr: []
var vueHeader = new Vue({
el: '#header-container',
data: {
searchq: '',
searchres: [],
searchsuggest: [],
searchload: 0,
searchactive: false,
searchmoveidx: 0,
searchmovekey: '',
searchmovearr: []
},
watch: {
searchq: (val, oldVal) => {
vueHeader.searchmoveidx = 0;
if(val.length >= 3) {
vueHeader.searchactive = true;
vueHeader.searchload++;
socket.emit('search', { terms: val }, (data) => {
vueHeader.searchres = data.match;
vueHeader.searchsuggest = data.suggest;
vueHeader.searchmovearr = _.concat([], vueHeader.searchres, vueHeader.searchsuggest);
if(vueHeader.searchload > 0) { vueHeader.searchload--; }
});
} else {
vueHeader.searchactive = false;
vueHeader.searchres = [];
vueHeader.searchsuggest = [];
vueHeader.searchmovearr = [];
vueHeader.searchload = 0;
}
},
watch: {
searchq: (val, oldVal) => {
vueHeader.searchmoveidx = 0;
if(val.length >= 3) {
vueHeader.searchactive = true;
vueHeader.searchload++;
socket.emit('search', { terms: val }, (data) => {
vueHeader.searchres = data.match;
vueHeader.searchsuggest = data.suggest;
vueHeader.searchmovearr = _.concat([], vueHeader.searchres, vueHeader.searchsuggest);
if(vueHeader.searchload > 0) { vueHeader.searchload--; }
});
} else {
vueHeader.searchactive = false;
vueHeader.searchres = [];
vueHeader.searchsuggest = [];
vueHeader.searchmovearr = [];
vueHeader.searchload = 0;
}
},
searchmoveidx: (val, oldVal) => {
if(val > 0) {
vueHeader.searchmovekey = (vueHeader.searchmovearr[val - 1]) ?
'res.' + vueHeader.searchmovearr[val - 1]._id :
'sug.' + vueHeader.searchmovearr[val - 1];
} else {
vueHeader.searchmovekey = '';
}
searchmoveidx: (val, oldVal) => {
if(val > 0) {
vueHeader.searchmovekey = (vueHeader.searchmovearr[val - 1]) ?
'res.' + vueHeader.searchmovearr[val - 1]._id :
'sug.' + vueHeader.searchmovearr[val - 1];
} else {
vueHeader.searchmovekey = '';
}
}
},
methods: {
useSuggestion: (sug) => {
vueHeader.searchq = sug;
},
methods: {
useSuggestion: (sug) => {
vueHeader.searchq = sug;
},
closeSearch: () => {
vueHeader.searchq = '';
},
moveSelectSearch: () => {
if(vueHeader.searchmoveidx < 1) { return; }
let i = vueHeader.searchmoveidx - 1;
closeSearch: () => {
vueHeader.searchq = '';
},
moveSelectSearch: () => {
if(vueHeader.searchmoveidx < 1) { return; }
let i = vueHeader.searchmoveidx - 1;
if(vueHeader.searchmovearr[i]) {
window.location.assign('/' + vueHeader.searchmovearr[i]._id);
} else {
vueHeader.searchq = vueHeader.searchmovearr[i];
}
if(vueHeader.searchmovearr[i]) {
window.location.assign('/' + vueHeader.searchmovearr[i]._id);
} else {
vueHeader.searchq = vueHeader.searchmovearr[i];
}
},
moveDownSearch: () => {
if(vueHeader.searchmoveidx < vueHeader.searchmovearr.length) {
vueHeader.searchmoveidx++;
}
},
moveUpSearch: () => {
if(vueHeader.searchmoveidx > 0) {
vueHeader.searchmoveidx--;
}
},
moveDownSearch: () => {
if(vueHeader.searchmoveidx < vueHeader.searchmovearr.length) {
vueHeader.searchmoveidx++;
}
},
moveUpSearch: () => {
if(vueHeader.searchmoveidx > 0) {
vueHeader.searchmoveidx--;
}
}
});
$('main').on('click', vueHeader.closeSearch);
}
});
}
$('main').on('click', vueHeader.closeSearch);
});
\ No newline at end of file
}
\ No newline at end of file
......@@ -24,13 +24,6 @@ host: http://localhost
port: 80
# ---------------------------------------------------------------------
# Port the websocket server should listen to (8080 by default)
# ---------------------------------------------------------------------
# Make sure this port is opened in the firewall if applicable
wsPort: 8080
# ---------------------------------------------------------------------
# Data Directories
# ---------------------------------------------------------------------
......
......@@ -24,10 +24,11 @@ router.get('/edit/*', (req, res, next) => {
cache: false
}).then((pageData) => {
if(pageData) {
return res.render('pages/edit', { pageData });
res.render('pages/edit', { pageData });
} else {
throw new Error('Invalid page path.');
}
return true;
}).catch((err) => {
res.render('error', {
message: err.message,
......@@ -158,12 +159,13 @@ router.get('/*', (req, res, next) => {
entries.fetch(safePath).then((pageData) => {
if(pageData) {
return res.render('pages/view', { pageData });
res.render('pages/view', { pageData });
} else {
res.render('error-notexist', {
newpath: safePath
});
}
return true;
}).error((err) => {
res.render('error-notexist', {
message: err.message,
......
......@@ -41,10 +41,7 @@ router.post('/img', lcdata.uploadImgHandler, (req, res, next) => {
let destFolder = _.chain(req.body.folder).trim().toLower().value();
ws.emit('uploadsValidateFolder', {
auth: WSInternalKey,
content: destFolder
}, (destFolderPath) => {
upl.validateUploadsFolder(destFolder).then((destFolderPath) => {
if(!destFolderPath) {
return res.json({ ok: false, msg: 'Invalid Folder' });
......
"use strict";
module.exports = (socket) => {
//-----------------------------------------
// SEARCH
//-----------------------------------------
socket.on('search', (data, cb) => {
cb = cb || _.noop;
entries.search(data.terms).then((results) => {
cb(results);
});
});
//-----------------------------------------
// UPLOADS
//-----------------------------------------
socket.on('uploadsGetFolders', (data, cb) => {
cb = cb || _.noop;
upl.getUploadsFolders().then((f) => {
cb(f);
})
});
socket.on('uploadsCreateFolder', (data, cb) => {
cb = cb || _.noop;
upl.createUploadsFolder(data.foldername).then((f) => {
cb(f);
});
});
socket.on('uploadsGetImages', (data, cb) => {
cb = cb || _.noop;
upl.getUploadsFiles('image', data.folder).then((f) => {
cb(f);
});
});
socket.on('uploadsDeleteFile', (data, cb) => {
cb = cb || _.noop;
upl.deleteUploadsFile(data.uid).then((f) => {
cb(f);
});
});
};
\ No newline at end of file
[
{
"mime": "application/vnd.hzn-3d-crossword",
"name": "3D Crossword Plugin",
"ext": ".x3d"
},
{
"mime": "video/3gpp",
"name": "3GP",
"ext": ".3gp"
},
{
"mime": "video/3gpp2",
"name": "3GP2",
"ext": ".3g2"
},
{
"mime": "application/vnd.mseq",
"name": "3GPP MSEQ File",
"ext": ".mseq"
},
{
"mime": "application/vnd.3m.post-it-notes",
"name": "3M Post It Notes",
"ext": ".pwn"
},
{
"mime": "application/vnd.3gpp.pic-bw-large",
"name": "3rd Generation Partnership Project - Pic Large",
"ext": ".plb"
},
{
"mime": "application/vnd.3gpp.pic-bw-small",
"name": "3rd Generation Partnership Project - Pic Small",
"ext": ".psb"
},
{
"mime": "application/vnd.3gpp.pic-bw-var",
"name": "3rd Generation Partnership Project - Pic Var",
"ext": ".pvb"
},
{
"mime": "application/vnd.3gpp2.tcap",
"name": "3rd Generation Partnership Project - Transaction Capabilities Application Part",
"ext": ".tcap"
},
{
"mime": "application/x-7z-compressed",
"name": "7-Zip",
"ext": ".7z"
},
{
"mime": "application/x-abiword",
"name": "AbiWord",
"ext": ".abw"
},
{
"mime": "application/x-ace-compressed",
"name": "Ace Archive",
"ext": ".ace"
},
{
"mime": "application/vnd.americandynamics.acc",
"name": "Active Content Compression",
"ext": ".acc"
},
{
"mime": "application/vnd.acucobol",
"name": "ACU Cobol",
"ext": ".acu"
},
{
"mime": "application/vnd.acucorp",
"name": "ACU Cobol",
"ext": ".atc"
},
{
"mime": "audio/adpcm",
"name": "Adaptive differential pulse-code modulation",
"ext": ".adp"
},
{
"mime": "application/x-authorware-bin",
"name": "Adobe (Macropedia) Authorware - Binary File",
"ext": ".aab"
},
{
"mime": "application/x-authorware-map",
"name": "Adobe (Macropedia) Authorware - Map",
"ext": ".aam"
},
{
"mime": "application/x-authorware-seg",
"name": "Adobe (Macropedia) Authorware - Segment File",
"ext": ".aas"
},
{
"mime": "application/vnd.adobe.air-application-installer-package+zip",
"name": "Adobe AIR Application",
"ext": ".air"
},
{
"mime": "application/x-shockwave-flash",
"name": "Adobe Flash",
"ext": ".swf"
},
{
"mime": "application/vnd.adobe.fxp",
"name": "Adobe Flex Project",
"ext": ".fxp"
},
{
"mime": "application/pdf",
"name": "Adobe Portable Document Format",
"ext": ".pdf"
},
{
"mime": "application/vnd.cups-ppd",
"name": "Adobe PostScript Printer Description File Format",
"ext": ".ppd"
},
{
"mime": "application/x-director",
"name": "Adobe Shockwave Player",
"ext": ".dir"
},
{
"mime": "application/vnd.adobe.xdp+xml",
"name": "Adobe XML Data Package",
"ext": ".xdp"
},
{
"mime": "application/vnd.adobe.xfdf",
"name": "Adobe XML Forms Data Format",
"ext": ".xfdf"
},
{
"mime": "audio/x-aac",
"name": "Advanced Audio Coding (AAC)",
"ext": ".aac"
},
{
"mime": "application/vnd.ahead.space",
"name": "Ahead AIR Application",
"ext": ".ahead"
},
{
"mime": "application/vnd.airzip.filesecure.azf",
"name": "AirZip FileSECURE",
"ext": ".azf"
},
{
"mime": "application/vnd.airzip.filesecure.azs",
"name": "AirZip FileSECURE",
"ext": ".azs"
},
{
"mime": "application/vnd.amazon.ebook",
"name": "Amazon Kindle eBook format",
"ext": ".azw"
},
{
"mime": "application/vnd.amiga.ami",
"name": "AmigaDE",
"ext": ".ami"
},
{
"mime": "application/andrew-inset",
"name": "Andrew Toolkit",
"ext": "N/A"
},
{
"mime": "application/vnd.android.package-archive",
"name": "Android Package Archive",
"ext": ".apk"
},
{
"mime": "application/vnd.anser-web-certificate-issue-initiation",
"name": "ANSER-WEB Terminal Client - Certificate Issue",
"ext": ".cii"
},
{
"mime": "application/vnd.anser-web-funds-transfer-initiation",
"name": "ANSER-WEB Terminal Client - Web Funds Transfer",
"ext": ".fti"
},
{
"mime": "application/vnd.antix.game-component",
"name": "Antix Game Player",
"ext": ".atx"
},
{
"mime": "application/vnd.apple.installer+xml",
"name": "Apple Installer Package",
"ext": ".mpkg"
},
{
"mime": "application/applixware",
"name": "Applixware",
"ext": ".aw"
},
{
"mime": "application/vnd.hhe.lesson-player",
"name": "Archipelago Lesson Player",
"ext": ".les"
},
{
"mime": "application/vnd.aristanetworks.swi",
"name": "Arista Networks Software Image",
"ext": ".swi"
},
{
"mime": "text/x-asm",
"name": "Assembler Source File",
"ext": ".s"
},
{
"mime": "application/atomcat+xml",
"name": "Atom Publishing Protocol",
"ext": ".atomcat"
},
{
"mime": "application/atomsvc+xml",
"name": "Atom Publishing Protocol Service Document",
"ext": ".atomsvc"
},
{
"mime": "application/atom+xml",
"name": "Atom Syndication Format",
"ext": ".atom, .xml"
},
{
"mime": "application/pkix-attr-cert",
"name": "Attribute Certificate",
"ext": ".ac"
},
{
"mime": "audio/x-aiff",
"name": "Audio Interchange File Format",
"ext": ".aif"
},
{
"mime": "video/x-msvideo",
"name": "Audio Video Interleave (AVI)",
"ext": ".avi"
},
{
"mime": "application/vnd.audiograph",
"name": "Audiograph",
"ext": ".aep"
},
{
"mime": "image/vnd.dxf",
"name": "AutoCAD DXF",
"ext": ".dxf"
},
{
"mime": "model/vnd.dwf",
"name": "Autodesk Design Web Format (DWF)",
"ext": ".dwf"
},
{
"mime": "text/plain-bas",
"name": "BAS Partitur Format",
"ext": ".par"
},
{
"mime": "application/x-bcpio",
"name": "Binary CPIO Archive",
"ext": ".bcpio"
},
{
"mime": "application/octet-stream",
"name": "Binary Data",
"ext": ".bin"
},
{
"mime": "image/bmp",
"name": "Bitmap Image File",
"ext": ".bmp"
},
{
"mime": "application/x-bittorrent",
"name": "BitTorrent",
"ext": ".torrent"
},
{
"mime": "application/vnd.rim.cod",
"name": "Blackberry COD File",
"ext": ".cod"
},
{
"mime": "application/vnd.blueice.multipass",
"name": "Blueice Research Multipass",
"ext": ".mpm"
},
{
"mime": "application/vnd.bmi",
"name": "BMI Drawing Data Interchange",
"ext": ".bmi"
},
{
"mime": "application/x-sh",
"name": "Bourne Shell Script",
"ext": ".sh"
},
{
"mime": "image/prs.btif",
"name": "BTIF",
"ext": ".btif"
},
{
"mime": "application/vnd.businessobjects",
"name": "BusinessObjects",
"ext": ".rep"
},
{
"mime": "application/x-bzip",
"name": "Bzip Archive",
"ext": ".bz"
},
{
"mime": "application/x-bzip2",
"name": "Bzip2 Archive",
"ext": ".bz2"
},
{
"mime": "application/x-csh",
"name": "C Shell Script",
"ext": ".csh"
},
{
"mime": "text/x-c",
"name": "C Source File",
"ext": ".c"
},
{
"mime": "application/vnd.chemdraw+xml",
"name": "CambridgeSoft Chem Draw",
"ext": ".cdxml"
},
{
"mime": "text/css",
"name": "Cascading Style Sheets (CSS)",
"ext": ".css"
},
{
"mime": "chemical/x-cdx",
"name": "ChemDraw eXchange file",
"ext": ".cdx"
},
{
"mime": "chemical/x-cml",
"name": "Chemical Markup Language",
"ext": ".cml"
},
{
"mime": "chemical/x-csml",
"name": "Chemical Style Markup Language",
"ext": ".csml"
},
{
"mime": "application/vnd.contact.cmsg",
"name": "CIM Database",
"ext": ".cdbcmsg"
},
{
"mime": "application/vnd.claymore",
"name": "Claymore Data Files",
"ext": ".cla"
},
{
"mime": "application/vnd.clonk.c4group",
"name": "Clonk Game",
"ext": ".c4g"
},
{
"mime": "image/vnd.dvb.subtitle",
"name": "Close Captioning - Subtitle",
"ext": ".sub"
},
{
"mime": "application/cdmi-capability",
"name": "Cloud Data Management Interface (CDMI) - Capability",
"ext": ".cdmia"
},
{
"mime": "application/cdmi-container",
"name": "Cloud Data Management Interface (CDMI) - Contaimer",
"ext": ".cdmic"
},
{
"mime": "application/cdmi-domain",
"name": "Cloud Data Management Interface (CDMI) - Domain",
"ext": ".cdmid"
},
{
"mime": "application/cdmi-object",
"name": "Cloud Data Management Interface (CDMI) - Object",
"ext": ".cdmio"
},
{
"mime": "application/cdmi-queue",
"name": "Cloud Data Management Interface (CDMI) - Queue",
"ext": ".cdmiq"
},
{
"mime": "application/vnd.cluetrust.cartomobile-config",
"name": "ClueTrust CartoMobile - Config",
"ext": ".c11amc"
},
{
"mime": "application/vnd.cluetrust.cartomobile-config-pkg",
"name": "ClueTrust CartoMobile - Config Package",
"ext": ".c11amz"
},
{
"mime": "image/x-cmu-raster",
"name": "CMU Image",
"ext": ".ras"
},
{
"mime": "model/vnd.collada+xml",
"name": "COLLADA",
"ext": ".dae"
},
{
"mime": "text/csv",
"name": "Comma-Separated Values",
"ext": ".csv"
},
{
"mime": "application/mac-compactpro",
"name": "Compact Pro",
"ext": ".cpt"
},
{
"mime": "application/vnd.wap.wmlc",
"name": "Compiled Wireless Markup Language (WMLC)",
"ext": ".wmlc"
},
{
"mime": "image/cgm",
"name": "Computer Graphics Metafile",
"ext": ".cgm"
},
{
"mime": "x-conference/x-cooltalk",
"name": "CoolTalk",
"ext": ".ice"
},
{
"mime": "image/x-cmx",
"name": "Corel Metafile Exchange (CMX)",
"ext": ".cmx"
},
{
"mime": "application/vnd.xara",
"name": "CorelXARA",
"ext": ".xar"
},
{
"mime": "application/vnd.cosmocaller",
"name": "CosmoCaller",
"ext": ".cmc"
},
{
"mime": "application/x-cpio",
"name": "CPIO Archive",
"ext": ".cpio"
},
{
"mime": "application/vnd.crick.clicker",
"name": "CrickSoftware - Clicker",
"ext": ".clkx"
},
{
"mime": "application/vnd.crick.clicker.keyboard",
"name": "CrickSoftware - Clicker - Keyboard",
"ext": ".clkk"
},
{
"mime": "application/vnd.crick.clicker.palette",
"name": "CrickSoftware - Clicker - Palette",
"ext": ".clkp"
},
{
"mime": "application/vnd.crick.clicker.template",
"name": "CrickSoftware - Clicker - Template",
"ext": ".clkt"
},
{
"mime": "application/vnd.crick.clicker.wordbank",
"name": "CrickSoftware - Clicker - Wordbank",
"ext": ".clkw"
},
{
"mime": "application/vnd.criticaltools.wbs+xml",
"name": "Critical Tools - PERT Chart EXPERT",
"ext": ".wbs"
},
{
"mime": "application/vnd.rig.cryptonote",
"name": "CryptoNote",
"ext": ".cryptonote"
},
{
"mime": "chemical/x-cif",
"name": "Crystallographic Interchange Format",
"ext": ".cif"
},
{
"mime": "chemical/x-cmdf",
"name": "CrystalMaker Data Format",
"ext": ".cmdf"
},
{
"mime": "application/cu-seeme",
"name": "CU-SeeMe",
"ext": ".cu"
},
{
"mime": "application/prs.cww",
"name": "CU-Writer",
"ext": ".cww"
},
{
"mime": "text/vnd.curl",
"name": "Curl - Applet",
"ext": ".curl"
},
{
"mime": "text/vnd.curl.dcurl",
"name": "Curl - Detached Applet",
"ext": ".dcurl"
},
{
"mime": "text/vnd.curl.mcurl",
"name": "Curl - Manifest File",
"ext": ".mcurl"
},
{
"mime": "text/vnd.curl.scurl",
"name": "Curl - Source Code",
"ext": ".scurl"
},
{
"mime": "application/vnd.curl.car",
"name": "CURL Applet",
"ext": ".car"
},
{
"mime": "application/vnd.curl.pcurl",
"name": "CURL Applet",
"ext": ".pcurl"
},
{
"mime": "application/vnd.yellowriver-custom-menu",
"name": "CustomMenu",
"ext": ".cmp"
},
{
"mime": "application/dssc+der",
"name": "Data Structure for the Security Suitability of Cryptographic Algorithms",
"ext": ".dssc"
},
{
"mime": "application/dssc+xml",
"name": "Data Structure for the Security Suitability of Cryptographic Algorithms",
"ext": ".xdssc"
},
{
"mime": "application/x-debian-package",
"name": "Debian Package",
"ext": ".deb"
},
{
"mime": "audio/vnd.dece.audio",
"name": "DECE Audio",
"ext": ".uva"
},
{
"mime": "image/vnd.dece.graphic",
"name": "DECE Graphic",
"ext": ".uvi"
},
{
"mime": "video/vnd.dece.hd",
"name": "DECE High Definition Video",
"ext": ".uvh"
},
{
"mime": "video/vnd.dece.mobile",
"name": "DECE Mobile Video",
"ext": ".uvm"
},
{
"mime": "video/vnd.uvvu.mp4",
"name": "DECE MP4",
"ext": ".uvu"
},
{
"mime": "video/vnd.dece.pd",
"name": "DECE PD Video",
"ext": ".uvp"
},
{
"mime": "video/vnd.dece.sd",
"name": "DECE SD Video",
"ext": ".uvs"
},
{
"mime": "video/vnd.dece.video",
"name": "DECE Video",
"ext": ".uvv"
},
{
"mime": "application/x-dvi",
"name": "Device Independent File Format (DVI)",
"ext": ".dvi"
},
{
"mime": "application/vnd.fdsn.seed",
"name": "Digital Siesmograph Networks - SEED Datafiles",
"ext": ".seed"
},
{
"mime": "application/x-dtbook+xml",
"name": "Digital Talking Book",
"ext": ".dtb"
},
{
"mime": "application/x-dtbresource+xml",
"name": "Digital Talking Book - Resource File",
"ext": ".res"
},
{
"mime": "application/vnd.dvb.ait",
"name": "Digital Video Broadcasting",
"ext": ".ait"
},
{
"mime": "application/vnd.dvb.service",
"name": "Digital Video Broadcasting",
"ext": ".svc"
},
{
"mime": "audio/vnd.digital-winds",
"name": "Digital Winds Music",
"ext": ".eol"
},
{
"mime": "image/vnd.djvu",
"name": "DjVu",
"ext": ".djvu"
},
{
"mime": "application/xml-dtd",
"name": "Document Type Definition",
"ext": ".dtd"
},
{
"mime": "application/vnd.dolby.mlp",
"name": "Dolby Meridian Lossless Packing",
"ext": ".mlp"
},
{
"mime": "application/x-doom",
"name": "Doom Video Game",
"ext": ".wad"
},
{
"mime": "application/vnd.dpgraph",
"name": "DPGraph",
"ext": ".dpg"
},
{
"mime": "audio/vnd.dra",
"name": "DRA Audio",
"ext": ".dra"
},
{
"mime": "application/vnd.dreamfactory",
"name": "DreamFactory",
"ext": ".dfac"
},
{
"mime": "audio/vnd.dts",
"name": "DTS Audio",
"ext": ".dts"
},
{
"mime": "audio/vnd.dts.hd",
"name": "DTS High Definition Audio",
"ext": ".dtshd"
},
{
"mime": "image/vnd.dwg",
"name": "DWG Drawing",
"ext": ".dwg"
},
{
"mime": "application/vnd.dynageo",
"name": "DynaGeo",
"ext": ".geo"
},
{
"mime": "application/ecmascript",
"name": "ECMAScript",
"ext": ".es"
},
{
"mime": "application/vnd.ecowin.chart",
"name": "EcoWin Chart",
"ext": ".mag"
},
{
"mime": "image/vnd.fujixerox.edmics-mmr",
"name": "EDMICS 2000",
"ext": ".mmr"
},
{
"mime": "image/vnd.fujixerox.edmics-rlc",
"name": "EDMICS 2000",
"ext": ".rlc"
},
{
"mime": "application/exi",
"name": "Efficient XML Interchange",
"ext": ".exi"
},
{
"mime": "application/vnd.proteus.magazine",
"name": "EFI Proteus",
"ext": ".mgz"
},
{
"mime": "application/epub+zip",
"name": "Electronic Publication",
"ext": ".epub"
},
{
"mime": "message/rfc822",
"name": "Email Message",
"ext": ".eml"
},
{
"mime": "application/vnd.enliven",
"name": "Enliven Viewer",
"ext": ".nml"
},
{
"mime": "application/vnd.is-xpr",
"name": "Express by Infoseek",
"ext": ".xpr"
},
{
"mime": "image/vnd.xiff",
"name": "eXtended Image File Format (XIFF)",
"ext": ".xif"
},
{
"mime": "application/vnd.xfdl",
"name": "Extensible Forms Description Language",
"ext": ".xfdl"
},
{
"mime": "application/emma+xml",
"name": "Extensible MultiModal Annotation",
"ext": ".emma"
},
{
"mime": "application/vnd.ezpix-album",
"name": "EZPix Secure Photo Album",
"ext": ".ez2"
},
{
"mime": "application/vnd.ezpix-package",
"name": "EZPix Secure Photo Album",
"ext": ".ez3"
},
{
"mime": "image/vnd.fst",
"name": "FAST Search & Transfer ASA",
"ext": ".fst"
},
{
"mime": "video/vnd.fvt",
"name": "FAST Search & Transfer ASA",
"ext": ".fvt"
},
{
"mime": "image/vnd.fastbidsheet",
"name": "FastBid Sheet",
"ext": ".fbs"
},
{
"mime": "application/vnd.denovo.fcselayout-link",
"name": "FCS Express Layout Link",
"ext": ".fe_launch"
},
{
"mime": "video/x-f4v",
"name": "Flash Video",
"ext": ".f4v"
},
{
"mime": "video/x-flv",
"name": "Flash Video",
"ext": ".flv"
},
{
"mime": "image/vnd.fpx",
"name": "FlashPix",
"ext": ".fpx"
},
{
"mime": "image/vnd.net-fpx",
"name": "FlashPix",
"ext": ".npx"
},
{
"mime": "text/vnd.fmi.flexstor",
"name": "FLEXSTOR",
"ext": ".flx"
},
{
"mime": "video/x-fli",
"name": "FLI/FLC Animation Format",
"ext": ".fli"
},
{
"mime": "application/vnd.fluxtime.clip",
"name": "FluxTime Clip",
"ext": ".ftc"
},
{
"mime": "application/vnd.fdf",
"name": "Forms Data Format",
"ext": ".fdf"
},
{
"mime": "text/x-fortran",
"name": "Fortran Source File",
"ext": ".f"
},
{
"mime": "application/vnd.mif",
"name": "FrameMaker Interchange Format",
"ext": ".mif"
},
{
"mime": "application/vnd.framemaker",
"name": "FrameMaker Normal Format",
"ext": ".fm"
},
{
"mime": "image/x-freehand",
"name": "FreeHand MX",
"ext": ".fh"
},
{
"mime": "application/vnd.fsc.weblaunch",
"name": "Friendly Software Corporation",
"ext": ".fsc"
},
{
"mime": "application/vnd.frogans.fnc",
"name": "Frogans Player",
"ext": ".fnc"
},
{
"mime": "application/vnd.frogans.ltf",
"name": "Frogans Player",
"ext": ".ltf"
},
{
"mime": "application/vnd.fujixerox.ddd",
"name": "Fujitsu - Xerox 2D CAD Data",
"ext": ".ddd"
},
{
"mime": "application/vnd.fujixerox.docuworks",
"name": "Fujitsu - Xerox DocuWorks",
"ext": ".xdw"
},
{
"mime": "application/vnd.fujixerox.docuworks.binder",
"name": "Fujitsu - Xerox DocuWorks Binder",
"ext": ".xbd"
},
{
"mime": "application/vnd.fujitsu.oasys",
"name": "Fujitsu Oasys",
"ext": ".oas"
},
{
"mime": "application/vnd.fujitsu.oasys2",
"name": "Fujitsu Oasys",
"ext": ".oa2"
},
{
"mime": "application/vnd.fujitsu.oasys3",
"name": "Fujitsu Oasys",
"ext": ".oa3"
},
{
"mime": "application/vnd.fujitsu.oasysgp",
"name": "Fujitsu Oasys",
"ext": ".fg5"
},
{
"mime": "application/vnd.fujitsu.oasysprs",
"name": "Fujitsu Oasys",
"ext": ".bh2"
},
{
"mime": "application/x-futuresplash",
"name": "FutureSplash Animator",
"ext": ".spl"
},
{
"mime": "application/vnd.fuzzysheet",
"name": "FuzzySheet",
"ext": ".fzs"
},
{
"mime": "image/g3fax",
"name": "G3 Fax Image",
"ext": ".g3"
},
{
"mime": "application/vnd.gmx",
"name": "GameMaker ActiveX",
"ext": ".gmx"
},
{
"mime": "model/vnd.gtw",
"name": "Gen-Trix Studio",
"ext": ".gtw"
},
{
"mime": "application/vnd.genomatix.tuxedo",
"name": "Genomatix Tuxedo Framework",
"ext": ".txd"
},
{
"mime": "application/vnd.geogebra.file",
"name": "GeoGebra",
"ext": ".ggb"
},
{
"mime": "application/vnd.geogebra.tool",
"name": "GeoGebra",
"ext": ".ggt"
},
{
"mime": "model/vnd.gdl",
"name": "Geometric Description Language (GDL)",
"ext": ".gdl"
},
{
"mime": "application/vnd.geometry-explorer",
"name": "GeoMetry Explorer",
"ext": ".gex"
},
{
"mime": "application/vnd.geonext",
"name": "GEONExT and JSXGraph",
"ext": ".gxt"
},
{
"mime": "application/vnd.geoplan",
"name": "GeoplanW",
"ext": ".g2w"
},
{
"mime": "application/vnd.geospace",
"name": "GeospacW",
"ext": ".g3w"
},
{
"mime": "application/x-font-ghostscript",
"name": "Ghostscript Font",
"ext": ".gsf"
},
{
"mime": "application/x-font-bdf",
"name": "Glyph Bitmap Distribution Format",
"ext": ".bdf"
},
{
"mime": "application/x-gtar",
"name": "GNU Tar Files",
"ext": ".gtar"
},
{
"mime": "application/x-texinfo",
"name": "GNU Texinfo Document",
"ext": ".texinfo"
},
{
"mime": "application/x-gnumeric",
"name": "Gnumeric",
"ext": ".gnumeric"
},
{
"mime": "application/vnd.google-earth.kml+xml",
"name": "Google Earth - KML",
"ext": ".kml"
},
{
"mime": "application/vnd.google-earth.kmz",
"name": "Google Earth - Zipped KML",
"ext": ".kmz"
},
{
"mime": "application/vnd.grafeq",
"name": "GrafEq",
"ext": ".gqf"
},
{
"mime": "image/gif",
"name": "Graphics Interchange Format",
"ext": ".gif"
},
{
"mime": "text/vnd.graphviz",
"name": "Graphviz",
"ext": ".gv"
},
{
"mime": "application/vnd.groove-account",
"name": "Groove - Account",
"ext": ".gac"
},
{
"mime": "application/vnd.groove-help",
"name": "Groove - Help",
"ext": ".ghf"
},
{
"mime": "application/vnd.groove-identity-message",
"name": "Groove - Identity Message",
"ext": ".gim"
},
{
"mime": "application/vnd.groove-injector",
"name": "Groove - Injector",
"ext": ".grv"
},
{
"mime": "application/vnd.groove-tool-message",
"name": "Groove - Tool Message",
"ext": ".gtm"
},
{
"mime": "application/vnd.groove-tool-template",
"name": "Groove - Tool Template",
"ext": ".tpl"
},
{
"mime": "application/vnd.groove-vcard",
"name": "Groove - Vcard",
"ext": ".vcg"
},
{
"mime": "video/h261",
"name": "H.261",
"ext": ".h261"
},
{
"mime": "video/h263",
"name": "H.263",
"ext": ".h263"
},
{
"mime": "video/h264",
"name": "H.264",
"ext": ".h264"
},
{
"mime": "application/vnd.hp-hpid",
"name": "Hewlett Packard Instant Delivery",
"ext": ".hpid"
},
{
"mime": "application/vnd.hp-hps",
"name": "Hewlett-Packard's WebPrintSmart",
"ext": ".hps"
},
{
"mime": "application/x-hdf",
"name": "Hierarchical Data Format",
"ext": ".hdf"
},
{
"mime": "audio/vnd.rip",
"name": "Hit'n'Mix",
"ext": ".rip"
},
{
"mime": "application/vnd.hbci",
"name": "Homebanking Computer Interface (HBCI)",
"ext": ".hbci"
},
{
"mime": "application/vnd.hp-jlyt",
"name": "HP Indigo Digital Press - Job Layout Languate",
"ext": ".jlt"
},
{
"mime": "application/vnd.hp-pcl",
"name": "HP Printer Command Language",
"ext": ".pcl"
},
{
"mime": "application/vnd.hp-hpgl",
"name": "HP-GL/2 and HP RTL",
"ext": ".hpgl"
},
{
"mime": "application/vnd.yamaha.hv-script",
"name": "HV Script",
"ext": ".hvs"
},
{
"mime": "application/vnd.yamaha.hv-dic",
"name": "HV Voice Dictionary",
"ext": ".hvd"
},
{
"mime": "application/vnd.yamaha.hv-voice",
"name": "HV Voice Parameter",
"ext": ".hvp"
},
{
"mime": "application/vnd.hydrostatix.sof-data",
"name": "Hydrostatix Master Suite",
"ext": ".sfd-hdstx"
},
{
"mime": "application/hyperstudio",
"name": "Hyperstudio",
"ext": ".stk"
},
{
"mime": "application/vnd.hal+xml",
"name": "Hypertext Application Language",
"ext": ".hal"
},
{
"mime": "text/html",
"name": "HyperText Markup Language (HTML)",
"ext": ".html"
},
{
"mime": "application/vnd.ibm.rights-management",
"name": "IBM DB2 Rights Manager",
"ext": ".irm"
},
{
"mime": "application/vnd.ibm.secure-container",
"name": "IBM Electronic Media Management System - Secure Container",
"ext": ".sc"
},
{
"mime": "text/calendar",
"name": "iCalendar",
"ext": ".ics"
},
{
"mime": "application/vnd.iccprofile",
"name": "ICC profile",
"ext": ".icc"
},
{
"mime": "image/x-icon",
"name": "Icon Image",
"ext": ".ico"
},
{
"mime": "application/vnd.igloader",
"name": "igLoader",
"ext": ".igl"
},
{
"mime": "image/ief",
"name": "Image Exchange Format",
"ext": ".ief"
},
{
"mime": "application/vnd.immervision-ivp",
"name": "ImmerVision PURE Players",
"ext": ".ivp"
},
{
"mime": "application/vnd.immervision-ivu",
"name": "ImmerVision PURE Players",
"ext": ".ivu"
},
{
"mime": "application/reginfo+xml",
"name": "IMS Networks",
"ext": ".rif"
},
{
"mime": "text/vnd.in3d.3dml",
"name": "In3D - 3DML",
"ext": ".3dml"
},
{
"mime": "text/vnd.in3d.spot",
"name": "In3D - 3DML",
"ext": ".spot"
},
{
"mime": "model/iges",
"name": "Initial Graphics Exchange Specification (IGES)",
"ext": ".igs"
},
{
"mime": "application/vnd.intergeo",
"name": "Interactive Geometry Software",
"ext": ".i2g"
},
{
"mime": "application/vnd.cinderella",
"name": "Interactive Geometry Software Cinderella",
"ext": ".cdy"
},
{
"mime": "application/vnd.intercon.formnet",
"name": "Intercon FormNet",
"ext": ".xpw"
},
{
"mime": "application/vnd.isac.fcs",
"name": "International Society for Advancement of Cytometry",
"ext": ".fcs"
},
{
"mime": "application/ipfix",
"name": "Internet Protocol Flow Information Export",
"ext": ".ipfix"
},
{
"mime": "application/pkix-cert",
"name": "Internet Public Key Infrastructure - Certificate",
"ext": ".cer"
},
{
"mime": "application/pkixcmp",
"name": "Internet Public Key Infrastructure - Certificate Management Protocole",
"ext": ".pki"
},
{
"mime": "application/pkix-crl",
"name": "Internet Public Key Infrastructure - Certificate Revocation Lists",
"ext": ".crl"
},
{
"mime": "application/pkix-pkipath",
"name": "Internet Public Key Infrastructure - Certification Path",
"ext": ".pkipath"
},
{
"mime": "application/vnd.insors.igm",
"name": "IOCOM Visimeet",
"ext": ".igm"
},
{
"mime": "application/vnd.ipunplugged.rcprofile",
"name": "IP Unplugged Roaming Client",
"ext": ".rcprofile"
},
{
"mime": "application/vnd.irepository.package+xml",
"name": "iRepository / Lucidoc Editor",
"ext": ".irp"
},
{
"mime": "text/vnd.sun.j2me.app-descriptor",
"name": "J2ME App Descriptor",
"ext": ".jad"
},
{
"mime": "application/java-archive",
"name": "Java Archive",
"ext": ".jar"
},
{
"mime": "application/java-vm",
"name": "Java Bytecode File",
"ext": ".class"
},
{
"mime": "application/x-java-jnlp-file",
"name": "Java Network Launching Protocol",
"ext": ".jnlp"
},
{
"mime": "application/java-serialized-object",
"name": "Java Serialized Object",
"ext": ".ser"
},
{
"mime": "text/x-java-source,java",
"name": "Java Source File",
"ext": ".java"
},
{
"mime": "application/javascript",
"name": "JavaScript",
"ext": ".js"
},
{
"mime": "application/json",
"name": "JavaScript Object Notation (JSON)",
"ext": ".json"
},
{
"mime": "application/vnd.joost.joda-archive",
"name": "Joda Archive",
"ext": ".joda"
},
{
"mime": "video/jpm",
"name": "JPEG 2000 Compound Image File Format",
"ext": ".jpm"
},
{
"mime": "image/jpeg",
"name": "JPEG Image",
"ext": ".jpeg"
},
{
"mime": "image/jpeg",
"name": "JPEG Image",
"ext": ".jpg"
},
{
"mime": "video/jpeg",
"name": "JPGVideo",
"ext": ".jpgv"
},
{
"mime": "application/vnd.kahootz",
"name": "Kahootz",
"ext": ".ktz"
},
{
"mime": "application/vnd.chipnuts.karaoke-mmd",
"name": "Karaoke on Chipnuts Chipsets",
"ext": ".mmd"
},
{
"mime": "application/vnd.kde.karbon",
"name": "KDE KOffice Office Suite - Karbon",
"ext": ".karbon"
},
{
"mime": "application/vnd.kde.kchart",
"name": "KDE KOffice Office Suite - KChart",
"ext": ".chrt"
},
{
"mime": "application/vnd.kde.kformula",
"name": "KDE KOffice Office Suite - Kformula",
"ext": ".kfo"
},
{
"mime": "application/vnd.kde.kivio",
"name": "KDE KOffice Office Suite - Kivio",
"ext": ".flw"
},
{
"mime": "application/vnd.kde.kontour",
"name": "KDE KOffice Office Suite - Kontour",
"ext": ".kon"
},
{
"mime": "application/vnd.kde.kpresenter",
"name": "KDE KOffice Office Suite - Kpresenter",
"ext": ".kpr"
},
{
"mime": "application/vnd.kde.kspread",
"name": "KDE KOffice Office Suite - Kspread",
"ext": ".ksp"
},
{
"mime": "application/vnd.kde.kword",
"name": "KDE KOffice Office Suite - Kword",
"ext": ".kwd"
},
{
"mime": "application/vnd.kenameaapp",
"name": "Kenamea App",
"ext": ".htke"
},
{
"mime": "application/vnd.kidspiration",
"name": "Kidspiration",
"ext": ".kia"
},
{
"mime": "application/vnd.kinar",
"name": "Kinar Applications",
"ext": ".kne"
},
{
"mime": "application/vnd.kodak-descriptor",
"name": "Kodak Storyshare",
"ext": ".sse"
},
{
"mime": "application/vnd.las.las+xml",
"name": "Laser App Enterprise",
"ext": ".lasxml"
},
{
"mime": "application/x-latex",
"name": "LaTeX",
"ext": ".latex"
},
{
"mime": "application/vnd.llamagraphics.life-balance.desktop",
"name": "Life Balance - Desktop Edition",
"ext": ".lbd"
},
{
"mime": "application/vnd.llamagraphics.life-balance.exchange+xml",
"name": "Life Balance - Exchange Format",
"ext": ".lbe"
},
{
"mime": "application/vnd.jam",
"name": "Lightspeed Audio Lab",
"ext": ".jam"
},
{
"mime": "application/vnd.lotus-1-2-3",
"name": "Lotus 1-2-3",
"ext": 0.123
},
{
"mime": "application/vnd.lotus-approach",
"name": "Lotus Approach",
"ext": ".apr"
},
{
"mime": "application/vnd.lotus-freelance",
"name": "Lotus Freelance",
"ext": ".pre"
},
{
"mime": "application/vnd.lotus-notes",
"name": "Lotus Notes",
"ext": ".nsf"
},
{
"mime": "application/vnd.lotus-organizer",
"name": "Lotus Organizer",
"ext": ".org"
},
{
"mime": "application/vnd.lotus-screencam",
"name": "Lotus Screencam",
"ext": ".scm"
},
{
"mime": "application/vnd.lotus-wordpro",
"name": "Lotus Wordpro",
"ext": ".lwp"
},
{
"mime": "audio/vnd.lucent.voice",
"name": "Lucent Voice",
"ext": ".lvp"
},
{
"mime": "audio/x-mpegurl",
"name": "M3U (Multimedia Playlist)",
"ext": ".m3u"
},
{
"mime": "video/x-m4v",
"name": "M4v",
"ext": ".m4v"
},
{
"mime": "application/mac-binhex40",
"name": "Macintosh BinHex 4.0",
"ext": ".hqx"
},
{
"mime": "application/vnd.macports.portpkg",
"name": "MacPorts Port System",
"ext": ".portpkg"
},
{
"mime": "application/vnd.osgeo.mapguide.package",
"name": "MapGuide DBXML",
"ext": ".mgp"
},
{
"mime": "application/marc",
"name": "MARC Formats",
"ext": ".mrc"
},
{
"mime": "application/marcxml+xml",
"name": "MARC21 XML Schema",
"ext": ".mrcx"
},
{
"mime": "application/mxf",
"name": "Material Exchange Format",
"ext": ".mxf"
},
{
"mime": "application/vnd.wolfram.player",
"name": "Mathematica Notebook Player",
"ext": ".nbp"
},
{
"mime": "application/mathematica",
"name": "Mathematica Notebooks",
"ext": ".ma"
},
{
"mime": "application/mathml+xml",
"name": "Mathematical Markup Language",
"ext": ".mathml"
},
{
"mime": "application/mbox",
"name": "Mbox database files",
"ext": ".mbox"
},
{
"mime": "application/vnd.medcalcdata",
"name": "MedCalc",
"ext": ".mc1"
},
{
"mime": "application/mediaservercontrol+xml",
"name": "Media Server Control Markup Language",
"ext": ".mscml"
},
{
"mime": "application/vnd.mediastation.cdkey",
"name": "MediaRemote",
"ext": ".cdkey"
},
{
"mime": "application/vnd.mfer",
"name": "Medical Waveform Encoding Format",
"ext": ".mwf"
},
{
"mime": "application/vnd.mfmp",
"name": "Melody Format for Mobile Platform",
"ext": ".mfm"
},
{
"mime": "model/mesh",
"name": "Mesh Data Type",
"ext": ".msh"
},
{
"mime": "application/mads+xml",
"name": "Metadata Authority Description Schema",
"ext": ".mads"
},
{
"mime": "application/mets+xml",
"name": "Metadata Encoding and Transmission Standard",
"ext": ".mets"
},
{
"mime": "application/mods+xml",
"name": "Metadata Object Description Schema",
"ext": ".mods"
},
{
"mime": "application/metalink4+xml",
"name": "Metalink",
"ext": ".meta4"
},
{
"mime": "application/vnd.ms-powerpoint.template.macroenabled.12",
"name": "Micosoft PowerPoint - Macro-Enabled Template File",
"ext": ".potm"
},
{
"mime": "application/vnd.ms-word.document.macroenabled.12",
"name": "Micosoft Word - Macro-Enabled Document",
"ext": ".docm"
},
{
"mime": "application/vnd.ms-word.template.macroenabled.12",
"name": "Micosoft Word - Macro-Enabled Template",
"ext": ".dotm"
},
{
"mime": "application/vnd.mcd",
"name": "Micro CADAM Helix D&D",
"ext": ".mcd"
},
{
"mime": "application/vnd.micrografx.flo",
"name": "Micrografx",
"ext": ".flo"
},
{
"mime": "application/vnd.micrografx.igx",
"name": "Micrografx iGrafx Professional",
"ext": ".igx"
},
{
"mime": "application/vnd.eszigno3+xml",
"name": "MICROSEC e-Szign¢",
"ext": ".es3"
},
{
"mime": "application/x-msaccess",
"name": "Microsoft Access",
"ext": ".mdb"
},
{
"mime": "video/x-ms-asf",
"name": "Microsoft Advanced Systems Format (ASF)",
"ext": ".asf"
},
{
"mime": "application/x-msdownload",
"name": "Microsoft Application",
"ext": ".exe"
},
{
"mime": "application/vnd.ms-artgalry",
"name": "Microsoft Artgalry",
"ext": ".cil"
},
{
"mime": "application/vnd.ms-cab-compressed",
"name": "Microsoft Cabinet File",
"ext": ".cab"
},
{
"mime": "application/vnd.ms-ims",
"name": "Microsoft Class Server",
"ext": ".ims"
},
{
"mime": "application/x-ms-application",
"name": "Microsoft ClickOnce",
"ext": ".application"
},
{
"mime": "application/x-msclip",
"name": "Microsoft Clipboard Clip",
"ext": ".clp"
},
{
"mime": "image/vnd.ms-modi",
"name": "Microsoft Document Imaging Format",
"ext": ".mdi"
},
{
"mime": "application/vnd.ms-fontobject",
"name": "Microsoft Embedded OpenType",
"ext": ".eot"
},
{
"mime": "application/vnd.ms-excel",
"name": "Microsoft Excel",
"ext": ".xls"
},
{
"mime": "application/vnd.ms-excel.addin.macroenabled.12",
"name": "Microsoft Excel - Add-In File",
"ext": ".xlam"
},
{
"mime": "application/vnd.ms-excel.sheet.binary.macroenabled.12",
"name": "Microsoft Excel - Binary Workbook",
"ext": ".xlsb"
},
{
"mime": "application/vnd.ms-excel.template.macroenabled.12",
"name": "Microsoft Excel - Macro-Enabled Template File",
"ext": ".xltm"
},
{
"mime": "application/vnd.ms-excel.sheet.macroenabled.12",
"name": "Microsoft Excel - Macro-Enabled Workbook",
"ext": ".xlsm"
},
{
"mime": "application/vnd.ms-htmlhelp",
"name": "Microsoft Html Help File",
"ext": ".chm"
},
{
"mime": "application/x-mscardfile",
"name": "Microsoft Information Card",
"ext": ".crd"
},
{
"mime": "application/vnd.ms-lrm",
"name": "Microsoft Learning Resource Module",
"ext": ".lrm"
},
{
"mime": "application/x-msmediaview",
"name": "Microsoft MediaView",
"ext": ".mvb"
},
{
"mime": "application/x-msmoney",
"name": "Microsoft Money",
"ext": ".mny"
},
{
"mime": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
"name": "Microsoft Office - OOXML - Presentation",
"ext": ".pptx"
},
{
"mime": "application/vnd.openxmlformats-officedocument.presentationml.slide",
"name": "Microsoft Office - OOXML - Presentation (Slide)",
"ext": ".sldx"
},
{
"mime": "application/vnd.openxmlformats-officedocument.presentationml.slideshow",
"name": "Microsoft Office - OOXML - Presentation (Slideshow)",
"ext": ".ppsx"
},
{
"mime": "application/vnd.openxmlformats-officedocument.presentationml.template",
"name": "Microsoft Office - OOXML - Presentation Template",
"ext": ".potx"
},
{
"mime": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"name": "Microsoft Office - OOXML - Spreadsheet",
"ext": ".xlsx"
},
{
"mime": "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
"name": "Microsoft Office - OOXML - Spreadsheet Teplate",
"ext": ".xltx"
},
{
"mime": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"name": "Microsoft Office - OOXML - Word Document",
"ext": ".docx"
},
{
"mime": "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
"name": "Microsoft Office - OOXML - Word Document Template",
"ext": ".dotx"
},
{
"mime": "application/x-msbinder",
"name": "Microsoft Office Binder",
"ext": ".obd"
},
{
"mime": "application/vnd.ms-officetheme",
"name": "Microsoft Office System Release Theme",
"ext": ".thmx"
},
{
"mime": "application/onenote",
"name": "Microsoft OneNote",
"ext": ".onetoc"
},
{
"mime": "audio/vnd.ms-playready.media.pya",
"name": "Microsoft PlayReady Ecosystem",
"ext": ".pya"
},
{
"mime": "video/vnd.ms-playready.media.pyv",
"name": "Microsoft PlayReady Ecosystem Video",
"ext": ".pyv"
},
{
"mime": "application/vnd.ms-powerpoint",
"name": "Microsoft PowerPoint",
"ext": ".ppt"
},
{
"mime": "application/vnd.ms-powerpoint.addin.macroenabled.12",
"name": "Microsoft PowerPoint - Add-in file",
"ext": ".ppam"
},
{
"mime": "application/vnd.ms-powerpoint.slide.macroenabled.12",
"name": "Microsoft PowerPoint - Macro-Enabled Open XML Slide",
"ext": ".sldm"
},
{
"mime": "application/vnd.ms-powerpoint.presentation.macroenabled.12",
"name": "Microsoft PowerPoint - Macro-Enabled Presentation File",
"ext": ".pptm"
},
{
"mime": "application/vnd.ms-powerpoint.slideshow.macroenabled.12",
"name": "Microsoft PowerPoint - Macro-Enabled Slide Show File",
"ext": ".ppsm"
},
{
"mime": "application/vnd.ms-project",
"name": "Microsoft Project",
"ext": ".mpp"
},
{
"mime": "application/x-mspublisher",
"name": "Microsoft Publisher",
"ext": ".pub"
},
{
"mime": "application/x-msschedule",
"name": "Microsoft Schedule+",
"ext": ".scd"
},
{
"mime": "application/x-silverlight-app",
"name": "Microsoft Silverlight",
"ext": ".xap"
},
{
"mime": "application/vnd.ms-pki.stl",
"name": "Microsoft Trust UI Provider - Certificate Trust Link",
"ext": ".stl"
},
{
"mime": "application/vnd.ms-pki.seccat",
"name": "Microsoft Trust UI Provider - Security Catalog",
"ext": ".cat"
},
{
"mime": "application/vnd.visio",
"name": "Microsoft Visio",
"ext": ".vsd"
},
{
"mime": "video/x-ms-wm",
"name": "Microsoft Windows Media",
"ext": ".wm"
},
{
"mime": "audio/x-ms-wma",
"name": "Microsoft Windows Media Audio",
"ext": ".wma"
},
{
"mime": "audio/x-ms-wax",
"name": "Microsoft Windows Media Audio Redirector",
"ext": ".wax"
},
{
"mime": "video/x-ms-wmx",
"name": "Microsoft Windows Media Audio/Video Playlist",
"ext": ".wmx"
},
{
"mime": "application/x-ms-wmd",
"name": "Microsoft Windows Media Player Download Package",
"ext": ".wmd"
},
{
"mime": "application/vnd.ms-wpl",
"name": "Microsoft Windows Media Player Playlist",
"ext": ".wpl"
},
{
"mime": "application/x-ms-wmz",
"name": "Microsoft Windows Media Player Skin Package",
"ext": ".wmz"
},
{
"mime": "video/x-ms-wmv",
"name": "Microsoft Windows Media Video",
"ext": ".wmv"
},
{
"mime": "video/x-ms-wvx",
"name": "Microsoft Windows Media Video Playlist",
"ext": ".wvx"
},
{
"mime": "application/x-msmetafile",
"name": "Microsoft Windows Metafile",
"ext": ".wmf"
},
{
"mime": "application/x-msterminal",
"name": "Microsoft Windows Terminal Services",
"ext": ".trm"
},
{
"mime": "application/msword",
"name": "Microsoft Word",
"ext": ".doc"
},
{
"mime": "application/x-mswrite",
"name": "Microsoft Wordpad",
"ext": ".wri"
},
{
"mime": "application/vnd.ms-works",
"name": "Microsoft Works",
"ext": ".wps"
},
{
"mime": "application/x-ms-xbap",
"name": "Microsoft XAML Browser Application",
"ext": ".xbap"
},
{
"mime": "application/vnd.ms-xpsdocument",
"name": "Microsoft XML Paper Specification",
"ext": ".xps"
},
{
"mime": "audio/midi",
"name": "MIDI - Musical Instrument Digital Interface",
"ext": ".mid"
},
{
"mime": "application/vnd.ibm.minipay",
"name": "MiniPay",
"ext": ".mpy"
},
{
"mime": "application/vnd.ibm.modcap",
"name": "MO:DCA-P",
"ext": ".afp"
},
{
"mime": "application/vnd.jcp.javame.midlet-rms",
"name": "Mobile Information Device Profile",
"ext": ".rms"
},
{
"mime": "application/vnd.tmobile-livetv",
"name": "MobileTV",
"ext": ".tmo"
},
{
"mime": "application/x-mobipocket-ebook",
"name": "Mobipocket",
"ext": ".prc"
},
{
"mime": "application/vnd.mobius.mbk",
"name": "Mobius Management Systems - Basket file",
"ext": ".mbk"
},
{
"mime": "application/vnd.mobius.dis",
"name": "Mobius Management Systems - Distribution Database",
"ext": ".dis"
},
{
"mime": "application/vnd.mobius.plc",
"name": "Mobius Management Systems - Policy Definition Language File",
"ext": ".plc"
},
{
"mime": "application/vnd.mobius.mqy",
"name": "Mobius Management Systems - Query File",
"ext": ".mqy"
},
{
"mime": "application/vnd.mobius.msl",
"name": "Mobius Management Systems - Script Language",
"ext": ".msl"
},
{
"mime": "application/vnd.mobius.txf",
"name": "Mobius Management Systems - Topic Index File",
"ext": ".txf"
},
{
"mime": "application/vnd.mobius.daf",
"name": "Mobius Management Systems - UniversalArchive",
"ext": ".daf"
},
{
"mime": "text/vnd.fly",
"name": "mod_fly / fly.cgi",
"ext": ".fly"
},
{
"mime": "application/vnd.mophun.certificate",
"name": "Mophun Certificate",
"ext": ".mpc"
},
{
"mime": "application/vnd.mophun.application",
"name": "Mophun VM",
"ext": ".mpn"
},
{
"mime": "video/mj2",
"name": "Motion JPEG 2000",
"ext": ".mj2"
},
{
"mime": "audio/mpeg",
"name": "MPEG Audio",
"ext": ".mpga"
},
{
"mime": "video/vnd.mpegurl",
"name": "MPEG Url",
"ext": ".mxu"
},
{
"mime": "video/mpeg",
"name": "MPEG Video",
"ext": ".mpeg"
},
{
"mime": "application/mp21",
"name": "MPEG-21",
"ext": ".m21"
},
{
"mime": "audio/mp4",
"name": "MPEG-4 Audio",
"ext": ".mp4a"
},
{
"mime": "video/mp4",
"name": "MPEG-4 Video",
"ext": ".mp4"
},
{
"mime": "application/mp4",
"name": "MPEG4",
"ext": ".mp4"
},
{
"mime": "application/vnd.apple.mpegurl",
"name": "Multimedia Playlist Unicode",
"ext": ".m3u8"
},
{
"mime": "application/vnd.musician",
"name": "MUsical Score Interpreted Code Invented for the ASCII designation of Notation",
"ext": ".mus"
},
{
"mime": "application/vnd.muvee.style",
"name": "Muvee Automatic Video Editing",
"ext": ".msty"
},
{
"mime": "application/xv+xml",
"name": "MXML",
"ext": ".mxml"
},
{
"mime": "application/vnd.nokia.n-gage.data",
"name": "N-Gage Game Data",
"ext": ".ngdat"
},
{
"mime": "application/vnd.nokia.n-gage.symbian.install",
"name": "N-Gage Game Installer",
"ext": ".n-gage"
},
{
"mime": "application/x-dtbncx+xml",
"name": "Navigation Control file for XML (for ePub)",
"ext": ".ncx"
},
{
"mime": "application/x-netcdf",
"name": "Network Common Data Form (NetCDF)",
"ext": ".nc"
},
{
"mime": "application/vnd.neurolanguage.nlu",
"name": "neuroLanguage",
"ext": ".nlu"
},
{
"mime": "application/vnd.dna",
"name": "New Moon Liftoff/DNA",
"ext": ".dna"
},
{
"mime": "application/vnd.noblenet-directory",
"name": "NobleNet Directory",
"ext": ".nnd"
},
{
"mime": "application/vnd.noblenet-sealer",
"name": "NobleNet Sealer",
"ext": ".nns"
},
{
"mime": "application/vnd.noblenet-web",
"name": "NobleNet Web",
"ext": ".nnw"
},
{
"mime": "application/vnd.nokia.radio-preset",
"name": "Nokia Radio Application - Preset",
"ext": ".rpst"
},
{
"mime": "application/vnd.nokia.radio-presets",
"name": "Nokia Radio Application - Preset",
"ext": ".rpss"
},
{
"mime": "text/n3",
"name": "Notation3",
"ext": ".n3"
},
{
"mime": "application/vnd.novadigm.edm",
"name": "Novadigm's RADIA and EDM products",
"ext": ".edm"
},
{
"mime": "application/vnd.novadigm.edx",
"name": "Novadigm's RADIA and EDM products",
"ext": ".edx"
},
{
"mime": "application/vnd.novadigm.ext",
"name": "Novadigm's RADIA and EDM products",
"ext": ".ext"
},
{
"mime": "application/vnd.flographit",
"name": "NpGraphIt",
"ext": ".gph"
},
{
"mime": "audio/vnd.nuera.ecelp4800",
"name": "Nuera ECELP 4800",
"ext": ".ecelp4800"
},
{
"mime": "audio/vnd.nuera.ecelp7470",
"name": "Nuera ECELP 7470",
"ext": ".ecelp7470"
},
{
"mime": "audio/vnd.nuera.ecelp9600",
"name": "Nuera ECELP 9600",
"ext": ".ecelp9600"
},
{
"mime": "application/oda",
"name": "Office Document Architecture",
"ext": ".oda"
},
{
"mime": "application/ogg",
"name": "Ogg",
"ext": ".ogx"
},
{
"mime": "audio/ogg",
"name": "Ogg Audio",
"ext": ".oga"
},
{
"mime": "video/ogg",
"name": "Ogg Video",
"ext": ".ogv"
},
{
"mime": "application/vnd.oma.dd2+xml",
"name": "OMA Download Agents",
"ext": ".dd2"
},
{
"mime": "application/vnd.oasis.opendocument.text-web",
"name": "Open Document Text Web",
"ext": ".oth"
},
{
"mime": "application/oebps-package+xml",
"name": "Open eBook Publication Structure",
"ext": ".opf"
},
{
"mime": "application/vnd.intu.qbo",
"name": "Open Financial Exchange",
"ext": ".qbo"
},
{
"mime": "application/vnd.openofficeorg.extension",
"name": "Open Office Extension",
"ext": ".oxt"
},
{
"mime": "application/vnd.yamaha.openscoreformat",
"name": "Open Score Format",
"ext": ".osf"
},
{
"mime": "audio/webm",
"name": "Open Web Media Project - Audio",
"ext": ".weba"
},
{
"mime": "video/webm",
"name": "Open Web Media Project - Video",
"ext": ".webm"
},
{
"mime": "application/vnd.oasis.opendocument.chart",
"name": "OpenDocument Chart",
"ext": ".odc"
},
{
"mime": "application/vnd.oasis.opendocument.chart-template",
"name": "OpenDocument Chart Template",
"ext": ".otc"
},
{
"mime": "application/vnd.oasis.opendocument.database",
"name": "OpenDocument Database",
"ext": ".odb"
},
{
"mime": "application/vnd.oasis.opendocument.formula",
"name": "OpenDocument Formula",
"ext": ".odf"
},
{
"mime": "application/vnd.oasis.opendocument.formula-template",
"name": "OpenDocument Formula Template",
"ext": ".odft"
},
{
"mime": "application/vnd.oasis.opendocument.graphics",
"name": "OpenDocument Graphics",
"ext": ".odg"
},
{
"mime": "application/vnd.oasis.opendocument.graphics-template",
"name": "OpenDocument Graphics Template",
"ext": ".otg"
},
{
"mime": "application/vnd.oasis.opendocument.image",
"name": "OpenDocument Image",
"ext": ".odi"
},
{
"mime": "application/vnd.oasis.opendocument.image-template",
"name": "OpenDocument Image Template",
"ext": ".oti"
},
{
"mime": "application/vnd.oasis.opendocument.presentation",
"name": "OpenDocument Presentation",
"ext": ".odp"
},
{
"mime": "application/vnd.oasis.opendocument.presentation-template",
"name": "OpenDocument Presentation Template",
"ext": ".otp"
},
{
"mime": "application/vnd.oasis.opendocument.spreadsheet",
"name": "OpenDocument Spreadsheet",
"ext": ".ods"
},
{
"mime": "application/vnd.oasis.opendocument.spreadsheet-template",
"name": "OpenDocument Spreadsheet Template",
"ext": ".ots"
},
{
"mime": "application/vnd.oasis.opendocument.text",
"name": "OpenDocument Text",
"ext": ".odt"
},
{
"mime": "application/vnd.oasis.opendocument.text-master",
"name": "OpenDocument Text Master",
"ext": ".odm"
},
{
"mime": "application/vnd.oasis.opendocument.text-template",
"name": "OpenDocument Text Template",
"ext": ".ott"
},
{
"mime": "image/ktx",
"name": "OpenGL Textures (KTX)",
"ext": ".ktx"
},
{
"mime": "application/vnd.sun.xml.calc",
"name": "OpenOffice - Calc (Spreadsheet)",
"ext": ".sxc"
},
{
"mime": "application/vnd.sun.xml.calc.template",
"name": "OpenOffice - Calc Template (Spreadsheet)",
"ext": ".stc"
},
{
"mime": "application/vnd.sun.xml.draw",
"name": "OpenOffice - Draw (Graphics)",
"ext": ".sxd"
},
{
"mime": "application/vnd.sun.xml.draw.template",
"name": "OpenOffice - Draw Template (Graphics)",
"ext": ".std"
},
{
"mime": "application/vnd.sun.xml.impress",
"name": "OpenOffice - Impress (Presentation)",
"ext": ".sxi"
},
{
"mime": "application/vnd.sun.xml.impress.template",
"name": "OpenOffice - Impress Template (Presentation)",
"ext": ".sti"
},
{
"mime": "application/vnd.sun.xml.math",
"name": "OpenOffice - Math (Formula)",
"ext": ".sxm"
},
{
"mime": "application/vnd.sun.xml.writer",
"name": "OpenOffice - Writer (Text - HTML)",
"ext": ".sxw"
},
{
"mime": "application/vnd.sun.xml.writer.global",
"name": "OpenOffice - Writer (Text - HTML)",
"ext": ".sxg"
},
{
"mime": "application/vnd.sun.xml.writer.template",
"name": "OpenOffice - Writer Template (Text - HTML)",
"ext": ".stw"
},
{
"mime": "application/x-font-otf",
"name": "OpenType Font File",
"ext": ".otf"
},
{
"mime": "application/vnd.yamaha.openscoreformat.osfpvg+xml",
"name": "OSFPVG",
"ext": ".osfpvg"
},
{
"mime": "application/vnd.osgi.dp",
"name": "OSGi Deployment Package",
"ext": ".dp"
},
{
"mime": "application/vnd.palm",
"name": "PalmOS Data",
"ext": ".pdb"
},
{
"mime": "text/x-pascal",
"name": "Pascal Source File",
"ext": ".p"
},
{
"mime": "application/vnd.pawaafile",
"name": "PawaaFILE",
"ext": ".paw"
},
{
"mime": "application/vnd.hp-pclxl",
"name": "PCL 6 Enhanced (Formely PCL XL)",
"ext": ".pclxl"
},
{
"mime": "application/vnd.picsel",
"name": "Pcsel eFIF File",
"ext": ".efif"
},
{
"mime": "image/x-pcx",
"name": "PCX Image",
"ext": ".pcx"
},
{
"mime": "image/vnd.adobe.photoshop",
"name": "Photoshop Document",
"ext": ".psd"
},
{
"mime": "application/pics-rules",
"name": "PICSRules",
"ext": ".prf"
},
{
"mime": "image/x-pict",
"name": "PICT Image",
"ext": ".pic"
},
{
"mime": "application/x-chat",
"name": "pIRCh",
"ext": ".chat"
},
{
"mime": "application/pkcs10",
"name": "PKCS #10 - Certification Request Standard",
"ext": ".p10"
},
{
"mime": "application/x-pkcs12",
"name": "PKCS #12 - Personal Information Exchange Syntax Standard",
"ext": ".p12"
},
{
"mime": "application/pkcs7-mime",
"name": "PKCS #7 - Cryptographic Message Syntax Standard",
"ext": ".p7m"
},
{
"mime": "application/pkcs7-signature",
"name": "PKCS #7 - Cryptographic Message Syntax Standard",
"ext": ".p7s"
},
{
"mime": "application/x-pkcs7-certreqresp",
"name": "PKCS #7 - Cryptographic Message Syntax Standard (Certificate Request Response)",
"ext": ".p7r"
},
{
"mime": "application/x-pkcs7-certificates",
"name": "PKCS #7 - Cryptographic Message Syntax Standard (Certificates)",
"ext": ".p7b"
},
{
"mime": "application/pkcs8",
"name": "PKCS #8 - Private-Key Information Syntax Standard",
"ext": ".p8"
},
{
"mime": "application/vnd.pocketlearn",
"name": "PocketLearn Viewers",
"ext": ".plf"
},
{
"mime": "image/x-portable-anymap",
"name": "Portable Anymap Image",
"ext": ".pnm"
},
{
"mime": "image/x-portable-bitmap",
"name": "Portable Bitmap Format",
"ext": ".pbm"
},
{
"mime": "application/x-font-pcf",
"name": "Portable Compiled Format",
"ext": ".pcf"
},
{
"mime": "application/font-tdpfr",
"name": "Portable Font Resource",
"ext": ".pfr"
},
{
"mime": "application/x-chess-pgn",
"name": "Portable Game Notation (Chess Games)",
"ext": ".pgn"
},
{
"mime": "image/x-portable-graymap",
"name": "Portable Graymap Format",
"ext": ".pgm"
},
{
"mime": "image/png",
"name": "Portable Network Graphics (PNG)",
"ext": ".png"
},
{
"mime": "image/x-portable-pixmap",
"name": "Portable Pixmap Format",
"ext": ".ppm"
},
{
"mime": "application/pskc+xml",
"name": "Portable Symmetric Key Container",
"ext": ".pskcxml"
},
{
"mime": "application/vnd.ctc-posml",
"name": "PosML",
"ext": ".pml"
},
{
"mime": "application/postscript",
"name": "PostScript",
"ext": ".ai"
},
{
"mime": "application/x-font-type1",
"name": "PostScript Fonts",
"ext": ".pfa"
},
{
"mime": "application/vnd.powerbuilder6",
"name": "PowerBuilder",
"ext": ".pbd"
},
{
"mime": "application/pgp-encrypted",
"name": "Pretty Good Privacy",
"ext": ""
},
{
"mime": "application/pgp-signature",
"name": "Pretty Good Privacy - Signature",
"ext": ".pgp"
},
{
"mime": "application/vnd.previewsystems.box",
"name": "Preview Systems ZipLock/VBox",
"ext": ".box"
},
{
"mime": "application/vnd.pvi.ptid1",
"name": "Princeton Video Image",
"ext": ".ptid"
},
{
"mime": "application/pls+xml",
"name": "Pronunciation Lexicon Specification",
"ext": ".pls"
},
{
"mime": "application/vnd.pg.format",
"name": "Proprietary P&G Standard Reporting System",
"ext": ".str"
},
{
"mime": "application/vnd.pg.osasli",
"name": "Proprietary P&G Standard Reporting System",
"ext": ".ei6"
},
{
"mime": "text/prs.lines.tag",
"name": "PRS Lines Tag",
"ext": ".dsc"
},
{
"mime": "application/x-font-linux-psf",
"name": "PSF Fonts",
"ext": ".psf"
},
{
"mime": "application/vnd.publishare-delta-tree",
"name": "PubliShare Objects",
"ext": ".qps"
},
{
"mime": "application/vnd.pmi.widget",
"name": "Qualcomm's Plaza Mobile Internet",
"ext": ".wg"
},
{
"mime": "application/vnd.quark.quarkxpress",
"name": "QuarkXpress",
"ext": ".qxd"
},
{
"mime": "application/vnd.epson.esf",
"name": "QUASS Stream Player",
"ext": ".esf"
},
{
"mime": "application/vnd.epson.msf",
"name": "QUASS Stream Player",
"ext": ".msf"
},
{
"mime": "application/vnd.epson.ssf",
"name": "QUASS Stream Player",
"ext": ".ssf"
},
{
"mime": "application/vnd.epson.quickanime",
"name": "QuickAnime Player",
"ext": ".qam"
},
{
"mime": "application/vnd.intu.qfx",
"name": "Quicken",
"ext": ".qfx"
},
{
"mime": "video/quicktime",
"name": "Quicktime Video",
"ext": ".qt"
},
{
"mime": "application/x-rar-compressed",
"name": "RAR Archive",
"ext": ".rar"
},
{
"mime": "audio/x-pn-realaudio",
"name": "Real Audio Sound",
"ext": ".ram"
},
{
"mime": "audio/x-pn-realaudio-plugin",
"name": "Real Audio Sound",
"ext": ".rmp"
},
{
"mime": "application/rsd+xml",
"name": "Really Simple Discovery",
"ext": ".rsd"
},
{
"mime": "application/vnd.rn-realmedia",
"name": "RealMedia",
"ext": ".rm"
},
{
"mime": "application/vnd.realvnc.bed",
"name": "RealVNC",
"ext": ".bed"
},
{
"mime": "application/vnd.recordare.musicxml",
"name": "Recordare Applications",
"ext": ".mxl"
},
{
"mime": "application/vnd.recordare.musicxml+xml",
"name": "Recordare Applications",
"ext": ".musicxml"
},
{
"mime": "application/relax-ng-compact-syntax",
"name": "Relax NG Compact Syntax",
"ext": ".rnc"
},
{
"mime": "application/vnd.data-vision.rdz",
"name": "RemoteDocs R-Viewer",
"ext": ".rdz"
},
{
"mime": "application/rdf+xml",
"name": "Resource Description Framework",
"ext": ".rdf"
},
{
"mime": "application/vnd.cloanto.rp9",
"name": "RetroPlatform Player",
"ext": ".rp9"
},
{
"mime": "application/vnd.jisp",
"name": "RhymBox",
"ext": ".jisp"
},
{
"mime": "application/rtf",
"name": "Rich Text Format",
"ext": ".rtf"
},
{
"mime": "text/richtext",
"name": "Rich Text Format (RTF)",
"ext": ".rtx"
},
{
"mime": "application/vnd.route66.link66+xml",
"name": "ROUTE 66 Location Based Services",
"ext": ".link66"
},
{
"mime": "application/rss+xml",
"name": "RSS - Really Simple Syndication",
"ext": ".rss, .xml"
},
{
"mime": "application/shf+xml",
"name": "S Hexdump Format",
"ext": ".shf"
},
{
"mime": "application/vnd.sailingtracker.track",
"name": "SailingTracker",
"ext": ".st"
},
{
"mime": "image/svg+xml",
"name": "Scalable Vector Graphics (SVG)",
"ext": ".svg"
},
{
"mime": "application/vnd.sus-calendar",
"name": "ScheduleUs",
"ext": ".sus"
},
{
"mime": "application/sru+xml",
"name": "Search/Retrieve via URL Response Format",
"ext": ".sru"
},
{
"mime": "application/set-payment-initiation",
"name": "Secure Electronic Transaction - Payment",
"ext": ".setpay"
},
{
"mime": "application/set-registration-initiation",
"name": "Secure Electronic Transaction - Registration",
"ext": ".setreg"
},
{
"mime": "application/vnd.sema",
"name": "Secured eMail",
"ext": ".sema"
},
{
"mime": "application/vnd.semd",
"name": "Secured eMail",
"ext": ".semd"
},
{
"mime": "application/vnd.semf",
"name": "Secured eMail",
"ext": ".semf"
},
{
"mime": "application/vnd.seemail",
"name": "SeeMail",
"ext": ".see"
},
{
"mime": "application/x-font-snf",
"name": "Server Normal Format",
"ext": ".snf"
},
{
"mime": "application/scvp-vp-request",
"name": "Server-Based Certificate Validation Protocol - Validation Policies - Request",
"ext": ".spq"
},
{
"mime": "application/scvp-vp-response",
"name": "Server-Based Certificate Validation Protocol - Validation Policies - Response",
"ext": ".spp"
},
{
"mime": "application/scvp-cv-request",
"name": "Server-Based Certificate Validation Protocol - Validation Request",
"ext": ".scq"
},
{
"mime": "application/scvp-cv-response",
"name": "Server-Based Certificate Validation Protocol - Validation Response",
"ext": ".scs"
},
{
"mime": "application/sdp",
"name": "Session Description Protocol",
"ext": ".sdp"
},
{
"mime": "text/x-setext",
"name": "Setext",
"ext": ".etx"
},
{
"mime": "video/x-sgi-movie",
"name": "SGI Movie",
"ext": ".movie"
},
{
"mime": "application/vnd.shana.informed.formdata",
"name": "Shana Informed Filler",
"ext": ".ifm"
},
{
"mime": "application/vnd.shana.informed.formtemplate",
"name": "Shana Informed Filler",
"ext": ".itp"
},
{
"mime": "application/vnd.shana.informed.interchange",
"name": "Shana Informed Filler",
"ext": ".iif"
},
{
"mime": "application/vnd.shana.informed.package",
"name": "Shana Informed Filler",
"ext": ".ipk"
},
{
"mime": "application/thraud+xml",
"name": "Sharing Transaction Fraud Data",
"ext": ".tfi"
},
{
"mime": "application/x-shar",
"name": "Shell Archive",
"ext": ".shar"
},
{
"mime": "image/x-rgb",
"name": "Silicon Graphics RGB Bitmap",
"ext": ".rgb"
},
{
"mime": "application/vnd.epson.salt",
"name": "SimpleAnimeLite Player",
"ext": ".slt"
},
{
"mime": "application/vnd.accpac.simply.aso",
"name": "Simply Accounting",
"ext": ".aso"
},
{
"mime": "application/vnd.accpac.simply.imp",
"name": "Simply Accounting - Data Import",
"ext": ".imp"
},
{
"mime": "application/vnd.simtech-mindmapper",
"name": "SimTech MindMapper",
"ext": ".twd"
},
{
"mime": "application/vnd.commonspace",
"name": "Sixth Floor Media - CommonSpace",
"ext": ".csp"
},
{
"mime": "application/vnd.yamaha.smaf-audio",
"name": "SMAF Audio",
"ext": ".saf"
},
{
"mime": "application/vnd.smaf",
"name": "SMAF File",
"ext": ".mmf"
},
{
"mime": "application/vnd.yamaha.smaf-phrase",
"name": "SMAF Phrase",
"ext": ".spf"
},
{
"mime": "application/vnd.smart.teacher",
"name": "SMART Technologies Apps",
"ext": ".teacher"
},
{
"mime": "application/vnd.svd",
"name": "SourceView Document",
"ext": ".svd"
},
{
"mime": "application/sparql-query",
"name": "SPARQL - Query",
"ext": ".rq"
},
{
"mime": "application/sparql-results+xml",
"name": "SPARQL - Results",
"ext": ".srx"
},
{
"mime": "application/srgs",
"name": "Speech Recognition Grammar Specification",
"ext": ".gram"
},
{
"mime": "application/srgs+xml",
"name": "Speech Recognition Grammar Specification - XML",
"ext": ".grxml"
},
{
"mime": "application/ssml+xml",
"name": "Speech Synthesis Markup Language",
"ext": ".ssml"
},
{
"mime": "application/vnd.koan",
"name": "SSEYO Koan Play File",
"ext": ".skp"
},
{
"mime": "text/sgml",
"name": "Standard Generalized Markup Language (SGML)",
"ext": ".sgml"
},
{
"mime": "application/vnd.stardivision.calc",
"name": "StarOffice - Calc",
"ext": ".sdc"
},
{
"mime": "application/vnd.stardivision.draw",
"name": "StarOffice - Draw",
"ext": ".sda"
},
{
"mime": "application/vnd.stardivision.impress",
"name": "StarOffice - Impress",
"ext": ".sdd"
},
{
"mime": "application/vnd.stardivision.math",
"name": "StarOffice - Math",
"ext": ".smf"
},
{
"mime": "application/vnd.stardivision.writer",
"name": "StarOffice - Writer",
"ext": ".sdw"
},
{
"mime": "application/vnd.stardivision.writer-global",
"name": "StarOffice - Writer (Global)",
"ext": ".sgl"
},
{
"mime": "application/vnd.stepmania.stepchart",
"name": "StepMania",
"ext": ".sm"
},
{
"mime": "application/x-stuffit",
"name": "Stuffit Archive",
"ext": ".sit"
},
{
"mime": "application/x-stuffitx",
"name": "Stuffit Archive",
"ext": ".sitx"
},
{
"mime": "application/vnd.solent.sdkm+xml",
"name": "SudokuMagic",
"ext": ".sdkm"
},
{
"mime": "application/vnd.olpc-sugar",
"name": "Sugar Linux Application Bundle",
"ext": ".xo"
},
{
"mime": "audio/basic",
"name": "Sun Audio - Au file format",
"ext": ".au"
},
{
"mime": "application/vnd.wqd",
"name": "SundaHus WQ",
"ext": ".wqd"
},
{
"mime": "application/vnd.symbian.install",
"name": "Symbian Install Package",
"ext": ".sis"
},
{
"mime": "application/smil+xml",
"name": "Synchronized Multimedia Integration Language",
"ext": ".smi"
},
{
"mime": "application/vnd.syncml+xml",
"name": "SyncML",
"ext": ".xsm"
},
{
"mime": "application/vnd.syncml.dm+wbxml",
"name": "SyncML - Device Management",
"ext": ".bdm"
},
{
"mime": "application/vnd.syncml.dm+xml",
"name": "SyncML - Device Management",
"ext": ".xdm"
},
{
"mime": "application/x-sv4cpio",
"name": "System V Release 4 CPIO Archive",
"ext": ".sv4cpio"
},
{
"mime": "application/x-sv4crc",
"name": "System V Release 4 CPIO Checksum Data",
"ext": ".sv4crc"
},
{
"mime": "application/sbml+xml",
"name": "Systems Biology Markup Language",
"ext": ".sbml"
},
{
"mime": "text/tab-separated-values",
"name": "Tab Separated Values",
"ext": ".tsv"
},
{
"mime": "image/tiff",
"name": "Tagged Image File Format",
"ext": ".tiff"
},
{
"mime": "application/vnd.tao.intent-module-archive",
"name": "Tao Intent",
"ext": ".tao"
},
{
"mime": "application/x-tar",
"name": "Tar File (Tape Archive)",
"ext": ".tar"
},
{
"mime": "application/x-tcl",
"name": "Tcl Script",
"ext": ".tcl"
},
{
"mime": "application/x-tex",
"name": "TeX",
"ext": ".tex"
},
{
"mime": "application/x-tex-tfm",
"name": "TeX Font Metric",
"ext": ".tfm"
},
{
"mime": "application/tei+xml",
"name": "Text Encoding and Interchange",
"ext": ".tei"
},
{
"mime": "text/plain",
"name": "Text File",
"ext": ".txt"
},
{
"mime": "application/vnd.spotfire.dxp",
"name": "TIBCO Spotfire",
"ext": ".dxp"
},
{
"mime": "application/vnd.spotfire.sfs",
"name": "TIBCO Spotfire",
"ext": ".sfs"
},
{
"mime": "application/timestamped-data",
"name": "Time Stamped Data Envelope",
"ext": ".tsd"
},
{
"mime": "application/vnd.trid.tpt",
"name": "TRI Systems Config",
"ext": ".tpt"
},
{
"mime": "application/vnd.triscape.mxs",
"name": "Triscape Map Explorer",
"ext": ".mxs"
},
{
"mime": "text/troff",
"name": "troff",
"ext": ".t"
},
{
"mime": "application/vnd.trueapp",
"name": "True BASIC",
"ext": ".tra"
},
{
"mime": "application/x-font-ttf",
"name": "TrueType Font",
"ext": ".ttf"
},
{
"mime": "text/turtle",
"name": "Turtle (Terse RDF Triple Language)",
"ext": ".ttl"
},
{
"mime": "application/vnd.umajin",
"name": "UMAJIN",
"ext": ".umj"
},
{
"mime": "application/vnd.uoml+xml",
"name": "Unique Object Markup Language",
"ext": ".uoml"
},
{
"mime": "application/vnd.unity",
"name": "Unity 3d",
"ext": ".unityweb"
},
{
"mime": "application/vnd.ufdl",
"name": "Universal Forms Description Language",
"ext": ".ufd"
},
{
"mime": "text/uri-list",
"name": "URI Resolution Services",
"ext": ".uri"
},
{
"mime": "application/vnd.uiq.theme",
"name": "User Interface Quartz - Theme (Symbian)",
"ext": ".utz"
},
{
"mime": "application/x-ustar",
"name": "Ustar (Uniform Standard Tape Archive)",
"ext": ".ustar"
},
{
"mime": "text/x-uuencode",
"name": "UUEncode",
"ext": ".uu"
},
{
"mime": "text/x-vcalendar",
"name": "vCalendar",
"ext": ".vcs"
},
{
"mime": "text/x-vcard",
"name": "vCard",
"ext": ".vcf"
},
{
"mime": "application/x-cdlink",
"name": "Video CD",
"ext": ".vcd"
},
{
"mime": "application/vnd.vsf",
"name": "Viewport+",
"ext": ".vsf"
},
{
"mime": "model/vrml",
"name": "Virtual Reality Modeling Language",
"ext": ".wrl"
},
{
"mime": "application/vnd.vcx",
"name": "VirtualCatalog",
"ext": ".vcx"
},
{
"mime": "model/vnd.mts",
"name": "Virtue MTS",
"ext": ".mts"
},
{
"mime": "model/vnd.vtu",
"name": "Virtue VTU",
"ext": ".vtu"
},
{
"mime": "application/vnd.visionary",
"name": "Visionary",
"ext": ".vis"
},
{
"mime": "video/vnd.vivo",
"name": "Vivo",
"ext": ".viv"
},
{
"mime": "application/ccxml+xml,",
"name": "Voice Browser Call Control",
"ext": ".ccxml"
},
{
"mime": "application/voicexml+xml",
"name": "VoiceXML",
"ext": ".vxml"
},
{
"mime": "application/x-wais-source",
"name": "WAIS Source",
"ext": ".src"
},
{
"mime": "application/vnd.wap.wbxml",
"name": "WAP Binary XML (WBXML)",
"ext": ".wbxml"
},
{
"mime": "image/vnd.wap.wbmp",
"name": "WAP Bitamp (WBMP)",
"ext": ".wbmp"
},
{
"mime": "audio/x-wav",
"name": "Waveform Audio File Format (WAV)",
"ext": ".wav"
},
{
"mime": "application/davmount+xml",
"name": "Web Distributed Authoring and Versioning",
"ext": ".davmount"
},
{
"mime": "application/x-font-woff",
"name": "Web Open Font Format",
"ext": ".woff"
},
{
"mime": "application/wspolicy+xml",
"name": "Web Services Policy",
"ext": ".wspolicy"
},
{
"mime": "image/webp",
"name": "WebP Image",
"ext": ".webp"
},
{
"mime": "application/vnd.webturbo",
"name": "WebTurbo",
"ext": ".wtb"
},
{
"mime": "application/widget",
"name": "Widget Packaging and XML Configuration",
"ext": ".wgt"
},
{
"mime": "application/winhlp",
"name": "WinHelp",
"ext": ".hlp"
},
{
"mime": "text/vnd.wap.wml",
"name": "Wireless Markup Language (WML)",
"ext": ".wml"
},
{
"mime": "text/vnd.wap.wmlscript",
"name": "Wireless Markup Language Script (WMLScript)",
"ext": ".wmls"
},
{
"mime": "application/vnd.wap.wmlscriptc",
"name": "WMLScript",
"ext": ".wmlsc"
},
{
"mime": "application/vnd.wordperfect",
"name": "Wordperfect",
"ext": ".wpd"
},
{
"mime": "application/vnd.wt.stf",
"name": "Worldtalk",
"ext": ".stf"
},
{
"mime": "application/wsdl+xml",
"name": "WSDL - Web Services Description Language",
"ext": ".wsdl"
},
{
"mime": "image/x-xbitmap",
"name": "X BitMap",
"ext": ".xbm"
},
{
"mime": "image/x-xpixmap",
"name": "X PixMap",
"ext": ".xpm"
},
{
"mime": "image/x-xwindowdump",
"name": "X Window Dump",
"ext": ".xwd"
},
{
"mime": "application/x-x509-ca-cert",
"name": "X.509 Certificate",
"ext": ".der"
},
{
"mime": "application/x-xfig",
"name": "Xfig",
"ext": ".fig"
},
{
"mime": "application/xhtml+xml",
"name": "XHTML - The Extensible HyperText Markup Language",
"ext": ".xhtml"
},
{
"mime": "application/xml",
"name": "XML - Extensible Markup Language",
"ext": ".xml"
},
{
"mime": "application/xcap-diff+xml",
"name": "XML Configuration Access Protocol - XCAP Diff",
"ext": ".xdf"
},
{
"mime": "application/xenc+xml",
"name": "XML Encryption Syntax and Processing",
"ext": ".xenc"
},
{
"mime": "application/patch-ops-error+xml",
"name": "XML Patch Framework",
"ext": ".xer"
},
{
"mime": "application/resource-lists+xml",
"name": "XML Resource Lists",
"ext": ".rl"
},
{
"mime": "application/rls-services+xml",
"name": "XML Resource Lists",
"ext": ".rs"
},
{
"mime": "application/resource-lists-diff+xml",
"name": "XML Resource Lists Diff",
"ext": ".rld"
},
{
"mime": "application/xslt+xml",
"name": "XML Transformations",
"ext": ".xslt"
},
{
"mime": "application/xop+xml",
"name": "XML-Binary Optimized Packaging",
"ext": ".xop"
},
{
"mime": "application/x-xpinstall",
"name": "XPInstall - Mozilla",
"ext": ".xpi"
},
{
"mime": "application/xspf+xml",
"name": "XSPF - XML Shareable Playlist Format",
"ext": ".xspf"
},
{
"mime": "application/vnd.mozilla.xul+xml",
"name": "XUL - XML User Interface Language",
"ext": ".xul"
},
{
"mime": "chemical/x-xyz",
"name": "XYZ File Format",
"ext": ".xyz"
},
{
"mime": "application/yang",
"name": "YANG Data Modeling Language",
"ext": ".yang"
},
{
"mime": "application/yin+xml",
"name": "YIN (YANG - XML)",
"ext": ".yin"
},
{
"mime": "application/vnd.zul",
"name": "Z.U.L. Geometry",
"ext": ".zir"
},
{
"mime": "application/zip",
"name": "Zip Archive",
"ext": ".zip"
},
{
"mime": "application/vnd.handheld-entertainment+xml",
"name": "ZVUE Media Manager",
"ext": ".zmm"
},
{
"mime": "application/vnd.zzazz.deck+xml",
"name": "Zzazz Deck",
"ext": ".zaz"
}
]
\ No newline at end of file
......@@ -321,12 +321,17 @@ module.exports = {
text: mark.removeMarkdown(pageData.markdown)
};
}).then((content) => {
return db.Entry.create({
return db.Entry.findOneAndUpdate({
_id: content.entryPath
}, {
_id: content.entryPath,
title: content.meta.title || content.entryPath,
subtitle: content.meta.subtitle || '',
parent: content.parent.title || '',
content: content.text || ''
}, {
new: true,
upsert: true
});
});
......@@ -430,6 +435,67 @@ module.exports = {
return _.replace(contents, new RegExp('{TITLE}', 'g'), formattedTitle);
});
},
/**
* Searches entries based on terms.
*
* @param {String} terms The terms to search for
* @return {Promise<Object>} Promise of the search results
*/
search(terms) {
let self = this;
terms = _.chain(terms)
.deburr()
.toLower()
.trim()
.replace(/[^a-z0-9\- ]/g, '')
.split(' ')
.filter((f) => { return !_.isEmpty(f); })
.join(' ')
.value();
return db.Entry.find(
{ $text: { $search: terms } },
{ score: { $meta: "textScore" }, title: 1 }
)
.sort({ score: { $meta: "textScore" } })
.limit(10)
.exec()
.then((hits) => {
if(hits.length < 5) {
let regMatch = new RegExp('^' + _.split(terms, ' ')[0]);
return db.Entry.find({
_id: { $regex: regMatch }
}, '_id')
.sort('_id')
.limit(5)
.exec()
.then((matches) => {
return {
match: hits,
suggest: (matches) ? _.map(matches, '_id') : []
};
});
} else {
return {
match: _.filter(hits, (h) => { return h._doc.score >= 1; }),
suggest: []
};
}
}).catch((err) => {
winston.error(err);
return {
match: [],
suggest: []
};
});
}
};
\ No newline at end of file
......@@ -23,7 +23,7 @@ module.exports = {
let self = this;
let dbModelsPath = path.resolve(ROOTPATH, 'models', 'db');
let dbModelsPath = path.resolve(ROOTPATH, 'models');
modb.Promise = require('bluebird');
......
......@@ -57,10 +57,7 @@ module.exports = {
let pInfo = self.parseUploadsRelPath(p);
return self.processFile(pInfo.folder, pInfo.filename).then((mData) => {
ws.emit('uploadsAddFiles', {
auth: WSInternalKey,
content: mData
});
return db.UplFile.create(mData);
}).then(() => {
return git.commitUploads('Uploaded ' + p);
});
......@@ -72,11 +69,9 @@ module.exports = {
self._watcher.on('unlink', (p) => {
let pInfo = self.parseUploadsRelPath(p);
return self.deleteFile(pInfo.folder, pInfo.filename).then((uID) => {
ws.emit('uploadsRemoveFiles', {
auth: WSInternalKey,
content: uID
});
return db.UplFile.findOneAndRemove({
folder: 'f:' + pInfo.folder,
filename: pInfo.filename
}).then(() => {
return git.commitUploads('Deleted ' + p);
});
......@@ -205,7 +200,7 @@ module.exports = {
category: 'image',
mime: mimeInfo.mime,
extra: _.pick(mImgData, ['format', 'width', 'height', 'density', 'hasAlpha', 'orientation']),
folder: null,
folder: 'f:' + fldName,
filename: f,
basename: fPathObj.name,
filesize: s.size
......
......@@ -41,25 +41,14 @@ module.exports = {
},
/**
* Sets the uploads folders.
*
* @param {Array<String>} arrFolders The arr folders
* @return {Void} Void
*/
setUploadsFolders(arrFolders) {
this._uploadsFolders = arrFolders;
return;
},
/**
* Gets the uploads folders.
*
* @return {Array<String>} The uploads folders.
*/
getUploadsFolders() {
return this._uploadsFolders;
return db.UplFolder.find({}, 'name').sort('name').exec().then((results) => {
return (results) ? _.map(results, 'name') : [{ name: '' }];
});
},
/**
......@@ -79,10 +68,14 @@ module.exports = {
}
return fs.ensureDirAsync(path.join(self._uploadsPath, folderName)).then(() => {
if(!_.includes(self._uploadsFolders, folderName)) {
self._uploadsFolders.push(folderName);
self._uploadsFolders = _.sortBy(self._uploadsFolders);
}
return db.UplFolder.findOneAndUpdate({
_id: 'f:' + folderName
}, {
name: folderName
}, {
upsert: true
});
}).then(() => {
return self.getUploadsFolders();
});
......@@ -96,32 +89,9 @@ module.exports = {
*/
validateUploadsFolder(folderName) {
if(_.includes(this._uploadsFolders, folderName)) {
return path.resolve(this._uploadsPath, folderName);
} else {
return false;
}
},
/**
* Sets the uploads files.
*
* @param {Array<Object>} arrFiles The uploads files
* @return {Void} Void
*/
setUploadsFiles(arrFiles) {
let self = this;
/*if(_.isArray(arrFiles) && arrFiles.length > 0) {
self._uploadsDb.Files.clear();
self._uploadsDb.Files.insert(arrFiles);
self._uploadsDb.Files.ensureIndex('category', true);
self._uploadsDb.Files.ensureIndex('folder', true);
}*/
return;
return db.UplFolder.findOne({ name: folderName }).then((f) => {
return (f) ? path.resolve(this._uploadsPath, folderName) : false;
})
},
......@@ -147,14 +117,30 @@ module.exports = {
*/
getUploadsFiles(cat, fld) {
return /*this._uploadsDb.Files.chain().find({
'$and': [{ 'category' : cat },{ 'folder' : fld }]
}).simplesort('filename').data()*/;
return db.UplFile.find({
category: cat,
folder: 'f:' + fld
}).sort('filename').exec();
},
deleteUploadsFile(fldName, f) {
/**
* Deletes an uploads file.
*
* @param {string} uid The file unique ID
* @return {Promise} Promise of the operation
*/
deleteUploadsFile(uid) {
let self = this;
return db.UplFile.findOneAndRemove({ _id: uid }).then((f) => {
if(f) {
fs.remove(path.join(self._uploadsThumbsPath, uid + '.png'));
fs.remove(path.resolve(self._uploadsPath, f.folder.slice(2), f.filename));
}
return true;
})
}
};
\ No newline at end of file
......@@ -11,8 +11,11 @@ const modb = require('mongoose'),
*/
var uplFolderSchema = modb.Schema({
_id: String,
name: {
type: String
type: String,
index: true
}
},
......
"use strict";
const Promise = require('bluebird'),
_ = require('lodash'),
path = require('path');
/**
* Search Model
*/
module.exports = {
_si: null,
/**
* Initialize Search model
*
* @param {Object} appconfig The application config
* @return {Object} Search model instance
*/
init(appconfig) {
let self = this;
return self;
},
find(terms) {
let self = this;
terms = _.chain(terms)
.deburr()
.toLower()
.trim()
.replace(/[^a-z0-9 ]/g, '')
.split(' ')
.filter((f) => { return !_.isEmpty(f); })
.join(' ')
.value();
return db.Entry.find(
{ $text: { $search: terms } },
{ score: { $meta: "textScore" }, title: 1 }
)
.sort({ score: { $meta: "textScore" } })
.limit(10)
.exec()
.then((hits) => {
/*if(hits.length < 5) {
return self._si.matchAsync({
beginsWith: terms,
threshold: 3,
limit: 5,
type: 'simple'
}).then((matches) => {
return {
match: hits,
suggest: matches
};
});
} else {*/
return {
match: hits,
suggest: []
};
//}
}).catch((err) => {
if(err.type === 'NotFoundError') {
return {
match: [],
suggest: []
};
} else {
winston.error(err);
}
});
},
/**
* Delete an entry from the index
*
* @param {String} The entry path
* @return {Promise} Promise of the operation
*/
delete(entryPath) {
let self = this;
/*let hasResults = false;
return new Promise((resolve, reject) => {
self._si.search({
query: {
AND: { 'entryPath': [entryPath] }
}
}).on('data', (results) => {
hasResults = true;
if(results.totalHits > 0) {
let delIds = _.map(results.hits, 'id');
self._si.del(delIds).on('end', () => { return resolve(true); });
} else {
resolve(true);
}
}).on('error', (err) => {
if(err.type === 'NotFoundError') {
resolve(true);
} else {
winston.error(err);
reject(err);
}
}).on('end', () => {
if(!hasResults) {
resolve(true);
}
});
});*/
}
};
\ No newline at end of file
"use strict";
// ===========================================
// REQUARKS WIKI
// 1.0.0
......@@ -11,52 +12,57 @@ global.PROCNAME = 'SERVER';
// Load Winston
// ----------------------------------------
var _isDebug = process.env.NODE_ENV === 'development';
global.winston = require('./lib/winston')(_isDebug);
const _isDebug = process.env.NODE_ENV === 'development';
global.winston = require('./libs/winston')(_isDebug);
winston.info('[SERVER] Requarks Wiki is initializing...');
// ----------------------------------------
// Load global modules
// ----------------------------------------
var appconfig = require('./models/config')('./config.yml');
global.lcdata = require('./models/server/local').init(appconfig);
global.db = require('./models/mongo').init(appconfig);
global.git = require('./models/git').init(appconfig, false);
global.entries = require('./models/entries').init(appconfig);
global.mark = require('./models/markdown');
var appconfig = require('./libs/config')('./config.yml');
global.lcdata = require('./libs/local').init(appconfig);
global.db = require('./libs/mongo').init(appconfig);
global.entries = require('./libs/entries').init(appconfig);
global.git = require('./libs/git').init(appconfig, false);
global.lang = require('i18next');
global.mark = require('./libs/markdown');
global.upl = require('./libs/uploads').init(appconfig);
// ----------------------------------------
// Load modules
// ----------------------------------------
var _ = require('lodash');
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var session = require('express-session');
const mongoStore = require('connect-mongo')(session);
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var flash = require('connect-flash');
var compression = require('compression');
var passport = require('passport');
var autoload = require('auto-load');
var expressValidator = require('express-validator');
var http = require('http');
global.lang = require('i18next');
var i18next_backend = require('i18next-node-fs-backend');
var i18next_mw = require('i18next-express-middleware');
const _ = require('lodash');
const autoload = require('auto-load');
const bodyParser = require('body-parser');
const compression = require('compression');
const cookieParser = require('cookie-parser');
const express = require('express');
const favicon = require('serve-favicon');
const flash = require('connect-flash');
const fork = require('child_process').fork;
const http = require('http');
const i18next_backend = require('i18next-node-fs-backend');
const i18next_mw = require('i18next-express-middleware');
const passport = require('passport');
const path = require('path');
const session = require('express-session');
const sessionMongoStore = require('connect-mongo')(session);
const socketio = require('socket.io');
var mw = autoload(path.join(ROOTPATH, '/middlewares'));
var ctrl = autoload(path.join(ROOTPATH, '/controllers'));
var libInternalAuth = require('./libs/internalAuth');
global.WSInternalKey = libInternalAuth.generateKey();
// ----------------------------------------
// Define Express App
// ----------------------------------------
global.app = express();
app.use(compression());
// ----------------------------------------
// Security
......@@ -65,15 +71,22 @@ global.app = express();
app.use(mw.security);
// ----------------------------------------
// Passport Authentication
// Public Assets
// ----------------------------------------
app.use(favicon(path.join(ROOTPATH, 'assets', 'favicon.ico')));
app.use(express.static(path.join(ROOTPATH, 'assets')));
// ----------------------------------------
// Session
// ----------------------------------------
var strategy = require('./models/auth')(passport, appconfig);
var strategy = require('./libs/auth')(passport, appconfig);
app.use(cookieParser());
app.use(session({
name: 'requarkswiki.sid',
store: new mongoStore({
store: new sessionMongoStore({
mongooseConnection: db.connection,
touchAfter: 15
}),
......@@ -109,22 +122,12 @@ lang
// View Engine Setup
// ----------------------------------------
app.use(compression());
app.use(i18next_mw.handle(lang));
app.set('views', path.join(ROOTPATH, 'views'));
app.set('view engine', 'pug');
app.use(favicon(path.join(ROOTPATH, 'assets', 'favicon.ico')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(expressValidator());
// ----------------------------------------
// Public Assets
// ----------------------------------------
app.use(express.static(path.join(ROOTPATH, 'assets')));
// ----------------------------------------
// View accessible data
......@@ -149,14 +152,12 @@ app.use('/', ctrl.pages);
// Error handling
// ----------------------------------------
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
......@@ -169,10 +170,12 @@ app.use(function(err, req, res, next) {
// Start HTTP server
// ----------------------------------------
winston.info('[SERVER] Starting HTTP server on port ' + appconfig.port + '...');
winston.info('[SERVER] Starting HTTP/WS server on port ' + appconfig.port + '...');
app.set('port', appconfig.port);
var server = http.createServer(app);
var io = socketio(server);
server.listen(appconfig.port);
server.on('error', (error) => {
if (error.syscall !== 'listen') {
......@@ -195,40 +198,21 @@ server.on('error', (error) => {
});
server.on('listening', () => {
winston.info('[SERVER] HTTP server started successfully! [RUNNING]');
winston.info('[SERVER] HTTP/WS server started successfully! [RUNNING]');
});
// ----------------------------------------
// Start child processes
// WebSocket handlers
// ----------------------------------------
var fork = require('child_process').fork,
libInternalAuth = require('./lib/internalAuth');
global.WSInternalKey = libInternalAuth.generateKey();
var wsSrv = fork('ws-server.js', [WSInternalKey]),
bgAgent = fork('agent.js', [WSInternalKey]);
process.on('exit', (code) => {
wsSrv.disconnect();
bgAgent.disconnect();
});
io.on('connection', ctrl.ws);
// ----------------------------------------
// Connect to local WebSocket server
// Start child processes
// ----------------------------------------
var wsClient = require('socket.io-client');
global.ws = wsClient('http://localhost:' + appconfig.wsPort, { reconnectionAttempts: 10 });
var bgAgent = fork('agent.js', [WSInternalKey]);
ws.on('connect', function () {
winston.info('[SERVER] Connected to WebSocket server successfully!');
});
ws.on('connect_error', function () {
winston.warn('[SERVER] Unable to connect to WebSocket server! Retrying...');
});
ws.on('reconnect_failed', function () {
winston.error('[SERVER] Failed to reconnect to WebSocket server too many times! Stopping...');
process.exit(1);
process.on('exit', (code) => {
bgAgent.disconnect();
});
\ No newline at end of file
......@@ -25,7 +25,7 @@ html
script(type='text/javascript', src='/js/libs.js')
script(type='text/javascript', src='/js/app.js')
script(type='text/javascript').
var ioHost = window.location.origin + ':!{appconfig.wsPort}/';
var ioHost = window.location.origin + ':!{appconfig.port}/';
block head
......
......@@ -17,7 +17,7 @@
span.icon.is-small: i.fa.fa-folder
span New Folder
.control.has-addons
a.button.is-info.is-outlined#btn-editor-uploadimage(v-on:click="uploadImage")
a.button.is-info.is-outlined#btn-editor-uploadimage
span.icon.is-small: i.fa.fa-upload
span Upload Image
label
......@@ -58,8 +58,8 @@
a.button.is-primary(title="Page Logo", v-on:click="selectAlignment('logo')", v-bind:class="{ 'is-outlined': currentAlign !== 'logo' }")
span.icon.is-small: i.fa.fa-external-link-square
.column.editor-modal-imagechoices
figure(v-for="img in images", v-bind:class="{ 'is-active': currentImage === img.uid }", v-on:click="selectImage(img.uid)")
img(v-bind:src="'/uploads/t/' + img.uid + '.png'")
figure(v-for="img in images", v-bind:class="{ 'is-active': currentImage === img._id }", v-on:click="selectImage(img._id)", v-bind:data-uid="img._id")
img(v-bind:src="'/uploads/t/' + img._id + '.png'")
span: strong {{ img.basename }}
span {{ img.filesize | filesize }}
em(v-show="images.length < 1") This folder is empty.
......@@ -96,4 +96,18 @@
span.help.is-danger.is-hidden This URL path is invalid!
footer.card-footer
a.card-footer-item(v-on:click="fetchFromUrlDiscard") Discard
a.card-footer-item(v-on:click="fetchFromUrlFetch") Fetch
\ No newline at end of file
a.card-footer-item(v-on:click="fetchFromUrlFetch") Fetch
.modal(v-bind:class="{ 'is-active': deleteImageShow }")
.modal-background
.modal-container
.modal-content
.card.is-fullwidth
header.card-header.is-danger
p.card-header-title Delete image?
.card-content
.content
| Are you sure you want to delete #[strong {{deleteImageFilename}}]?
footer.card-footer
a.card-footer-item(v-on:click="deleteImageWarn(false)") Discard
a.card-footer-item(v-on:click="deleteImageGo") Delete
\ No newline at end of file
// ===========================================
// REQUARKS WIKI - WebSocket Server
// 1.0.0
// Licensed under AGPLv3
// ===========================================
global.ROOTPATH = __dirname;
global.PROCNAME = 'WS';
// ----------------------------------------
// Load Winston
// ----------------------------------------
var _isDebug = process.env.NODE_ENV === 'development';
global.winston = require('./lib/winston')(_isDebug);
// ----------------------------------------
// Fetch internal handshake key
// ----------------------------------------
if(!process.argv[2] || process.argv[2].length !== 40) {
winston.error('[WS] Illegal process start. Missing handshake key.');
process.exit(1);
}
global.internalAuth = require('./lib/internalAuth').init(process.argv[2]);;
// ----------------------------------------
// Load global modules
// ----------------------------------------
winston.info('[WS] WS Server is initializing...');
var appconfig = require('./models/config')('./config.yml');
global.db = require('./models/mongo').init(appconfig);
global.upl = require('./models/ws/uploads').init(appconfig);
global.entries = require('./models/entries').init(appconfig);
global.mark = require('./models/markdown');
global.search = require('./models/ws/search').init(appconfig);
// ----------------------------------------
// Load local modules
// ----------------------------------------
var _ = require('lodash');
var express = require('express');
var path = require('path');
var http = require('http');
var socketio = require('socket.io');
var moment = require('moment');
// ----------------------------------------
// Define Express App
// ----------------------------------------
global.app = express();
// ----------------------------------------
// Controllers
// ----------------------------------------
app.get('/', function(req, res){
res.send('Requarks Wiki WebSocket server');
});
// ----------------------------------------
// Start WebSocket server
// ----------------------------------------
winston.info('[SERVER] Starting WebSocket server on port ' + appconfig.wsPort + '...');
app.set('port', appconfig.wsPort);
var server = http.Server(app);
var io = socketio(server);
server.on('error', (error) => {
if (error.syscall !== 'listen') {
throw error;
}
switch (error.code) {
case 'EACCES':
console.error('Listening on port ' + appconfig.port + ' requires elevated privileges!');
process.exit(1);
break;
case 'EADDRINUSE':
console.error('Port ' + appconfig.port + ' is already in use!');
process.exit(1);
break;
default:
throw error;
}
});
server.listen(appconfig.wsPort, () => {
winston.info('[WS] WebSocket server started successfully! [RUNNING]');
});
io.on('connection', (socket) => {
//-----------------------------------------
// SEARCH
//-----------------------------------------
socket.on('searchAdd', (data) => {
if(internalAuth.validateKey(data.auth)) {
search.add(data.content);
}
});
socket.on('searchDel', (data, cb) => {
cb = cb || _.noop;
if(internalAuth.validateKey(data.auth)) {
search.delete(data.entryPath);
}
});
socket.on('search', (data, cb) => {
cb = cb || _.noop;
search.find(data.terms).then((results) => {
cb(results);
});
});
//-----------------------------------------
// UPLOADS
//-----------------------------------------
socket.on('uploadsSetFolders', (data) => {
if(internalAuth.validateKey(data.auth)) {
upl.setUploadsFolders(data.content);
}
});
socket.on('uploadsGetFolders', (data, cb) => {
cb = cb || _.noop;
cb(upl.getUploadsFolders());
});
socket.on('uploadsValidateFolder', (data, cb) => {
cb = cb || _.noop;
if(internalAuth.validateKey(data.auth)) {
cb(upl.validateUploadsFolder(data.content));
}
});
socket.on('uploadsCreateFolder', (data, cb) => {
cb = cb || _.noop;
upl.createUploadsFolder(data.foldername).then((fldList) => {
cb(fldList);
});
});
socket.on('uploadsSetFiles', (data) => {
if(internalAuth.validateKey(data.auth)) {
upl.setUploadsFiles(data.content);
}
});
socket.on('uploadsAddFiles', (data) => {
if(internalAuth.validateKey(data.auth)) {
upl.addUploadsFiles(data.content);
}
});
socket.on('uploadsGetImages', (data, cb) => {
cb = cb || _.noop;
cb(upl.getUploadsFiles('image', data.folder));
});
});
// ----------------------------------------
// Shutdown gracefully
// ----------------------------------------
process.on('disconnect', () => {
winston.warn('[WS] Lost connection to main server. Exiting... [' + moment().toISOString() + ']');
server.close();
process.exit();
});
process.on('exit', () => {
server.stop();
});
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment