1
0
mirror of https://git.teknik.io/Teknikode/Teknik.git synced 2023-08-02 14:16:22 +02:00

Added Help pages.

This commit is contained in:
Uncled1023 2016-01-21 14:47:07 -08:00
parent 47cc6f3a9b
commit 7679851064
21 changed files with 1272 additions and 0 deletions

View File

@ -0,0 +1,63 @@
.api {
color: #393939;
font-size: 14px;
line-height: 1.5em;
}
.api pre {
border: 1px solid #cacaca;
font: 12px/1.4em Consolas, "Liberation Mono", Courier, monospace;
padding: 10px;
overflow: auto;
border-radius: 3px;
background-color: #fafafb;
color: #393939;
margin: 2em 0;
}
.api pre code {
white-space: pre;
}
.api table {
width: 100%;
display: block;
margin: 15px 0;
}
.api tbody {
vertical-align: middle;
border-color: inherit;
}
.api thead {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
.api table tr {
border-top: 1px solid #ccc;
background-color: #fff;
vertical-align: inherit;
}
.api table th {
border: 1px solid #ddd;
padding: 6px 13px;
font-weight: bold;
text-align: center;
}
.api table td {
border: 1px solid #ddd;
padding: 6px 13px;
}
.api code {
white-space: nowrap;
font: 12px Consolas, "Liberation Mono", Courier, monospace;
}

View File

@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Teknik.Areas.Help.ViewModels;
using Teknik.Controllers;
namespace Teknik.Areas.Help.Controllers
{
public class HelpController : DefaultController
{
// GET: Help/Help
[AllowAnonymous]
public ActionResult Index()
{
ViewBag.Title = "Help - " + Config.Title;
HelpViewModel model = new HelpViewModel();
return View(model);
}
[AllowAnonymous]
public ActionResult Topic(string topic)
{
ViewBag.Title = topic + " Help - " + Config.Title;
HelpViewModel model = new HelpViewModel();
string view = string.Empty;
switch(topic.ToLower())
{
case "api":
view = "~/Areas/Help/Views/Help/Api.cshtml";
break;
case "blog":
view = "~/Areas/Help/Views/Help/Blog.cshtml";
break;
case "git":
view = "~/Areas/Help/Views/Help/Git.cshtml";
break;
case "irc":
view = "~/Areas/Help/Views/Help/Irc.cshtml";
break;
case "mail":
view = "~/Areas/Help/Views/Help/Mail.cshtml";
break;
case "mumble":
view = "~/Areas/Help/Views/Help/Mumble.cshtml";
break;
case "upload":
view = "~/Areas/Help/Views/Help/Upload.cshtml";
break;
default:
break;
}
if (!string.IsNullOrEmpty(view))
{
return View(view, model);
}
return RedirectToRoute("*.Error.Http404");
}
}
}

View File

@ -0,0 +1,52 @@
using System.Web.Mvc;
using System.Web.Optimization;
namespace Teknik.Areas.Help
{
public class HelpAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Help";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapSubdomainRoute(
"Help.Index", // Route name
"dev",
"Help", // URL with parameters
new { controller = "Help", action = "Index" }, // Parameter defaults
new[] { typeof(Controllers.HelpController).Namespace }
);
context.MapSubdomainRoute(
"Help.Topic", // Route name
"dev",
"Help/{topic}", // URL with parameters
new { controller = "Help", action = "Topic" }, // Parameter defaults
new[] { typeof(Controllers.HelpController).Namespace }
);
context.MapSubdomainRoute(
"Help.Index", // Route name
"help",
"", // URL with parameters
new { controller = "Help", action = "Index" }, // Parameter defaults
new[] { typeof(Controllers.HelpController).Namespace }
);
context.MapSubdomainRoute(
"Help.Topic", // Route name
"help",
"{topic}", // URL with parameters
new { controller = "Help", action = "Topic" }, // Parameter defaults
new[] { typeof(Controllers.HelpController).Namespace }
);
// Register Style Bundles
BundleTable.Bundles.Add(new StyleBundle("~/Content/help").Include(
"~/Areas/Help/Content/Help.css"));
}
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Teknik.ViewModels;
namespace Teknik.Areas.Help.ViewModels
{
public class HelpViewModel : ViewModelBase
{
}
}

View File

@ -0,0 +1,211 @@
@model Teknik.Areas.Help.ViewModels.HelpViewModel
@Styles.Render("~/Content/help");
<div class="container">
<div class="row api">
<h2><b>Teknik API</b></h2>
<hr>
<h3>Overview</h3>
<p>
The Teknik API is free for everyone to use, and is defined on a per service basis.
<br />
<br />
The general API calls can be summarized as follows: <code>@Url.SubRouteUrl("api", "Api.Index", new { service = "<b>Service</b>", action = "<b>Action</b>", version = Model.Config.ApiConfig.Version })</code>
</p>
<h4>Responses</h4>
<p>
All responses are returned as json. The returned json can contain any of the following sections.
<br />
<br />
<strong>Results</strong>
<pre><code>{"results":{"&lt;resultType&gt;":{"&lt;resultData&gt;":"&lt;value&gt;"}}}</code></pre>
<strong>Errors</strong>
<pre><code>{"error":{"code":&lt;value&gt;, "message":"&lt;errorMessage&gt;"}}</code></pre>
</p>
<h3><b>Upload</b></h3>
<hr>
<p>This is a description of the API commands available for the Upload service.</p>
<h4>Upload a File</h4>
<pre><code>POST @Url.SubRouteUrl("api", "Api.Index", new { service = "Upload", action = "Post", version = Model.Config.ApiConfig.Version })</code></pre>
<h5>Parameters</h5>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>file</code>
</td>
<td>
<code>file</code>
</td>
<td>
<var>NULL</var>
</td>
<td>
<strong>Required</strong>
The file that you would like to upload.
</td>
</tr>
<tr>
<td>
<code>encrypt</code>
</td>
<td>
<code>string</code>
</td>
<td>
<var>no</var>
</td>
<td>
If you want the file to be encrypted server side. This will regenerate the key and/or iv if none are passed in. Choose <code>yes</code> or <code>no</code>
</td>
</tr>
<tr>
<td>
<code>key</code>
</td>
<td>
<code>string</code>
</td>
<td>
<var>NULL</var>
</td>
<td>
If you want the file to be decrypted server side, include the key.
</td>
</tr>
<tr>
<td>
<code>iv</code>
</td>
<td>
<code>string</code>
</td>
<td>
<var>NULL</var>
</td>
<td>
If the file has been encrypted and you want it decrypted (Both Server and Client Side), include the iv.
</td>
</tr>
<tr>
<td>
<code>getDeletionKey</code>
</td>
<td>
<code>string</code>
</td>
<td>
<var>no</var>
</td>
<td>
Whether you would like to create a deletion link. Choose <code>yes</code> or <code>no</code>
</td>
</tr>
</tbody>
</table>
<h5>Response</h5>
<pre><code>{"results":{"file":{"name":"<var>file_name</var>", "url":"<var>url</var>", "type":"<var>file_type</var>", "size":<var>size</var>, "key":<var>key</var>, "iv":<var>iv</var>, "deletionKey":<var>deletion_key</var>}}}</code></pre>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>name</code>
</td>
<td>
<code>string</code>
</td>
<td>
The filename of the uploaded file.
</td>
</tr>
<tr>
<td>
<code>url</code>
</td>
<td>
<code>string</code>
</td>
<td>
The direct url to the uploaded file. The key is apended to the url as an anchor tag.
</td>
</tr>
<tr>
<td>
<code>type</code>
</td>
<td>
<code>string</code>
</td>
<td>
The MIME file type of the uploaded file.
</td>
</tr>
<tr>
<td>
<code>size</code>
</td>
<td>
<code>integer</code>
</td>
<td>
The size of the uploaded file in bytes.
</td>
</tr>
<tr>
<td>
<code>key</code>
</td>
<td>
<code>string</code>
</td>
<td>
The key that was used to encrypt the file.
</td>
</tr>
<tr>
<td>
<code>iv</code>
</td>
<td>
<code>string</code>
</td>
<td>
The iv that was used to encrypt the file.
</td>
</tr>
<tr>
<td>
<code>deletionKey</code>
</td>
<td>
<code>string</code>
</td>
<td>
<strong>Optional</strong>
The deletion key for file. Use it as follows: <code>@Url.SubRouteUrl("u", "Upload.Upload", new { file = "<var>file.jpg</var>", key = "<var>deletionKey</var>" })</code>
</td>
</tr>
</tbody>
</table>
<h5>Example</h5>
<pre><code>$ curl -F "getDeletionKey=yes" -F "encrypt=yes" -F "file=@("@")image.png" @Url.SubRouteUrl("api", "Api.Index", new { service = "Upload", version = Model.Config.ApiConfig.Version })</code></pre>
<br />
<br />
</div>
</div>

View File

@ -0,0 +1,12 @@
@model Teknik.Areas.Help.ViewModels.HelpViewModel
<div class="container">
<div class="row">
<h2><b>Blogging</b></h2>
<hr>
<h3>Formatting</h3>
<p>
Each article uses a basic Markdown formatter to display the information. Any Html or script information will be stripped from the post before displaying.
</p>
</div>
</div>

View File

@ -0,0 +1,12 @@
@model Teknik.Areas.Help.ViewModels.HelpViewModel
<div class="container">
<div class="row">
<h2><b>Git</b></h2>
<hr>
<h3>Authorization</h3>
<p>
To login into your git account, you will initially need to initially use your teknik email address to login using the web interface. Once you have done so at least once, you can from then on use your teknik username.
</p>
</div>
</div>

View File

@ -0,0 +1,35 @@
@model Teknik.Areas.Help.ViewModels.HelpViewModel
<div class="container">
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<h2 class="text-center">Teknik Services</h2>
<hr>
<h3 class="text-center">Important Links</h3>
<dl class="dl-horizontal">
<dt><a href="@Url.SubRouteUrl("transparency", "Transparency.Index")" target="_blank">Site Transparency</a></dt>
<dd>All the site's transactions, statistics, and data effecting actions.</dd>
<dt><a href="@Url.SubRouteUrl("privacy", "Privacy.Index")" target="_blank">Privacy Policy</a></dt>
<dd>Everything about how we handle your privacy.</dd>
</dl>
<hr>
<h3 class="text-center">Help Topics</h3>
<dl class="dl-horizontal">
<dt><a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "Api" })">Api</a></dt>
<dd>Open API available to interact with the difference services.</dd>
<dt><a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "Blog" })">Blogging</a></dt>
<dd>Blogging platform available to the users and visible to the public.</dd>
<dt><a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "Git" })">Git Repositories</a></dt>
<dd>All the site's transactions, statistics, and data effecting actions.</dd>
<dt><a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "Irc" })">Irc Network</a></dt>
<dd>All the site's transactions, statistics, and data effecting actions.</dd>
<dt><a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "Mail" })">Mail Server</a></dt>
<dd>All the site's transactions, statistics, and data effecting actions.</dd>
<dt><a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "Mumble" })">Mumble Chat Server</a></dt>
<dd>The public Mumble server and configuration settings needed.</dd>
<dt><a href="@Url.SubRouteUrl("help", "Help.Topic", new { topic = "Upload" })">Uploads</a></dt>
<dd>How the Upload service works and special considerations.</dd>
</dl>
</div>
</div>
</div>

View File

@ -0,0 +1,16 @@
@model Teknik.Areas.Help.ViewModels.HelpViewModel
<div class="container">
<div class="row">
<h2><b>IRC</b></h2>
<hr>
<h3>IRC Server Info</h3>
<p>
You can connect to the Teknik IRC using any RFC compliant client by connecting to <b>irc.@Model.Config.Host</b> on port <b>6667</b>.
</p>
<h3>Channel Information</h3>
<p>
The main channel for Teknik support is located at #teknik.
</p>
</div>
</div>

View File

@ -0,0 +1,69 @@
@model Teknik.Areas.Help.ViewModels.HelpViewModel
<div class="container">
<div class="row">
<h2><b>Mail</b></h2>
<hr>
<h3>Mail Server Settings</h3>
<p>
At registration, each user is given an email address with <b>1 GB</b> of storage space.
You can either access your email via the <a href="@Url.SubRouteUrl("mail", "Mail.Index")" target="_blank">Web Client</a> or by using a client of your choosing with support for IMAP or POP3.
</p>
<div class="row">
<div class="col-md-12">
<ul class="list-group">
<li class="list-group-item text-center"><h4>Outlook</h4></li>
<br />
<div class="col-sm-6">
<ul class="list-group">
<li class="list-group-item text-center">User Information</li>
<li class="list-group-item">Email Address:<div class="pull-right"><b>@string.Format("[username]@{0}", Model.Config.Host)</b></div></li>
<li class="list-group-item text-center">Server Information</li>
<li class="list-group-item">Incoming Server:<div class="pull-right"><b>@Model.Config.SMTPConfig.Host</b></div></li>
<li class="list-group-item">Outgoing Server:<div class="pull-right"><b>@Model.Config.SMTPConfig.Host</b></div></li>
</ul>
</div>
<div class="col-sm-6">
<ul class="list-group">
<li class="list-group-item text-center">Logon Information</li>
<li class="list-group-item">Username:<div class="pull-right"><b>@string.Format("[username]@{0}", Model.Config.Host)</b></div></li>
<li class="list-group-item">Password:<div class="pull-right"><b>[password]</b></div></li>
<li class="list-group-item text-center">More Settings</li>
<li class="list-group-item">Requires Authentication:<div class="pull-right"><b>Both</b></div></li>
<li class="list-group-item">Incoming Server (IMAP):<div class="pull-right"><b>143 (993 SSL)</b></div></li>
<li class="list-group-item">Outgoing Server (SMTP):<div class="pull-right"><b>25 (465 SSL)</b></div></li>
</ul>
</div>
</ul>
</div>
</div>
<div class="row">
<div class="col-md-12">
<ul class="list-group">
<li class="list-group-item text-center"><h4>Thunderbird</h4></li>
<br />
<div class="col-sm-6">
<ul class="list-group">
<li class="list-group-item text-center">Server Settings</li>
<li class="list-group-item">Server Name:<div class="pull-right"><b>@Model.Config.SMTPConfig.Host</b></div></li>
<li class="list-group-item">Port:<div class="pull-right"><b>143 (993 SSL)</b></div></li>
<li class="list-group-item">User Name:<div class="pull-right"><b>@string.Format("[username]@{0}", Model.Config.Host)</b></div></li>
<li class="list-group-item">Connection Security:<div class="pull-right"><b>None (SSL/TLS)</b></div></li>
<li class="list-group-item">Authentication method:<div class="pull-right"><b>Password</b></div></li>
</ul>
</div>
<div class="col-sm-6">
<ul class="list-group">
<li class="list-group-item text-center">Outgoing Server (SMTP)</li>
<li class="list-group-item">Server Name:<div class="pull-right"><b>@Model.Config.SMTPConfig.Host</b></div></li>
<li class="list-group-item">Port:<div class="pull-right"><b>25 (465 SSL)</b></div></li>
<li class="list-group-item">User Name:<div class="pull-right"><b>@string.Format("[username]@{0}", Model.Config.Host)</b></div></li>
<li class="list-group-item">Connection Security:<div class="pull-right"><b>None (SSL/TLS)</b></div></li>
<li class="list-group-item">Authentication method:<div class="pull-right"><b>Password</b></div></li>
</ul>
</div>
</ul>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,12 @@
@model Teknik.Areas.Help.ViewModels.HelpViewModel
<div class="container">
<div class="row">
<h2><b>Mumble</b></h2>
<hr>
<h3>Mumble Server Info</h3>
<p>
You can connect to the Mumble server by connecting to <b>mumble.@Model.Config.Host</b> on port <b>64738</b>.
</p>
</div>
</div>

View File

@ -0,0 +1,37 @@
@model Teknik.Areas.Help.ViewModels.HelpViewModel
<div class="container">
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<h2 class="text-center"><b>Uploads</b></h2>
<hr>
<h3>Encryption Method</h3>
<br />
<h4>Using the Browser (Client Side Encryption)</h4>
<p>
When you using the web interface for uploads, the file is loaded using the javascript <a href="https://developer.mozilla.org/en-US/docs/Web/API/FileReader">FileReader</a> API.
</p>
<p>
Once the file is completely loaded into the buffer, a key and iv are generated by a random string generator to create a key that is <b>@Model.Config.UploadConfig.KeySize</b> Bytes and an iv (Block Size) that is <b>@Model.Config.UploadConfig.BlockSize</b> Bytes.
Then the file buffer, key, and iv are passed into a Web Worker for encryption.
</p>
<p>
The file data is passed through a progressive ciphering with a chunk size of <b>@Model.Config.UploadConfig.ChunkSize</b> bytes. This is to help reduce the memory usage needed by the encryption process as it only needs to process and convert each chunk instead of the entire file.
</p>
<p>
Once all the file's data has been processed, the final buffer is then passed back to the main encryption routine and is sent to the server as a ArrayBuffer, along with the content-type, generated iv, key size, and block size.
</p>
<p>
Once the data has been recieved by the server, a unique URL name and unique local filename are generated and saved to the database along with the passed up cipher information. The File Data is then written to the server and the resulting URL is passed back to the client.
</p>
<p>
When the client recieves the returned URL, it then appends the generated key to the URL as an anchor tag and updates the UI to display the final URL.
</p>
<br />
<h3>Cipher Properties</h3>
<p>
The encryption library being used is <a href="http://code.google.com/p/crypto-js/">Crypto-JS</a> and the cipher being used is <b>AES-@Model.Config.UploadConfig.KeySize</b> using the mode <b>CTR</b>. The variant of AES is determined by the size of the key used (128, 192, or 256).
</p>
</div>
</div>
</div>

View File

@ -0,0 +1,3 @@
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}

View File

@ -0,0 +1,36 @@
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.Optimization" />
<add namespace="Teknik" />
</namespaces>
</pages>
</system.web.webPages.razor>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.webServer>
<handlers>
<remove name="BlockViewHandler"/>
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
</handlers>
</system.webServer>
</configuration>

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Teknik.Configuration
{
public class ApiConfig
{
public int Version { get; set; }
public ApiConfig()
{
Version = 1;
}
}
}

View File

@ -20,6 +20,7 @@ namespace Teknik.Configuration
private SMTPConfig _SMTPConfig;
private UploadConfig _UploadConfig;
private BlogConfig _BlogConfig;
private ApiConfig _ApiConfig;
private string _SupportEmail;
private string _BitcoinAddress;
private string _BlogTitle;
@ -50,6 +51,9 @@ namespace Teknik.Configuration
// Upload Configuration
public UploadConfig UploadConfig { get { return _UploadConfig; } set { _UploadConfig = value; } }
// Upload Configuration
public ApiConfig ApiConfig { get { return _ApiConfig; } set { _ApiConfig = value; } }
public Config()
{
_ConfigRWLock = new ReaderWriterLockSlim();
@ -70,6 +74,7 @@ namespace Teknik.Configuration
SMTPConfig = new SMTPConfig();
BlogConfig = new BlogConfig();
UploadConfig = new UploadConfig();
ApiConfig = new ApiConfig();
SupportEmail = string.Empty;
BitcoinAddress = string.Empty;
}

View File

@ -0,0 +1,75 @@
/*
* jquery.tocify.css 1.9.1
* Author: @gregfranko
*/
/* The Table of Contents container element */
.tocify {
width: 20%;
max-height: 90%;
overflow: auto;
margin-left: 2%;
position: fixed;
border: 1px solid #ccc;
webkit-border-radius: 6px;
moz-border-radius: 6px;
border-radius: 6px;
}
/* The Table of Contents is composed of multiple nested unordered lists. These styles remove the default styling of an unordered list because it is ugly. */
.tocify ul, .tocify li {
list-style: none;
margin: 0;
padding: 0;
border: none;
line-height: 30px;
}
/* Top level header elements */
.tocify-header {
text-indent: 10px;
}
/* Top level subheader elements. These are the first nested items underneath a header element. */
.tocify-subheader {
text-indent: 20px;
display: none;
}
/* Makes the font smaller for all subheader elements. */
.tocify-subheader li {
font-size: 12px;
}
/* Further indents second level subheader elements. */
.tocify-subheader .tocify-subheader {
text-indent: 30px;
}
/* Further indents third level subheader elements. You can continue this pattern if you have more nested elements. */
.tocify-subheader .tocify-subheader .tocify-subheader {
text-indent: 40px;
}
/* Twitter Bootstrap Override Style */
.tocify .tocify-item > a, .tocify .nav-list .nav-header {
margin: 0px;
}
/* Twitter Bootstrap Override Styles */
.tocify .tocify-item a, .tocify .list-group-item {
padding: 5px;
}
.tocify .nav-pills > li {
float: none;
}
.tocify .list-group-item:hover, .tocify .list-group-item:focus {
background-color: #f5f5f5;
}
.tocify .list-group-item.active:hover, .tocify .list-group-item.active:focus {
background-color: #428bca;
}
/* End Twitter Bootstrap Override Styles */

Binary file not shown.

516
Teknik/Scripts/jquery-ui.widgets.js vendored Normal file
View File

@ -0,0 +1,516 @@
/*! jQuery UI - v1.10.4 - 2014-04-26
* http://jqueryui.com
* Includes: jquery.ui.widget.js
* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
(function( $, undefined ) {
var uuid = 0,
slice = Array.prototype.slice,
_cleanData = $.cleanData;
$.cleanData = function( elems ) {
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
try {
$( elem ).triggerHandler( "remove" );
// http://bugs.jquery.com/ticket/8235
} catch( e ) {}
}
_cleanData( elems );
};
$.widget = function( name, base, prototype ) {
var fullName, existingConstructor, constructor, basePrototype,
// proxiedPrototype allows the provided prototype to remain unmodified
// so that it can be used as a mixin for multiple widgets (#8876)
proxiedPrototype = {},
namespace = name.split( "." )[ 0 ];
name = name.split( "." )[ 1 ];
fullName = namespace + "-" + name;
if ( !prototype ) {
prototype = base;
base = $.Widget;
}
// create selector for plugin
$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
return !!$.data( elem, fullName );
};
$[ namespace ] = $[ namespace ] || {};
existingConstructor = $[ namespace ][ name ];
constructor = $[ namespace ][ name ] = function( options, element ) {
// allow instantiation without "new" keyword
if ( !this._createWidget ) {
return new constructor( options, element );
}
// allow instantiation without initializing for simple inheritance
// must use "new" keyword (the code above always passes args)
if ( arguments.length ) {
this._createWidget( options, element );
}
};
// extend with the existing constructor to carry over any static properties
$.extend( constructor, existingConstructor, {
version: prototype.version,
// copy the object used to create the prototype in case we need to
// redefine the widget later
_proto: $.extend( {}, prototype ),
// track widgets that inherit from this widget in case this widget is
// redefined after a widget inherits from it
_childConstructors: []
});
basePrototype = new base();
// we need to make the options hash a property directly on the new instance
// otherwise we'll modify the options hash on the prototype that we're
// inheriting from
basePrototype.options = $.widget.extend( {}, basePrototype.options );
$.each( prototype, function( prop, value ) {
if ( !$.isFunction( value ) ) {
proxiedPrototype[ prop ] = value;
return;
}
proxiedPrototype[ prop ] = (function() {
var _super = function() {
return base.prototype[ prop ].apply( this, arguments );
},
_superApply = function( args ) {
return base.prototype[ prop ].apply( this, args );
};
return function() {
var __super = this._super,
__superApply = this._superApply,
returnValue;
this._super = _super;
this._superApply = _superApply;
returnValue = value.apply( this, arguments );
this._super = __super;
this._superApply = __superApply;
return returnValue;
};
})();
});
constructor.prototype = $.widget.extend( basePrototype, {
// TODO: remove support for widgetEventPrefix
// always use the name + a colon as the prefix, e.g., draggable:start
// don't prefix for widgets that aren't DOM-based
widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
}, proxiedPrototype, {
constructor: constructor,
namespace: namespace,
widgetName: name,
widgetFullName: fullName
});
// If this widget is being redefined then we need to find all widgets that
// are inheriting from it and redefine all of them so that they inherit from
// the new version of this widget. We're essentially trying to replace one
// level in the prototype chain.
if ( existingConstructor ) {
$.each( existingConstructor._childConstructors, function( i, child ) {
var childPrototype = child.prototype;
// redefine the child widget using the same prototype that was
// originally used, but inherit from the new version of the base
$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
});
// remove the list of existing child constructors from the old constructor
// so the old child constructors can be garbage collected
delete existingConstructor._childConstructors;
} else {
base._childConstructors.push( constructor );
}
$.widget.bridge( name, constructor );
};
$.widget.extend = function( target ) {
var input = slice.call( arguments, 1 ),
inputIndex = 0,
inputLength = input.length,
key,
value;
for ( ; inputIndex < inputLength; inputIndex++ ) {
for ( key in input[ inputIndex ] ) {
value = input[ inputIndex ][ key ];
if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
// Clone objects
if ( $.isPlainObject( value ) ) {
target[ key ] = $.isPlainObject( target[ key ] ) ?
$.widget.extend( {}, target[ key ], value ) :
// Don't extend strings, arrays, etc. with objects
$.widget.extend( {}, value );
// Copy everything else by reference
} else {
target[ key ] = value;
}
}
}
}
return target;
};
$.widget.bridge = function( name, object ) {
var fullName = object.prototype.widgetFullName || name;
$.fn[ name ] = function( options ) {
var isMethodCall = typeof options === "string",
args = slice.call( arguments, 1 ),
returnValue = this;
// allow multiple hashes to be passed on init
options = !isMethodCall && args.length ?
$.widget.extend.apply( null, [ options ].concat(args) ) :
options;
if ( isMethodCall ) {
this.each(function() {
var methodValue,
instance = $.data( this, fullName );
if ( !instance ) {
return $.error( "cannot call methods on " + name + " prior to initialization; " +
"attempted to call method '" + options + "'" );
}
if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
return $.error( "no such method '" + options + "' for " + name + " widget instance" );
}
methodValue = instance[ options ].apply( instance, args );
if ( methodValue !== instance && methodValue !== undefined ) {
returnValue = methodValue && methodValue.jquery ?
returnValue.pushStack( methodValue.get() ) :
methodValue;
return false;
}
});
} else {
this.each(function() {
var instance = $.data( this, fullName );
if ( instance ) {
instance.option( options || {} )._init();
} else {
$.data( this, fullName, new object( options, this ) );
}
});
}
return returnValue;
};
};
$.Widget = function( /* options, element */ ) {};
$.Widget._childConstructors = [];
$.Widget.prototype = {
widgetName: "widget",
widgetEventPrefix: "",
defaultElement: "<div>",
options: {
disabled: false,
// callbacks
create: null
},
_createWidget: function( options, element ) {
element = $( element || this.defaultElement || this )[ 0 ];
this.element = $( element );
this.uuid = uuid++;
this.eventNamespace = "." + this.widgetName + this.uuid;
this.options = $.widget.extend( {},
this.options,
this._getCreateOptions(),
options );
this.bindings = $();
this.hoverable = $();
this.focusable = $();
if ( element !== this ) {
$.data( element, this.widgetFullName, this );
this._on( true, this.element, {
remove: function( event ) {
if ( event.target === element ) {
this.destroy();
}
}
});
this.document = $( element.style ?
// element within the document
element.ownerDocument :
// element is window or document
element.document || element );
this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
}
this._create();
this._trigger( "create", null, this._getCreateEventData() );
this._init();
},
_getCreateOptions: $.noop,
_getCreateEventData: $.noop,
_create: $.noop,
_init: $.noop,
destroy: function() {
this._destroy();
// we can probably remove the unbind calls in 2.0
// all event bindings should go through this._on()
this.element
.unbind( this.eventNamespace )
// 1.9 BC for #7810
// TODO remove dual storage
.removeData( this.widgetName )
.removeData( this.widgetFullName )
// support: jquery <1.6.3
// http://bugs.jquery.com/ticket/9413
.removeData( $.camelCase( this.widgetFullName ) );
this.widget()
.unbind( this.eventNamespace )
.removeAttr( "aria-disabled" )
.removeClass(
this.widgetFullName + "-disabled " +
"ui-state-disabled" );
// clean up events and states
this.bindings.unbind( this.eventNamespace );
this.hoverable.removeClass( "ui-state-hover" );
this.focusable.removeClass( "ui-state-focus" );
},
_destroy: $.noop,
widget: function() {
return this.element;
},
option: function( key, value ) {
var options = key,
parts,
curOption,
i;
if ( arguments.length === 0 ) {
// don't return a reference to the internal hash
return $.widget.extend( {}, this.options );
}
if ( typeof key === "string" ) {
// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
options = {};
parts = key.split( "." );
key = parts.shift();
if ( parts.length ) {
curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
for ( i = 0; i < parts.length - 1; i++ ) {
curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
curOption = curOption[ parts[ i ] ];
}
key = parts.pop();
if ( arguments.length === 1 ) {
return curOption[ key ] === undefined ? null : curOption[ key ];
}
curOption[ key ] = value;
} else {
if ( arguments.length === 1 ) {
return this.options[ key ] === undefined ? null : this.options[ key ];
}
options[ key ] = value;
}
}
this._setOptions( options );
return this;
},
_setOptions: function( options ) {
var key;
for ( key in options ) {
this._setOption( key, options[ key ] );
}
return this;
},
_setOption: function( key, value ) {
this.options[ key ] = value;
if ( key === "disabled" ) {
this.widget()
.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
.attr( "aria-disabled", value );
this.hoverable.removeClass( "ui-state-hover" );
this.focusable.removeClass( "ui-state-focus" );
}
return this;
},
enable: function() {
return this._setOption( "disabled", false );
},
disable: function() {
return this._setOption( "disabled", true );
},
_on: function( suppressDisabledCheck, element, handlers ) {
var delegateElement,
instance = this;
// no suppressDisabledCheck flag, shuffle arguments
if ( typeof suppressDisabledCheck !== "boolean" ) {
handlers = element;
element = suppressDisabledCheck;
suppressDisabledCheck = false;
}
// no element argument, shuffle and use this.element
if ( !handlers ) {
handlers = element;
element = this.element;
delegateElement = this.widget();
} else {
// accept selectors, DOM elements
element = delegateElement = $( element );
this.bindings = this.bindings.add( element );
}
$.each( handlers, function( event, handler ) {
function handlerProxy() {
// allow widgets to customize the disabled handling
// - disabled as an array instead of boolean
// - disabled class as method for disabling individual parts
if ( !suppressDisabledCheck &&
( instance.options.disabled === true ||
$( this ).hasClass( "ui-state-disabled" ) ) ) {
return;
}
return ( typeof handler === "string" ? instance[ handler ] : handler )
.apply( instance, arguments );
}
// copy the guid so direct unbinding works
if ( typeof handler !== "string" ) {
handlerProxy.guid = handler.guid =
handler.guid || handlerProxy.guid || $.guid++;
}
var match = event.match( /^(\w+)\s*(.*)$/ ),
eventName = match[1] + instance.eventNamespace,
selector = match[2];
if ( selector ) {
delegateElement.delegate( selector, eventName, handlerProxy );
} else {
element.bind( eventName, handlerProxy );
}
});
},
_off: function( element, eventName ) {
eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
element.unbind( eventName ).undelegate( eventName );
},
_delay: function( handler, delay ) {
function handlerProxy() {
return ( typeof handler === "string" ? instance[ handler ] : handler )
.apply( instance, arguments );
}
var instance = this;
return setTimeout( handlerProxy, delay || 0 );
},
_hoverable: function( element ) {
this.hoverable = this.hoverable.add( element );
this._on( element, {
mouseenter: function( event ) {
$( event.currentTarget ).addClass( "ui-state-hover" );
},
mouseleave: function( event ) {
$( event.currentTarget ).removeClass( "ui-state-hover" );
}
});
},
_focusable: function( element ) {
this.focusable = this.focusable.add( element );
this._on( element, {
focusin: function( event ) {
$( event.currentTarget ).addClass( "ui-state-focus" );
},
focusout: function( event ) {
$( event.currentTarget ).removeClass( "ui-state-focus" );
}
});
},
_trigger: function( type, event, data ) {
var prop, orig,
callback = this.options[ type ];
data = data || {};
event = $.Event( event );
event.type = ( type === this.widgetEventPrefix ?
type :
this.widgetEventPrefix + type ).toLowerCase();
// the original event may come from any element
// so we need to reset the target on the new event
event.target = this.element[ 0 ];
// copy original event properties over to the new event
orig = event.originalEvent;
if ( orig ) {
for ( prop in orig ) {
if ( !( prop in event ) ) {
event[ prop ] = orig[ prop ];
}
}
}
this.element.trigger( event, data );
return !( $.isFunction( callback ) &&
callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
event.isDefaultPrevented() );
}
};
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
if ( typeof options === "string" ) {
options = { effect: options };
}
var hasOptions,
effectName = !options ?
method :
options === true || typeof options === "number" ?
defaultEffect :
options.effect || defaultEffect;
options = options || {};
if ( typeof options === "number" ) {
options = { duration: options };
}
hasOptions = !$.isEmptyObject( options );
options.complete = callback;
if ( options.delay ) {
element.delay( options.delay );
}
if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
element[ method ]( options );
} else if ( effectName !== method && element[ effectName ] ) {
element[ effectName ]( options.duration, options.easing, callback );
} else {
element.queue(function( next ) {
$( this )[ method ]();
if ( callback ) {
callback.call( element[ 0 ] );
}
next();
});
}
};
});
})( jQuery );

4
Teknik/Scripts/jquery.tocify.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -160,6 +160,9 @@
<Compile Include="Areas\Error\Controllers\ErrorController.cs" />
<Compile Include="Areas\Error\ErrorAreaRegistration.cs" />
<Compile Include="Areas\Error\ViewModels\ErrorViewModel.cs" />
<Compile Include="Areas\Help\Controllers\HelpController.cs" />
<Compile Include="Areas\Help\HelpAreaRegistration.cs" />
<Compile Include="Areas\Help\ViewModels\HelpViewModel.cs" />
<Compile Include="Areas\Home\Controllers\HomeController.cs" />
<Compile Include="Areas\Home\HomeAreaRegistration.cs" />
<Compile Include="Areas\Home\ViewModels\HomeViewModel.cs" />
@ -177,6 +180,7 @@
<Compile Include="Areas\Upload\ViewModels\DeleteViewModel.cs" />
<Compile Include="Areas\Upload\ViewModels\DownloadViewModel.cs" />
<Compile Include="Areas\Upload\ViewModels\UploadViewModel.cs" />
<Compile Include="Configuration\ApiConfig.cs" />
<Compile Include="Configuration\BlogConfig.cs" />
<Compile Include="Configuration\Config.cs" />
<Compile Include="Areas\Blog\Controllers\BlogController.cs" />
@ -212,10 +216,12 @@
<Content Include="Areas\Blog\Content\Blog.css" />
<Content Include="Areas\Blog\Scripts\Blog.js" />
<Content Include="Areas\Contact\Scripts\Contact.js" />
<Content Include="Areas\Help\Content\Help.css" />
<Content Include="Areas\Home\Content\Home.css" />
<Content Include="Areas\Home\Scripts\Home.js" />
<Content Include="Areas\Profile\Scripts\Profile.js" />
<Content Include="Areas\Upload\Scripts\Download.js" />
<Content Include="Content\jquery.tocify.css" />
<Content Include="Scripts\Blob.js" />
<Content Include="Scripts\Crypto-js\aes.js" />
<Content Include="Areas\Upload\Scripts\EncryptionWorker.js" />
@ -291,6 +297,16 @@
<Content Include="Areas\Error\Views\Error\Http500.cshtml" />
<Content Include="Areas\Upload\Views\Upload\Download.cshtml" />
<Content Include="Areas\Upload\Views\Upload\Delete.cshtml" />
<Content Include="Areas\Help\Views\web.config" />
<Content Include="Areas\Help\Views\_ViewStart.cshtml" />
<Content Include="Areas\Help\Views\Help\Index.cshtml" />
<Content Include="Areas\Help\Views\Help\Api.cshtml" />
<Content Include="Areas\Help\Views\Help\Git.cshtml" />
<Content Include="Areas\Help\Views\Help\Irc.cshtml" />
<Content Include="Areas\Help\Views\Help\Mail.cshtml" />
<Content Include="Areas\Help\Views\Help\Mumble.cshtml" />
<Content Include="Areas\Help\Views\Help\Blog.cshtml" />
<Content Include="Areas\Help\Views\Help\Upload.cshtml" />
<None Include="Properties\PublishProfiles\Teknik Dev.pubxml" />
<None Include="Scripts\jquery-2.1.4.intellisense.js" />
<Content Include="Scripts\bootbox\bootbox.min.js" />
@ -308,7 +324,9 @@
<Content Include="Scripts\jquery-2.1.4.js" />
<Content Include="Scripts\jquery-2.1.4.min.js" />
<None Include="Scripts\jquery.validate-vsdoc.js" />
<Content Include="Scripts\jquery-ui.widgets.js" />
<Content Include="Scripts\jquery.blockUI.js" />
<Content Include="Scripts\jquery.tocify.min.js" />
<Content Include="Scripts\jquery.validate.js" />
<Content Include="Scripts\jquery.validate.min.js" />
<Content Include="Scripts\jquery.validate.unobtrusive.js" />
@ -352,6 +370,8 @@
<Folder Include="Areas\Dev\Views\Shared\" />
<Folder Include="Areas\Error\Models\" />
<Folder Include="Areas\Error\Views\Shared\" />
<Folder Include="Areas\Help\Models\" />
<Folder Include="Areas\Help\Views\Shared\" />
<Folder Include="Areas\Home\Models\" />
<Folder Include="Areas\Home\Views\Shared\" />
<Folder Include="Areas\Privacy\Models\" />