浏览代码

Upload files to ''

TC 6 年之前
父节点
当前提交
17a46552d8
共有 13 个文件被更改,包括 2575 次插入0 次删除
  1. 10 0
      GetMemoMax.php
  2. 33 0
      StickMemo.php
  3. 210 0
      display.php
  4. 38 0
      download.php
  5. 96 0
      file.php
  6. 202 0
      img.php
  7. 124 0
      index.php
  8. 28 0
      jquery.qrcode.min.js
  9. 218 0
      rx.php
  10. 0 0
      tocas.css
  11. 1424 0
      tocas.js
  12. 179 0
      upload.php
  13. 13 0
      urlfix.js

+ 10 - 0
GetMemoMax.php

@@ -0,0 +1,10 @@
+<?php
+$max = 0;
+	foreach (new DirectoryIterator('Memo/') as $fileInfo) {
+		if ($fileInfo->isDot()) continue;
+		$current = pathinfo($fileInfo->getFilename())['filename'];
+		if (!is_numeric($current)) continue;
+		if ($current > $max) $max = $current;
+	}
+echo json_encode($max);
+?>

+ 33 - 0
StickMemo.php

@@ -0,0 +1,33 @@
+<?php
+$memodir = "Memo/";
+if(isset($_POST['content']) !== False){
+    $content = $_POST['content'];
+	$content = bin2hex($content);
+}
+$max = 0;
+	foreach (new DirectoryIterator('Memo/') as $fileInfo) {
+		if ($fileInfo->isDot()) continue;
+		$current = pathinfo($fileInfo->getFilename())['filename'];
+		if (!is_numeric($current)) continue;
+		if ($current > $max) $max = $current;
+	}
+	
+//Check if the number of files exceed the max
+if ($max > 1000){
+	foreach (new DirectoryIterator('Memo/') as $fileInfo) {
+			$current = pathinfo($fileInfo->getFilename())['filename'];
+			if (!is_numeric($current)) continue;
+			if ((int)$current != 0){
+				unlink('Memo/' . $current . ".txt");
+			}
+	}
+	$max = 0;
+}
+
+$filename = (int)$max + 1;
+$myfile = fopen($memodir . $filename . ".txt", "w") or die("Unable to open file!");
+$txt = $content;
+fwrite($myfile, $txt);
+fclose($myfile);
+echo $filename;
+?>

+ 210 - 0
display.php

@@ -0,0 +1,210 @@
+<html>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<head>
+<title>QuickSend</title>
+<link rel="stylesheet" href="tocas.css">
+
+</head>
+<body>
+<div class="ts inverted heading fluid slate" style="background-color:#2c2835;color:white;">
+    <span class="large header">Quick Send System</span>
+    <span class="description">Send data between mobile and laptops.<br> Powered by IMUS Laboratory</span>
+    <div class="ts bottom attached tabbed menu" style="color:white;">
+        <a class="item" href="index.php" style="color:#9d9ca3;">Send</a>
+        <a class="item" href="rx.php" style="color:#9d9ca3;">Receive</a>
+        <a class="item" href="img.php" style="color:#9d9ca3;">Image</a>
+        <a class="item" href="file.php" style="color:#9d9ca3;">Files</a>
+		<a class="active item">Display</a>
+    </div>
+</div>
+
+<div class="ts container">
+<br><br>
+
+<div class="ts stackable grid">
+    <div class="four wide column" align="center">
+	<div id="output"></div>
+	<div class="ts small statistic">
+    <div class="label">QuickSend ID</div>
+    <div class="value" id="sid"><?php
+		if (isset($_GET['id']) !== False){
+			echo '<script>var sid = parseInt("' . $_GET['id'] . '");</script>';
+			echo $_GET['id'];
+			$id = $_GET['id'];
+		}else{
+			//No input ids
+			echo '<script>var sid = parseInt("0");</script>';
+			echo 0;
+			$id = 0;
+		}
+	?></div>
+	</div>
+	</div>
+    <div class="twelve wide column">
+	<div class="ts fluid input" style="height:250px">
+    <?php
+		$memodir = "Memo/";
+		$dataType = "TEXT";
+		if (file_exists($memodir . $id.".txt")){
+			$myfile = fopen($memodir . $id.".txt", "r") or die("Unable to open file!");
+			$content = hex2bin(fread($myfile,filesize($memodir . $id.".txt")));
+			fclose($myfile);
+			$filetrue = true;
+			//Process the different filetype
+			if (strpos($content, "data:image/") !== False && strpos($content, ";base64,") !== False){
+				//This is an image encoded in base64
+				echo "<img class='ts centered image' src='" . $content . "'> ";
+				echo '<a class="ts bottom right attached label" href="'.$content.'" target="_blank">View Raw</a>';
+				echo '</img>';
+				$dataType = "IMAGE";
+			}else if (strpos($content, "data:file/") !== False){
+				$filename = str_replace("data:file/","uploads/",$content);
+				echo '<div class="ts fluid segment">';
+				echo '<div class="ts fluid steps">
+						<div class="step">
+							<div class="content">
+								<div class="title">Click the button below to download your file</div>
+								<div class="description">Please beware that we have the permission to remove your file anytime.</div>
+							</div>
+						</div>
+					</div><br>';
+				echo '<a href="'.$filename.'" class="ts basic fluid button" download>Download</a>';
+				echo '</div>';
+				$dataType = "FILE";
+			
+			}else{
+				echo '<textarea id="textholder" placeholder="Text to be sent via QRcode.">';
+				echo $content;
+				echo '</textarea>';
+				$dataType = "TEXT";
+			}
+		}else{
+			$filetrue = false;
+			echo 'The specified Memo ID cannot be find in the database. Are you sure you entered the correct QuickSend id?';
+			
+		}
+	?>
+	<?php
+		if ($filetrue == true){
+			echo '<script>var file_exists = true;</script>';
+		}else{
+			echo '<script>var file_exists = false;</script>';
+		}
+	?>
+	</div><br><br>
+	<div class="ts container" align="right"><?php
+		if($dataType == "TEXT"){
+			echo '<button class="ts tiny basic button" onclick="action()">Open / Search</button>';
+			echo '<button class="ts tiny basic button" onclick="copy()">Copy to Clipboard</button>';
+		}
+	?>
+	</div>
+	</div>
+</div>
+
+</div>
+
+<div style="position: fixed;
+    z-index: 100; 
+    bottom: 0; 
+    left: 0;
+    width: 100%;
+	background-color:#2c2835;
+	color:white;">
+<div class="ts container">
+<img class="ts tiny right floated image" src="img/cube.png"></img>
+</div>
+<div align="left" class="ts container">
+<br>
+CopyRight IMUS Laboratory 2018, All right reserved.
+</div>
+</div>
+
+<div id="notifybar" class="ts active bottom right snackbar" style="display:none;z-index: 101;">
+    <div class="content" style="z-index: 102;">
+        Your message has been copied into the clipboard.
+    </div>
+</div>
+
+<br><br><br><br>
+<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
+<script type="text/javascript" src="jquery.qrcode.min.js"></script>
+<script>
+jQuery(function(){
+	if (file_exists == true){
+		jQuery('#output').qrcode("http://imuslab.com/qs/display.php?id=" + sid);
+	}else{
+		jQuery('#output').qrcode("NOT FOUND");
+	}
+})
+function copyToClipboard(elem) {
+	  // create hidden text element, if it doesn't already exist
+    var targetId = "_hiddenCopyText_";
+    var isInput = elem.tagName === "INPUT" || elem.tagName === "TEXTAREA";
+    var origSelectionStart, origSelectionEnd;
+    if (isInput) {
+        // can just use the original source element for the selection and copy
+        target = elem;
+        origSelectionStart = elem.selectionStart;
+        origSelectionEnd = elem.selectionEnd;
+    } else {
+        // must use a temporary form element for the selection and copy
+        target = document.getElementById(targetId);
+        if (!target) {
+            var target = document.createElement("textarea");
+            target.style.position = "absolute";
+            target.style.left = "-9999px";
+            target.style.top = "0";
+            target.id = targetId;
+            document.body.appendChild(target);
+        }
+        target.textContent = elem.textContent;
+    }
+    // select the content
+    var currentFocus = document.activeElement;
+    target.focus();
+    target.setSelectionRange(0, target.value.length);
+    
+    // copy the selection
+    var succeed;
+    try {
+    	  succeed = document.execCommand("copy");
+    } catch(e) {
+        succeed = false;
+    }
+    // restore original focus
+    if (currentFocus && typeof currentFocus.focus === "function") {
+        currentFocus.focus();
+    }
+    
+    if (isInput) {
+        // restore prior selection
+        elem.setSelectionRange(origSelectionStart, origSelectionEnd);
+    } else {
+        // clear temporary content
+        target.textContent = "";
+    }
+    return succeed;
+}
+
+function copy(){
+	copyToClipboard(document.getElementById("textholder"));
+	$("#notifybar").fadeIn('slow').delay(3000).fadeOut('slow');
+}
+
+function action(){
+	var content = $('#textholder').val();
+	//alert(content);
+	if (content.substr(0, 4).includes("http") || content.substr(0, 11).includes("data:image/")){
+		//It is a url to be open
+		window.open(content,"_blank");
+	}else{
+		//It is a normal text to be searched
+		content = content.replace(" ","+");
+		window.open("https://www.google.com.hk/?#safe=off&q=" + content,"_blank");
+	}
+}
+
+</script>
+</body>
+</html>

+ 38 - 0
download.php

@@ -0,0 +1,38 @@
+<?php
+//downloading script for QuickSend desktop application
+if (isset($_GET['VB_download']) && $_GET['VB_download'] == "true" && isset($_GET['id']) && $_GET['id'] != ""){
+	$id = $_GET['id'];
+	$memodir = "Memo/";
+		$dataType = "TEXT";
+		if (file_exists($memodir . $id.".txt")){
+			$myfile = fopen($memodir . $id.".txt", "r") or die("Unable to open file!");
+			$content = hex2bin(fread($myfile,filesize($memodir . $id.".txt")));
+			fclose($myfile);
+			$filetrue = true;
+			//Process the different filetype
+			if (strpos($content, "data:image/") !== False && strpos($content, ";base64,") !== False){
+				//This is an image encoded in base64, throw back to client to handle
+				echo "<img src='" .$content . "'></img>";
+			}else if (strpos($content, "data:file/") !== False){
+				$filename = str_replace("data:file/","uploads/",$content);
+				if (file_exists($filename) == true){
+					echo "FILE:" . $filename;
+				}else{
+					echo '410 GONE';
+				}
+				
+			
+			}else{
+				echo "TEXT:" .$content;
+			}
+		}else{
+			$filetrue = false;
+			echo '404 NOTFOUND';
+			
+		}
+}else{
+	echo 'Invalid operation.';
+	exit(0);
+}
+
+?>

+ 96 - 0
file.php

@@ -0,0 +1,96 @@
+<html>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<head>
+<title>Quick Send</title>
+<link rel="stylesheet" href="tocas.css">
+<script type="text/javascript" src="urlfix.js"></script>
+</head>
+<body>
+<?php
+	if (isset($_GET['rx']) && $_GET['rx'] != ""){
+		header("Location: display.php?id=" . $_GET['rx']);
+		die();
+	}
+?>
+<div class="ts inverted heading fluid slate" style="background-color:#2c2835;color:white;">
+    <span class="large header">Quick Send System</span>
+    <span class="description">Send data between mobile and laptops.<br> Powered by IMUS Laboratory</span>
+    <div class="ts bottom attached tabbed menu" style="color:white;">
+        <a class="item" href="index.php" style="color:#9d9ca3;">Send</a>
+        <a class="item" href="rx.php" style="color:#9d9ca3;">Receive</a>
+        <a class="item" href="img.php" style="color:#9d9ca3;">Image</a>
+        <a class="active item" href="file.php">Files</a>
+    </div>
+</div>
+
+<div class="ts container">
+<br><br>
+<div class="ts stackable grid">
+    <div class="four wide column" align="center">
+		<div id="output"></div>
+		<div class="ts small statistic">
+			<div class="label">QuickSend ID</div>
+			<div class="value" id="sid"><?php
+			$max = 0;
+			foreach (new DirectoryIterator('Memo/') as $fileInfo) {
+				if ($fileInfo->isDot()) continue;
+				$current = pathinfo($fileInfo->getFilename())['filename'];
+				if (!is_numeric($current)) continue;
+				if ($current > $max) $max = $current;
+			}
+			echo $max+1;
+			?></div>
+		</div>
+	</div>
+    <div class="twelve wide column">
+		<form action="upload.php" method="post" enctype="multipart/form-data">
+			<input class="ts basic fluid button" type="file" name="fileToUpload" id="fileToUpload"><br><br>
+			<input class="ts basic fluid button" type="submit" value="Generate QR-Code" name="submit">
+		</form>
+		<br>
+	</div>
+</div>
+
+<br><br><br><br><br><br>
+<div style="position: fixed;
+    z-index: 100; 
+    bottom: 0; 
+    left: 0;
+    width: 100%;
+	background-color:#2c2835;
+	color:white;">
+<div class="ts container">
+<img class="ts tiny right floated image" src="img/cube.png"></img>
+</div>
+<div align="left" class="ts container">
+<br>
+CopyRight IMUS Laboratory 2018, All right reserved.
+</div>
+</div>
+
+</div>
+<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
+<script type="text/javascript" src="jquery.qrcode.min.js"></script>
+<script>
+jQuery(function(){
+	jQuery('#output').qrcode("Hello World");
+})
+
+function senddata(){
+	textarea = $('#textholder').val();
+    $.ajax({
+        type: "POST",
+        url: "StickMemo.php",
+        data:{ content: textarea }, 
+        success: function(data){
+            //alert(data);
+			$("#output").empty();
+			jQuery('#output').qrcode("http://imuslab.com/qs/display.php?id=" + data);
+			$("#sid").html(data);
+        }
+    })
+	
+}
+</script>
+</body>
+</html>

+ 202 - 0
img.php

@@ -0,0 +1,202 @@
+<html>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<head>
+<title>QuickSend Image</title>
+<link rel="stylesheet" href="tocas.css">
+<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
+<script type="text/javascript" src="jquery.qrcode.min.js"></script>
+</head>
+
+<body>
+<div class="ts inverted heading fluid slate" style="background-color:#2c2835;color:white;">
+    <span class="large header">Quick Send System</span>
+    <span class="description">Send data between mobile and laptops.<br> Powered by IMUS Laboratory</span>
+    <div class="ts bottom attached tabbed menu" style="color:white;">
+        <a class="item" href="index.php" style="color:#9d9ca3;">Send</a>
+        <a class="item" href="rx.php" style="color:#9d9ca3;">Receive</a>
+        <a class="active item" href="img.php">Image</a>
+        <a class="item" href="file.php" style="color:#9d9ca3;">Files</a>
+    </div>
+</div>
+<br><br>
+<div class="ts container">
+<div class="ts stackable centered grid">
+	 <div class="six wide column" align="center" style="overflow:hidden;">
+		<div class="ts fluid steps">
+			<div class="step">
+				<div class="content">
+					<div class="title">Step 1</div>
+					<div class="description">Select your image to send</div>
+				</div>
+			</div>
+		</div>
+	 
+		<input class="ts button" id="inp" type='file' style="width:100%;"><br>
+		<button class="ts basic fluid negative button" onclick="clearselection()">Clear</button>
+		<div class="ts narrow container" style="">
+			<p id="b64"></p>
+			<img id="img" src='img/noimg.png' height="150">
+		</div>
+		
+	 </div>
+	 <div class="five wide column" align="center">
+	 <div class="ts fluid steps">
+			<div class="step">
+				<div class="content">
+					<div class="title">Step 2</div>
+					<div class="description">Generate the sender QR Code</div>
+				</div>
+			</div>
+		</div>
+	 
+		<div class="ts inverted segment">
+			<div class="ts tiny inverted statistics">
+				<div class="statistic">
+					<div class="value" id="width">N/A</div>
+					<div class="label">Image Width</div>
+				</div>
+				<div class="statistic">
+					<div class="value" id="height">N/A</div>
+					<div class="label">Image Height</div>
+				</div>
+				<div class="statistic">
+					<div class="value" id="size">N/A</div>
+					<div class="label">Storage Size</div>
+				</div>
+			</div>
+		</div>
+		<button class="ts basic fluid button" onclick="senddata()">Generate QR Code</button>
+	 
+	 </div>
+	 <div class="five wide column" align="center">
+		<div class="ts fluid steps">
+			<div class="step">
+				<div class="content">
+					<div class="title">Step 3</div>
+					<div class="description">Use the QR Code to receive the image.</div>
+				</div>
+			</div>
+		</div>
+		
+		<div id="output"></div>
+		<div class="ts small statistic">
+		<div class="label">QuickSend ID</div>
+		<div class="value" id="sid"><?php
+		$max = 0;
+		foreach (new DirectoryIterator('Memo/') as $fileInfo) {
+			if ($fileInfo->isDot()) continue;
+			$current = pathinfo($fileInfo->getFilename())['filename'];
+			if (!is_numeric($current)) continue;
+			if ($current > $max) $max = $current;
+		}
+		echo $max+1;
+		?></div>
+		</div>
+	 </div>
+
+</div>
+<div class="ts fluid input" style="display:none;">
+    <div class="ts input" style="width: 100%;height:250px">
+    <textarea id="base64" placeholder="Encoded Base64 Content..."></textarea>
+	</div>
+</div>
+<div class="ts segment">
+	<div class="ts grid" align="center">
+		<div class="six wide column">
+		
+		</div>
+		<div class="ten wide column">
+		
+		
+		
+		</div>
+	</div>
+</div>
+<br><br><br><br><br><br>
+
+
+<div style="position: fixed;
+    z-index: 100; 
+    bottom: 0; 
+    left: 0;
+    width: 100%;
+	background-color:#2c2835;
+	color:white;">
+<div class="ts container">
+<img class="ts tiny right floated image" src="img/cube.png"></img>
+</div>
+<div align="left" class="ts container">
+<br>
+CopyRight IMUS Laboratory 2018, All right reserved.
+</div>
+</div>
+<script>
+
+function clearselection(){
+	$("#base64").val('');
+	document.getElementById("img").src       = 'img/noimg.png';
+	$("#inp").val("");
+	$("#width").text("Null");
+	$("#height").text("Null");
+	$("#size").text("Null");
+}
+
+function bytesToSize(bytes) {
+   var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
+   if (bytes == 0) return '0 Byte';
+   var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
+   return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
+};
+
+function readFile() {
+  
+  if (this.files && this.files[0]) {
+    
+    var FR= new FileReader();
+    
+    FR.addEventListener("load", function(e) {
+      document.getElementById("img").src       = e.target.result;
+      $("#base64").val(e.target.result);
+	  var i = new Image();
+	  i.src = document.getElementById("img").src;
+	  i.onload = function(){
+	  console.log(i.width);
+	  $("#width").text(i.width + "px");
+	  console.log(i.height);
+	  $("#height").text(i.height+ "px");
+	  $("#size").text(bytesToSize(encodeURI(e.target.result).split(/%..|./).length - 1));
+	  }
+    }); 
+    
+    FR.readAsDataURL( this.files[0] );
+  }
+  
+}
+
+jQuery(function(){
+	jQuery('#output').qrcode("Hello World");
+})
+
+function senddata(){
+	textarea = $('#base64').val();
+	if (textarea != ""){
+    $.ajax({
+        type: "POST",
+        url: "StickMemo.php",
+        data:{ content: textarea }, 
+        success: function(data){
+            //alert(data);
+			$("#output").empty();
+			jQuery('#output').qrcode("http://imuslab.com/qs/display.php?id=" + data);
+			$("#sid").html(data);
+        }
+    })
+	
+
+	}}
+
+
+document.getElementById("inp").addEventListener("change", readFile);
+</script>
+</body>
+</html>

+ 124 - 0
index.php

@@ -0,0 +1,124 @@
+<html>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<head>
+<title>Quick Send</title>
+<link rel="stylesheet" href="tocas.css">
+<script type="text/javascript" src="urlfix.js"></script>
+</head>
+<body>
+<?php
+	if (isset($_GET['rx']) && $_GET['rx'] != ""){
+		header("Location: display.php?id=" . $_GET['rx']);
+		die();
+	}
+?>
+<div class="ts inverted heading fluid slate" style="background-color:#2c2835;color:white;">
+    <span class="large header">Quick Send System</span>
+    <span class="description">Send data between mobile and laptops.<br> Powered by IMUS Laboratory</span>
+    <div class="ts bottom attached tabbed menu" style="color:white;">
+        <a class="active item" href="index.php">Send</a>
+        <a class="item" href="rx.php" style="color:#9d9ca3;">Receive</a>
+        <a class="item" href="img.php" style="color:#9d9ca3;">Image</a>
+        <a class="item" href="file.php" style="color:#9d9ca3;">Files</a>
+    </div>
+</div>
+
+<div class="ts container">
+<br><br>
+<div class="ts stackable grid">
+    <div class="four wide column" align="center">
+		<div id="output"></div>
+		<div class="ts small statistic">
+			<div class="label">QuickSend ID</div>
+			<div class="value" id="sid"><?php
+			$max = 0;
+			foreach (new DirectoryIterator('Memo/') as $fileInfo) {
+				if ($fileInfo->isDot()) continue;
+				$current = pathinfo($fileInfo->getFilename())['filename'];
+				if (!is_numeric($current)) continue;
+				if ($current > $max) $max = $current;
+			}
+			echo $max+1;
+			?></div>
+		</div>
+	</div>
+    <div class="twelve wide column">
+		<div class="ts fluid input" style="height:250px">
+		<textarea id="textholder" placeholder="Text to be sent via QRcode."></textarea>
+		</div><br><br>
+		<div class="ts container" align="right">
+		<button class="ts tiny basic button" onclick="senddata()">Generate QR-Code</button>
+		</div>
+	</div>
+</div>
+<div class="ts horizontal divider">Latest QuickSend code</div>
+<div class="ts stackable fluid horizontal list">
+			<?php
+			$max = 0;
+			foreach (new DirectoryIterator('Memo/') as $fileInfo) {
+				if ($fileInfo->isDot()) continue;
+				$current = pathinfo($fileInfo->getFilename())['filename'];
+				if (!is_numeric($current)) continue;
+				if ($current > $max) $max = $current;
+			}
+			$number = 10;
+			if ($max < 10){
+				$number = $max;
+			}
+			for( $i = 0; $i <= $number; $i++){
+				echo "<div class='ts label'><a class='item' onCLick='rx(" . ($max - $i) . ");'>QSCODE#" . ($max - $i) . "</a></div>";
+			}
+			?>
+</div>
+<br><br><br><br><br><br>
+<div style="position: fixed;
+    z-index: 100; 
+    bottom: 0; 
+    left: 0;
+    width: 100%;
+	background-color:#2c2835;
+	color:white;">
+<div class="ts container">
+<img class="ts tiny right floated image" src="img/cube.png"></img>
+</div>
+<div align="left" class="ts container">
+<br>
+CopyRight IMUS Laboratory 2018, All right reserved.
+</div>
+</div>
+
+</div>
+<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
+<script type="text/javascript" src="jquery.qrcode.min.js"></script>
+<script>
+jQuery(function(){
+	jQuery('#output').qrcode("Hello World");
+})
+
+function senddata(){
+	textarea = $('#textholder').val();
+    $.ajax({
+        type: "POST",
+        url: "StickMemo.php",
+        data:{ content: textarea }, 
+        success: function(data){
+            //alert(data);
+			$("#output").empty();
+			jQuery('#output').qrcode("http://imuslab.com/qs/display.php?id=" + data);
+			$("#sid").html(data);
+        }
+    })
+	
+}
+
+$(document).ready(function(){
+	
+});
+
+function rx(id){
+	top.location.href = "http://imuslab.com/qs/display.php?id=" + id;
+}
+
+</script>
+</body>
+</html>

+ 28 - 0
jquery.qrcode.min.js

@@ -0,0 +1,28 @@
+(function(r){r.fn.qrcode=function(h){var s;function u(a){this.mode=s;this.data=a}function o(a,c){this.typeNumber=a;this.errorCorrectLevel=c;this.modules=null;this.moduleCount=0;this.dataCache=null;this.dataList=[]}function q(a,c){if(void 0==a.length)throw Error(a.length+"/"+c);for(var d=0;d<a.length&&0==a[d];)d++;this.num=Array(a.length-d+c);for(var b=0;b<a.length-d;b++)this.num[b]=a[b+d]}function p(a,c){this.totalCount=a;this.dataCount=c}function t(){this.buffer=[];this.length=0}u.prototype={getLength:function(){return this.data.length},
+write:function(a){for(var c=0;c<this.data.length;c++)a.put(this.data.charCodeAt(c),8)}};o.prototype={addData:function(a){this.dataList.push(new u(a));this.dataCache=null},isDark:function(a,c){if(0>a||this.moduleCount<=a||0>c||this.moduleCount<=c)throw Error(a+","+c);return this.modules[a][c]},getModuleCount:function(){return this.moduleCount},make:function(){if(1>this.typeNumber){for(var a=1,a=1;40>a;a++){for(var c=p.getRSBlocks(a,this.errorCorrectLevel),d=new t,b=0,e=0;e<c.length;e++)b+=c[e].dataCount;
+for(e=0;e<this.dataList.length;e++)c=this.dataList[e],d.put(c.mode,4),d.put(c.getLength(),j.getLengthInBits(c.mode,a)),c.write(d);if(d.getLengthInBits()<=8*b)break}this.typeNumber=a}this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17;this.modules=Array(this.moduleCount);for(var d=0;d<this.moduleCount;d++){this.modules[d]=Array(this.moduleCount);for(var b=0;b<this.moduleCount;b++)this.modules[d][b]=null}this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-
+7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(a,c);7<=this.typeNumber&&this.setupTypeNumber(a);null==this.dataCache&&(this.dataCache=o.createData(this.typeNumber,this.errorCorrectLevel,this.dataList));this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,c){for(var d=-1;7>=d;d++)if(!(-1>=a+d||this.moduleCount<=a+d))for(var b=-1;7>=b;b++)-1>=c+b||this.moduleCount<=c+b||(this.modules[a+d][c+b]=
+0<=d&&6>=d&&(0==b||6==b)||0<=b&&6>=b&&(0==d||6==d)||2<=d&&4>=d&&2<=b&&4>=b?!0:!1)},getBestMaskPattern:function(){for(var a=0,c=0,d=0;8>d;d++){this.makeImpl(!0,d);var b=j.getLostPoint(this);if(0==d||a>b)a=b,c=d}return c},createMovieClip:function(a,c,d){a=a.createEmptyMovieClip(c,d);this.make();for(c=0;c<this.modules.length;c++)for(var d=1*c,b=0;b<this.modules[c].length;b++){var e=1*b;this.modules[c][b]&&(a.beginFill(0,100),a.moveTo(e,d),a.lineTo(e+1,d),a.lineTo(e+1,d+1),a.lineTo(e,d+1),a.endFill())}return a},
+setupTimingPattern:function(){for(var a=8;a<this.moduleCount-8;a++)null==this.modules[a][6]&&(this.modules[a][6]=0==a%2);for(a=8;a<this.moduleCount-8;a++)null==this.modules[6][a]&&(this.modules[6][a]=0==a%2)},setupPositionAdjustPattern:function(){for(var a=j.getPatternPosition(this.typeNumber),c=0;c<a.length;c++)for(var d=0;d<a.length;d++){var b=a[c],e=a[d];if(null==this.modules[b][e])for(var f=-2;2>=f;f++)for(var i=-2;2>=i;i++)this.modules[b+f][e+i]=-2==f||2==f||-2==i||2==i||0==f&&0==i?!0:!1}},setupTypeNumber:function(a){for(var c=
+j.getBCHTypeNumber(this.typeNumber),d=0;18>d;d++){var b=!a&&1==(c>>d&1);this.modules[Math.floor(d/3)][d%3+this.moduleCount-8-3]=b}for(d=0;18>d;d++)b=!a&&1==(c>>d&1),this.modules[d%3+this.moduleCount-8-3][Math.floor(d/3)]=b},setupTypeInfo:function(a,c){for(var d=j.getBCHTypeInfo(this.errorCorrectLevel<<3|c),b=0;15>b;b++){var e=!a&&1==(d>>b&1);6>b?this.modules[b][8]=e:8>b?this.modules[b+1][8]=e:this.modules[this.moduleCount-15+b][8]=e}for(b=0;15>b;b++)e=!a&&1==(d>>b&1),8>b?this.modules[8][this.moduleCount-
+b-1]=e:9>b?this.modules[8][15-b-1+1]=e:this.modules[8][15-b-1]=e;this.modules[this.moduleCount-8][8]=!a},mapData:function(a,c){for(var d=-1,b=this.moduleCount-1,e=7,f=0,i=this.moduleCount-1;0<i;i-=2)for(6==i&&i--;;){for(var g=0;2>g;g++)if(null==this.modules[b][i-g]){var n=!1;f<a.length&&(n=1==(a[f]>>>e&1));j.getMask(c,b,i-g)&&(n=!n);this.modules[b][i-g]=n;e--; -1==e&&(f++,e=7)}b+=d;if(0>b||this.moduleCount<=b){b-=d;d=-d;break}}}};o.PAD0=236;o.PAD1=17;o.createData=function(a,c,d){for(var c=p.getRSBlocks(a,
+c),b=new t,e=0;e<d.length;e++){var f=d[e];b.put(f.mode,4);b.put(f.getLength(),j.getLengthInBits(f.mode,a));f.write(b)}for(e=a=0;e<c.length;e++)a+=c[e].dataCount;if(b.getLengthInBits()>8*a)throw Error("code length overflow. ("+b.getLengthInBits()+">"+8*a+")");for(b.getLengthInBits()+4<=8*a&&b.put(0,4);0!=b.getLengthInBits()%8;)b.putBit(!1);for(;!(b.getLengthInBits()>=8*a);){b.put(o.PAD0,8);if(b.getLengthInBits()>=8*a)break;b.put(o.PAD1,8)}return o.createBytes(b,c)};o.createBytes=function(a,c){for(var d=
+0,b=0,e=0,f=Array(c.length),i=Array(c.length),g=0;g<c.length;g++){var n=c[g].dataCount,h=c[g].totalCount-n,b=Math.max(b,n),e=Math.max(e,h);f[g]=Array(n);for(var k=0;k<f[g].length;k++)f[g][k]=255&a.buffer[k+d];d+=n;k=j.getErrorCorrectPolynomial(h);n=(new q(f[g],k.getLength()-1)).mod(k);i[g]=Array(k.getLength()-1);for(k=0;k<i[g].length;k++)h=k+n.getLength()-i[g].length,i[g][k]=0<=h?n.get(h):0}for(k=g=0;k<c.length;k++)g+=c[k].totalCount;d=Array(g);for(k=n=0;k<b;k++)for(g=0;g<c.length;g++)k<f[g].length&&
+(d[n++]=f[g][k]);for(k=0;k<e;k++)for(g=0;g<c.length;g++)k<i[g].length&&(d[n++]=i[g][k]);return d};s=4;for(var j={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,
+78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(a){for(var c=a<<10;0<=j.getBCHDigit(c)-j.getBCHDigit(j.G15);)c^=j.G15<<j.getBCHDigit(c)-j.getBCHDigit(j.G15);return(a<<10|c)^j.G15_MASK},getBCHTypeNumber:function(a){for(var c=a<<12;0<=j.getBCHDigit(c)-
+j.getBCHDigit(j.G18);)c^=j.G18<<j.getBCHDigit(c)-j.getBCHDigit(j.G18);return a<<12|c},getBCHDigit:function(a){for(var c=0;0!=a;)c++,a>>>=1;return c},getPatternPosition:function(a){return j.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,c,d){switch(a){case 0:return 0==(c+d)%2;case 1:return 0==c%2;case 2:return 0==d%3;case 3:return 0==(c+d)%3;case 4:return 0==(Math.floor(c/2)+Math.floor(d/3))%2;case 5:return 0==c*d%2+c*d%3;case 6:return 0==(c*d%2+c*d%3)%2;case 7:return 0==(c*d%3+(c+d)%2)%2;default:throw Error("bad maskPattern:"+
+a);}},getErrorCorrectPolynomial:function(a){for(var c=new q([1],0),d=0;d<a;d++)c=c.multiply(new q([1,l.gexp(d)],0));return c},getLengthInBits:function(a,c){if(1<=c&&10>c)switch(a){case 1:return 10;case 2:return 9;case s:return 8;case 8:return 8;default:throw Error("mode:"+a);}else if(27>c)switch(a){case 1:return 12;case 2:return 11;case s:return 16;case 8:return 10;default:throw Error("mode:"+a);}else if(41>c)switch(a){case 1:return 14;case 2:return 13;case s:return 16;case 8:return 12;default:throw Error("mode:"+
+a);}else throw Error("type:"+c);},getLostPoint:function(a){for(var c=a.getModuleCount(),d=0,b=0;b<c;b++)for(var e=0;e<c;e++){for(var f=0,i=a.isDark(b,e),g=-1;1>=g;g++)if(!(0>b+g||c<=b+g))for(var h=-1;1>=h;h++)0>e+h||c<=e+h||0==g&&0==h||i==a.isDark(b+g,e+h)&&f++;5<f&&(d+=3+f-5)}for(b=0;b<c-1;b++)for(e=0;e<c-1;e++)if(f=0,a.isDark(b,e)&&f++,a.isDark(b+1,e)&&f++,a.isDark(b,e+1)&&f++,a.isDark(b+1,e+1)&&f++,0==f||4==f)d+=3;for(b=0;b<c;b++)for(e=0;e<c-6;e++)a.isDark(b,e)&&!a.isDark(b,e+1)&&a.isDark(b,e+
+2)&&a.isDark(b,e+3)&&a.isDark(b,e+4)&&!a.isDark(b,e+5)&&a.isDark(b,e+6)&&(d+=40);for(e=0;e<c;e++)for(b=0;b<c-6;b++)a.isDark(b,e)&&!a.isDark(b+1,e)&&a.isDark(b+2,e)&&a.isDark(b+3,e)&&a.isDark(b+4,e)&&!a.isDark(b+5,e)&&a.isDark(b+6,e)&&(d+=40);for(e=f=0;e<c;e++)for(b=0;b<c;b++)a.isDark(b,e)&&f++;a=Math.abs(100*f/c/c-50)/5;return d+10*a}},l={glog:function(a){if(1>a)throw Error("glog("+a+")");return l.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;256<=a;)a-=255;return l.EXP_TABLE[a]},EXP_TABLE:Array(256),
+LOG_TABLE:Array(256)},m=0;8>m;m++)l.EXP_TABLE[m]=1<<m;for(m=8;256>m;m++)l.EXP_TABLE[m]=l.EXP_TABLE[m-4]^l.EXP_TABLE[m-5]^l.EXP_TABLE[m-6]^l.EXP_TABLE[m-8];for(m=0;255>m;m++)l.LOG_TABLE[l.EXP_TABLE[m]]=m;q.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var c=Array(this.getLength()+a.getLength()-1),d=0;d<this.getLength();d++)for(var b=0;b<a.getLength();b++)c[d+b]^=l.gexp(l.glog(this.get(d))+l.glog(a.get(b)));return new q(c,0)},mod:function(a){if(0>
+this.getLength()-a.getLength())return this;for(var c=l.glog(this.get(0))-l.glog(a.get(0)),d=Array(this.getLength()),b=0;b<this.getLength();b++)d[b]=this.get(b);for(b=0;b<a.getLength();b++)d[b]^=l.gexp(l.glog(a.get(b))+c);return(new q(d,0)).mod(a)}};p.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],
+[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,
+116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,
+43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,
+3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,
+55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,
+45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];p.getRSBlocks=function(a,c){var d=p.getRsBlockTable(a,c);if(void 0==d)throw Error("bad rs block @ typeNumber:"+a+"/errorCorrectLevel:"+c);for(var b=d.length/3,e=[],f=0;f<b;f++)for(var h=d[3*f+0],g=d[3*f+1],j=d[3*f+2],l=0;l<h;l++)e.push(new p(g,j));return e};p.getRsBlockTable=function(a,c){switch(c){case 1:return p.RS_BLOCK_TABLE[4*(a-1)+0];case 0:return p.RS_BLOCK_TABLE[4*(a-1)+1];case 3:return p.RS_BLOCK_TABLE[4*
+(a-1)+2];case 2:return p.RS_BLOCK_TABLE[4*(a-1)+3]}};t.prototype={get:function(a){return 1==(this.buffer[Math.floor(a/8)]>>>7-a%8&1)},put:function(a,c){for(var d=0;d<c;d++)this.putBit(1==(a>>>c-d-1&1))},getLengthInBits:function(){return this.length},putBit:function(a){var c=Math.floor(this.length/8);this.buffer.length<=c&&this.buffer.push(0);a&&(this.buffer[c]|=128>>>this.length%8);this.length++}};"string"===typeof h&&(h={text:h});h=r.extend({},{render:"canvas",width:256,height:256,typeNumber:-1,
+correctLevel:2,background:"#ffffff",foreground:"#000000"},h);return this.each(function(){var a;if("canvas"==h.render){a=new o(h.typeNumber,h.correctLevel);a.addData(h.text);a.make();var c=document.createElement("canvas");c.width=h.width;c.height=h.height;for(var d=c.getContext("2d"),b=h.width/a.getModuleCount(),e=h.height/a.getModuleCount(),f=0;f<a.getModuleCount();f++)for(var i=0;i<a.getModuleCount();i++){d.fillStyle=a.isDark(f,i)?h.foreground:h.background;var g=Math.ceil((i+1)*b)-Math.floor(i*b),
+j=Math.ceil((f+1)*b)-Math.floor(f*b);d.fillRect(Math.round(i*b),Math.round(f*e),g,j)}}else{a=new o(h.typeNumber,h.correctLevel);a.addData(h.text);a.make();c=r("<table></table>").css("width",h.width+"px").css("height",h.height+"px").css("border","0px").css("border-collapse","collapse").css("background-color",h.background);d=h.width/a.getModuleCount();b=h.height/a.getModuleCount();for(e=0;e<a.getModuleCount();e++){f=r("<tr></tr>").css("height",b+"px").appendTo(c);for(i=0;i<a.getModuleCount();i++)r("<td></td>").css("width",
+d+"px").css("background-color",a.isDark(e,i)?h.foreground:h.background).appendTo(f)}}a=c;jQuery(a).appendTo(this)})}})(jQuery);

+ 218 - 0
rx.php

@@ -0,0 +1,218 @@
+<html>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<head>
+<title>QuickSend RX</title>
+<link rel="stylesheet" href="tocas.css">
+<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
+<script type="text/javascript" src="js/grid.js"></script>
+<script type="text/javascript" src="js/version.js"></script>
+<script type="text/javascript" src="js/detector.js"></script>
+<script type="text/javascript" src="js/formatinf.js"></script>
+<script type="text/javascript" src="js/errorlevel.js"></script>
+<script type="text/javascript" src="js/bitmat.js"></script>
+<script type="text/javascript" src="js/datablock.js"></script>
+<script type="text/javascript" src="js/bmparser.js"></script>
+<script type="text/javascript" src="js/datamask.js"></script>
+<script type="text/javascript" src="js/rsdecoder.js"></script>
+<script type="text/javascript" src="js/gf256poly.js"></script>
+<script type="text/javascript" src="js/gf256.js"></script>
+<script type="text/javascript" src="js/decoder.js"></script>
+<script type="text/javascript" src="js/qrcode.js"></script>
+<script type="text/javascript" src="js/findpat.js"></script>
+<script type="text/javascript" src="js/alignpat.js"></script>
+<script type="text/javascript" src="js/databr.js"></script>
+
+<script type="text/javascript">
+function qdecode(){
+	var result = qrcode.decode();
+	if (result.includes("imuslab.com")){
+		window.location.replace(result);
+	}else{
+		alert(result);
+	}
+}
+</script>
+
+</head>
+
+<body>
+<div class="ts inverted heading fluid slate" style="background-color:#2c2835;color:white;">
+    <span class="large header">Quick Send System</span>
+    <span class="description">Send data between mobile and laptops.<br> Powered by IMUS Laboratory</span>
+    <div class="ts bottom attached tabbed menu" style="color:white;">
+        <a class="item" href="index.php" style="color:#9d9ca3;">Send</a>
+        <a class="active item" href="rx.php">Receive</a>
+        <a class="item" href="img.php" style="color:#9d9ca3;">Image</a>
+        <a class="item" href="file.php" style="color:#9d9ca3;">Files</a>
+    </div>
+</div>
+<div class="ts container">
+<br><br>
+<div class="ts stackable grid">
+    <div class="four wide column" align="center">
+		<h4>QuickSend ID</h4>
+		<div class="ts fluid input">
+			<input type="text" id="mid" placeholder="Memo ID" style="width:100%;">
+		</div>
+		<button id="viewbtn"class="ts basic fluid button" onclick="manual_redirect();" >View</button>
+		<div class="ts tiny statistic" onClick="cloneCode();">
+			<div class="label">Latest QSCode Number</div>
+			<div class="value" id="lcode"><?php
+			$max = 0;
+			foreach (new DirectoryIterator('Memo/') as $fileInfo) {
+				if ($fileInfo->isDot()) continue;
+				$current = pathinfo($fileInfo->getFilename())['filename'];
+				if (!is_numeric($current)) continue;
+				if ($current > $max) $max = $current;
+			}
+			echo $max;
+			?></div>
+		</div>
+		
+	</div>
+    <div class="twelve wide column">
+		<h4>QR-Code ID</h4>
+			<form>
+				<div>
+					<input class="ts button" type="file" accept="image/*" id="file-input" capture="camera">
+				</div>
+			</form>
+		<canvas id="qr-canvas" width="256px" height="256px" style="display:none;"></canvas>
+		<canvas id="preview-canvas" width="256px" height="256px"></canvas>
+		<div class="ts container" align="right">
+			<button class="ts basic button" onclick="qdecode()">Decode</button>
+		</div>
+	</div>
+</div>
+
+
+<br><br><br><br><br><br>
+
+
+<div style="position: fixed;
+    z-index: 100; 
+    bottom: 0; 
+    left: 0;
+    width: 100%;
+	background-color:#2c2835;
+	color:white;">
+<div class="ts container">
+<img class="ts tiny right floated image" src="img/cube.png"></img>
+</div>
+<div align="left" class="ts container">
+<br>
+CopyRight IMUS Laboratory 2018, All right reserved.
+</div>
+</div>
+
+
+</div>
+<script>
+$("#viewbtn").keyup(function(event) {
+    if (event.keyCode == 13) {
+        manual_redirect();
+    }
+});
+
+function resizeCanvasImage(img, canvas, maxWidth, maxHeight) {
+    var imgWidth = img.width, 
+        imgHeight = img.height;
+
+    var ratio = 1, ratio1 = 1, ratio2 = 1;
+    ratio1 = maxWidth / imgWidth;
+    ratio2 = maxHeight / imgHeight;
+
+    // Use the smallest ratio that the image best fit into the maxWidth x maxHeight box.
+    if (ratio1 < ratio2) {
+        ratio = ratio1;
+    }
+    else {
+        ratio = ratio2;
+    }
+
+    var canvasContext = canvas.getContext("2d");
+    var canvasCopy = document.createElement("canvas");
+    var copyContext = canvasCopy.getContext("2d");
+    var canvasCopy2 = document.createElement("canvas");
+    var copyContext2 = canvasCopy2.getContext("2d");
+    canvasCopy.width = imgWidth;
+    canvasCopy.height = imgHeight;  
+    copyContext.drawImage(img, 0, 0);
+
+    // init
+    canvasCopy2.width = imgWidth;
+    canvasCopy2.height = imgHeight;        
+    copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);
+
+
+    var rounds = 2;
+    var roundRatio = ratio * rounds;
+    for (var i = 1; i <= rounds; i++) {
+        console.log("Step: "+i);
+
+        // tmp
+        canvasCopy.width = imgWidth * roundRatio / i;
+        canvasCopy.height = imgHeight * roundRatio / i;
+
+        copyContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvasCopy.width, canvasCopy.height);
+
+        // copy back
+        canvasCopy2.width = imgWidth * roundRatio / i;
+        canvasCopy2.height = imgHeight * roundRatio / i;
+        copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);
+
+    } // end for
+
+
+    // copy back to canvas
+    canvas.width = imgWidth * roundRatio / rounds;
+    canvas.height = imgHeight * roundRatio / rounds;
+    canvasContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvas.width, canvas.height);
+
+
+}
+
+
+$(function() {
+    $('#file-input').change(function(e) {
+        var file = e.target.files[0],
+            imageType = /image.*/;
+
+        if (!file.type.match(imageType))
+            return;
+
+        var reader = new FileReader();
+        reader.onload = fileOnload;
+        reader.readAsDataURL(file);
+    });
+
+    function fileOnload(e) {
+        var $img = $('<img>', { src: e.target.result });
+        $img.load(function() {
+            var canvas = $('#qr-canvas')[0];
+            var context = canvas.getContext('2d');
+
+            canvas.width = this.naturalWidth;
+            canvas.height = this.naturalHeight;
+            context.drawImage(this, 0, 0);
+			//grab the context from your destination canvas
+			var pcanvas = $('#preview-canvas')[0];
+			var destCtx = pcanvas.getContext('2d');
+			//call its drawImage() function passing it the source canvas directly
+			destCtx.drawImage(canvas, 0, 0, 256, 256 * this.height / this.width);
+        });
+    }
+});
+
+function manual_redirect(){
+	var id = $("#mid").val();
+	window.location.replace("http://imuslab.com/qs/display.php?id=" + id);
+}
+
+function cloneCode(){
+	$("#mid").val($("#lcode").html());
+}
+
+</script>
+</body>
+</html>

文件差异内容过多而无法显示
+ 0 - 0
tocas.css


+ 1424 - 0
tocas.js

@@ -0,0 +1,1424 @@
+// Generated by CoffeeScript 2.0.0-beta4
+(function() {
+  // 主要的選擇器函式。
+  var ts;
+
+  ts = function(selector, context) {
+    var nodes, ref, tag;
+    nodes = [];
+    // 如果選擇器是文字,但是是標籤(如:`<div>`)就建立新的元素
+    if (typeof selector === 'string' && selector[0] === '<') {
+      tag = selector.match(/<(.*)\/>|<(.*)>/);
+      nodes = [document.createElement((ref = tag[1]) != null ? ref : tag[2])];
+    // 如果選擇器是一般的文字,就選取元素。
+    } else if (typeof selector === 'string' && context === void 0) {
+      document.querySelectorAll(selector).forEach(function(element) {
+        return nodes.push(element);
+      });
+    // 如果選擇器有上下文選擇器,就透過選擇器找出上下文元素。
+    } else if (typeof context === 'string') {
+      nodes = ts(selector).find(context).toArray();
+    // 如果選擇器是 NodeList 就轉換成元素陣列然後取出來接著繼續。
+    } else if (selector instanceof NodeList) {
+      selector.forEach(function(element) {
+        return nodes.push(element);
+      });
+    // 如果選擇器是陣列,就當作是元素陣列,取出來然後繼續。
+    // 或傳入的是一個選擇器,就取出裡面的元素然後繼續。
+    } else if (Array.isArray(selector) || (selector != null ? selector.isSelector : void 0) === true) {
+      nodes = nodes.concat(selector);
+      selector = selector.selector;
+      context = selector != null ? selector.context : void 0;
+    // 如果是單個 DOM 元素,就放入選擇器然後繼續。
+    } else if (selector instanceof HTMLElement || selector instanceof HTMLDocument || selector instanceof HTMLBodyElement || selector === window) {
+      nodes = [selector];
+    }
+    // 保存目前的選擇器文字與上下文選擇器文字。
+    nodes.selector = typeof selector === 'string' ? selector : null;
+    nodes.context = typeof context === 'string' ? context : null;
+    // 將自訂的選擇器方法插入到節點陣列中,這樣才能夠串連使用。
+    Object.defineProperties(nodes, ts.fn);
+    // 將節點陣列標註為是選擇器,這樣才能判斷傳入的是不是我們自己的選擇器。
+    Object.defineProperty(nodes, 'isSelector', {
+      value: true
+    });
+    return nodes;
+  };
+
+  // 註冊到視窗上。
+  window.ts = ts;
+
+  // 函式鏈。
+  ts.fn = {};
+
+  // 輔助函式。
+  ts.helper = {};
+
+  // 事件輔助函式。
+  ts.helper.eventAlias = function(event) {
+    var alias, pair;
+    pair = event.split('.');
+    alias = pair[1] !== void 0 ? `.${pair[1]}` : '';
+    switch (false) {
+      case pair.indexOf('animationend') === -1:
+        return `webkitAnimationEnd${alias} mozAnimationEnd${alias} MSAnimationEnd${alias} oanimationend${alias} animationend${alias}`;
+      case pair.indexOf('transitionend') === -1:
+        return `webkitTransitionEnd${alias} mozTransitionEnd${alias} oTransitionEnd${alias} msTransitionEnd${alias} transitionend${alias}`;
+      default:
+        return event;
+    }
+  };
+
+  // 是否為物件。
+  ts.isPlainObject = function(object) {
+    return Object.prototype.toString.call(object) === '[object Object]';
+  };
+
+  // 是否為可觸控裝置。
+  ts.isTouchDevice = function() {
+    return 'ontouchstart' in window || navigator.maxTouchPoints;
+  };
+
+  // 延展物件的函式,與 ES 的 `...` 不同之處在於 extend 並不會替換掉整個子物件,而會以補插的方式執行。
+  // https://gomakethings.com/vanilla-javascript-version-of-jquery-extend/
+  ts.extend = function() {
+    var deep, extended, i, length, merge, obj;
+    extended = {};
+    deep = true;
+    i = 0;
+    length = arguments.length;
+    if (Object.prototype.toString.call(arguments[0]) === '[object Boolean]') {
+      deep = arguments[0];
+      i++;
+    }
+    merge = function(obj) {
+      var prop;
+      for (prop in obj) {
+        if (Object.prototype.hasOwnProperty.call(obj, prop)) {
+          if (deep && Object.prototype.toString.call(obj[prop]) === '[object Object]') {
+            extended[prop] = ts.extend(true, extended[prop], obj[prop]);
+          } else {
+            extended[prop] = obj[prop];
+          }
+        }
+      }
+    };
+    while (i < length) {
+      obj = arguments[i];
+      merge(obj);
+      i++;
+    }
+    return extended;
+  };
+
+  // 建立元素
+  ts.createElement = (html) => {
+    var div;
+    div = document.createElement('div');
+    div.innerHTML = html.trim();
+    return div.firstChild;
+  };
+
+  // 註冊 Tocas 模塊
+  ts.register = ({NAME, MODULE_NAMESPACE, Settings}, starter) => {
+    return ts.fn[NAME] = {
+      value: function(parameters) {
+        var $allModules, consoleText, errorHeaderCSS, headerCSS, messageCSS, methodInvoked, query, queryArguments, returnedValue;
+        $allModules = ts(this);
+        query = arguments[0];
+        queryArguments = [].slice.call(arguments, 1);
+        methodInvoked = typeof query === 'string';
+        returnedValue = void 0;
+        consoleText = (args) => {
+          //currentdate = new Date();
+          //datetime = "#{currentdate.getFullYear()}/#{(currentdate.getMonth()+1)}/#{currentdate.getDate()}/@#{currentdate.getHours()}:#{currentdate.getMinutes()}:#{currentdate.getSeconds()}"
+          return `%c${NAME}%c ${args[0]}`;
+        };
+        headerCSS = "background   : #EEE;\ncolor        : #5A5A5A;\nfont-size    : 1em;\npadding      : 8px 8px;\nline-height  : 5px;\nmargin       : 5px 0 5px 0;\nborder-radius: 1000em;";
+        errorHeaderCSS = `${headerCSS}\nbackground: #CE5F58;\ncolor: #FFF;`;
+        messageCSS = "font-weight: bold;";
+        $allModules.each(function(_, index) {
+          var $this, debug, element, error, initialize, instance, instantiate, invoke, module, observeChanges, settings;
+          $this = ts(this);
+          element = this;
+          instance = $this.data(MODULE_NAMESPACE);
+          settings = ts.isPlainObject(parameters) ? ts.extend(Settings, parameters) : ts.extend(Settings);
+          debug = function() {
+            if (!settings.debug || settings.silent) {
+              return;
+            }
+            return console.info.call(console, consoleText(arguments), headerCSS, messageCSS, "\n", ...Array.prototype.slice.call(arguments).slice(1));
+          };
+          error = function() {
+            if (settings.silent) {
+              return;
+            }
+            error = Function.prototype.bind.call(console.error, console, consoleText(arguments), errorHeaderCSS, messageCSS);
+            return error.apply(console, Array.prototype.slice.call(arguments, 1));
+          };
+          instantiate = () => {
+            module.instantiate();
+            instance = module;
+            return $this.data(MODULE_NAMESPACE, instance);
+          };
+          initialize = () => {
+            module.initialize();
+            if (settings.observeChanges) {
+              observeChanges();
+            }
+            return instantiate();
+          };
+          observeChanges = () => {
+            var observer;
+            if (!'MutationObserver' in window) {
+              debug('找不到樹狀結構變更觀測者,略過結構監聽動作', element);
+              return;
+            }
+            observer = new MutationObserver((mutations) => {
+              //debug 'DOM 樹狀結構已變更,更新快取資料'
+              return module.refresh();
+            });
+            return observer.observe(element, {
+              childList: true,
+              subtree: true
+            });
+          };
+          //debug '已設置 DOM 樹狀結構異動觀察者', observer
+          invoke = (query, passedArguments, context) => {
+            var camelCaseValue, depth, found, j, len, maxDepth, object, response, value;
+            object = instance;
+            maxDepth = void 0;
+            found = void 0;
+            response = void 0;
+            passedArguments = passedArguments || queryArguments;
+            context = element || context;
+            if (typeof query === 'string' && object !== void 0) {
+              query = query.split(/[\. ]/);
+              maxDepth = query.length - 1;
+              for (depth = j = 0, len = query.length; j < len; depth = ++j) {
+                value = query[depth];
+                camelCaseValue = query;
+                if (depth !== maxDepth) {
+                  camelCaseValue = value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1);
+                }
+                switch (false) {
+                  case !(ts.isPlainObject(object[camelCaseValue]) && depth !== maxDepth):
+                    object = object[camelCaseValue];
+                    break;
+                  case object[camelCaseValue] === void 0:
+                    found = object[camelCaseValue];
+                    break;
+                  case !(ts.isPlainObject(object[value]) && depth !== maxDepth):
+                    object = object[value];
+                    break;
+                  case object[value] === void 0:
+                    found = object[value];
+                    break;
+                  default:
+                    error('欲呼叫的方法並不存在', query);
+                    break;
+                }
+              }
+            }
+            switch (false) {
+              case typeof found !== 'function':
+                response = found.apply(context, passedArguments);
+                break;
+              case found === void 0:
+                response = found;
+            }
+            switch (false) {
+              case response !== $allModules:
+                returnedValue = $allModules;
+                break;
+              default:
+                returnedValue = response;
+            }
+            return found;
+          };
+          module = starter({$allModules, $this, element, debug, settings, instance, index});
+          if (methodInvoked) {
+            if (instance === void 0) {
+              initialize();
+            }
+            return invoke(query);
+          } else {
+            if (instance !== void 0) {
+              invoke('destroy');
+            }
+            return initialize();
+          }
+        });
+        if (returnedValue !== void 0) {
+          return returnedValue;
+        } else {
+          return $allModules;
+        }
+      }
+    };
+  };
+
+  // Get
+
+  // 取得選擇器內的指定元素,並且回傳一個 DOM 元素而非選擇器。
+  ts.fn.get = {
+    value: function(index = 0) {
+      return this[index];
+    }
+  };
+
+  // ToArray
+
+  // 將選擇器轉換成帶有節點的一般陣列。
+  ts.fn.toArray = {
+    value: function() {
+      var array;
+      array = [];
+      this.forEach(function(element) {
+        return array.push(element);
+      });
+      return array;
+    }
+  };
+
+  // Each
+
+  // 遍歷整個選擇器陣列。
+  ts.fn.each = {
+    value: function(callback) {
+      this.forEach(function(element, index) {
+        return callback.call(element, element, index);
+      });
+      return this;
+    }
+  };
+
+  // CollectSwap
+
+  // 將收集到的元素替換掉目前選擇器內的所有元素。
+  ts.fn.collectSwap = {
+    value: function(callback) {
+      var collection, newSelector;
+      collection = [];
+      this.each(function(element, index) {
+        var result;
+        result = callback.call(element, element, index);
+        if (result === void 0 || result === null) {
+          return;
+        }
+        if (result instanceof NodeList) {
+          return result.forEach(function(el) {
+            return collection.push(el);
+          });
+        } else if (Array.isArray(result)) {
+          return collection = collection.concat(result);
+        } else {
+          if (collection.indexOf(result) === -1) {
+            return collection.push(result);
+          }
+        }
+      });
+      // 透過 Set 型態移除重複的節點。
+      collection = new Set(collection);
+      // 然後將 Set 轉換成陣列,建立新的選擇器。
+      newSelector = ts([...collection]);
+      // 保存選擇器之前的所有節點。
+      Object.defineProperty(newSelector, 'prevObject', {
+        value: this
+      });
+      // 回傳這個新的選擇器。
+      return newSelector;
+    }
+  };
+
+  // Eq
+
+  // 取得選擇器的指定元素,然後繼續回傳僅帶有該元素的選擇器。
+  ts.fn.eq = {
+    value: function(index) {
+      return ts(this.get(index));
+    }
+  };
+
+  // Parent
+
+  // 回傳元素的父元素選擇器。
+  ts.fn.parent = {
+    value: function() {
+      return this.collectSwap(function() {
+        return this.parentNode;
+      });
+    }
+  };
+
+  // Closest
+
+  // 回傳最接近指定的父元素選擇器。
+  ts.fn.closest = {
+    value: function(selector) {
+      return this.collectSwap(function() {
+        return this.closest(selector);
+      });
+    }
+  };
+
+  // Find
+
+  // 在目前元素中搜尋指定元素並回傳其選擇器。
+  ts.fn.find = {
+    value: function(selector) {
+      return this.collectSwap(function() {
+        return this.querySelectorAll(selector);
+      });
+    }
+  };
+
+  // Insert Before
+
+  // 將選擇器元素安插在指定元素前。
+  ts.fn.insertBefore = {
+    value: function(target) {
+      return this.each(function() {
+        return ts(target).each((element) => {
+          return element.parentNode.insertBefore(this, element);
+        });
+      });
+    }
+  };
+
+  // Insert After
+
+  // 將選擇器元素安插在指定元素後。
+  ts.fn.insertAfter = {
+    value: function(target) {
+      return this.each(function() {
+        return ts(target).each((element) => {
+          return element.parentNode.insertBefore(this, element.nextSibling);
+        });
+      });
+    }
+  };
+
+  // Wrap
+
+  // 將元素用指定元素包覆起來。
+  ts.fn.wrap = {
+    value: function(element) {
+      return this.each(function() {
+        if (this.nextSibling) {
+          this.parentNode.insertBefore(element, this.nextSibling);
+        } else {
+          this.parentNode.appendChild(element);
+        }
+        return element.appendChild(this);
+      });
+    }
+  };
+
+  // Clone
+
+  // 複製元素。
+  ts.fn.clone = {
+    value: function() {
+      return this.collectSwap(function() {
+        return this.cloneNode(true);
+      });
+    }
+  };
+
+  // Append
+
+  // 將元素插入在目前選擇器元素的內部最後面。
+  ts.fn.append = {
+    value: function(element) {
+      var shouldClone;
+      shouldClone = this.length !== 1;
+      if (element.isSelector !== void 0) {
+        return this.each(function() {
+          return element.each((e) => {
+            return this.appendChild(shouldClone ? e.cloneNode(true) : e);
+          });
+        });
+      } else if (typeof element === 'string') {
+        return this.each(function() {
+          return this.insertAdjacentHTML('beforeend', element);
+        });
+      } else {
+        return this.each(function() {
+          return this.appendChild(shouldClone ? element.cloneNode(true) : element);
+        });
+      }
+    }
+  };
+
+  // AppendTo
+
+  // 將目前選擇器元素插入到指定元素的內部最後面。
+  ts.fn.appendTo = {
+    value: function(selector) {
+      return this.each(function() {
+        return ts(selector).append(this);
+      });
+    }
+  };
+
+  // Prepend
+
+  // 將元素插入在目前選擇器元素的內部最前面。
+  ts.fn.prepend = {
+    value: function(element) {
+      var shouldClone;
+      shouldClone = this.length !== 1;
+      if (element.isSelector !== void 0) {
+        return this.each(function() {
+          return element.each((e) => {
+            return this.prepend(shouldClone ? e.cloneNode(true) : e);
+          });
+        });
+      } else if (typeof element === 'string') {
+        return this.each(function() {
+          return this.insertAdjacentHTML('afterbegin', element);
+        });
+      } else {
+        return this.each(function() {
+          return this.prepend(shouldClone ? element.cloneNode(true) : element);
+        });
+      }
+    }
+  };
+
+  // PrependTo
+
+  // 將目前選擇器元素插入到指定元素的內部最前面。
+  ts.fn.prependTo = {
+    value: function(selector) {
+      return this.each(function() {
+        return ts(selector).prepend(this);
+      });
+    }
+  };
+
+  // Remove
+
+  // 將選擇器元素從頁面上中移除。
+  ts.fn.remove = {
+    value: function() {
+      return this.each(function() {
+        var ref;
+        return (ref = this.parentNode) != null ? ref.removeChild(this) : void 0;
+      });
+    }
+  };
+
+  // Is
+
+  // 選擇一些元素,然後用來比對目前的選擇器元素是否在這群當中。
+  ts.fn.is = {
+    value: function(selector) {
+      var compareElements, isInElements;
+      compareElements = document.querySelectorAll(selector);
+      isInElements = false;
+      this.each(function() {
+        return compareElements.forEach(function(compareElement) {
+          if (this === compareElement) {
+            return isInElements = true;
+          }
+        }, this);
+      });
+      return isInElements;
+    }
+  };
+
+  // Contains
+
+  // 是否擁有指定子元素。
+  ts.fn.contains = {
+    value: function(selector) {
+      var ref;
+      return (ref = this.get(0)) != null ? ref.contains(ts(selector).get()) : void 0;
+    }
+  };
+
+  // Not
+
+  // 將指定元素從選擇器中剔除。
+  ts.fn.not = {
+    value: function(selector) {
+      return ts(this.toArray().filter((element) => {
+        return ts(selector).indexOf(element) === -1;
+      }));
+    }
+  };
+
+  // Slice
+
+  // 替元素陣列進行切分。
+  ts.fn.slice = {
+    value: function(from, to) {
+      return ts(this.toArray().slice(from, to));
+    }
+  };
+
+  // Children
+
+  // 取得容器裡的第一層子節點。
+  ts.fn.children = {
+    value: function(selector) {
+      return this.collectSwap(function() {
+        return this.querySelectorAll(selector != null ? `:scope > ${selector}` : ':scope > *');
+      });
+    }
+  };
+
+  // Replace With
+
+  // 將元素替換為指定選擇器元素。
+  ts.fn.replaceWith = {
+    value: function(selector) {
+      var element;
+      element = ts(selector).get();
+      return this.each(function() {
+        return this.replaceWith(element);
+      });
+    }
+  };
+
+  // Last
+
+  // 選擇器中的最後一個元素。
+  ts.fn.last = {
+    value: function() {
+      return this.eq(this.length - 1);
+    }
+  };
+
+  // Next
+
+  // 下一個元素。
+  ts.fn.next = {
+    value: function() {
+      return this.collectSwap(function() {
+        return this.nextElementSibling;
+      });
+    }
+  };
+
+  // Prev
+
+  // 上一個元素。
+  ts.fn.prev = {
+    value: function() {
+      return this.collectSwap(function() {
+        return this.previousElementSibling;
+      });
+    }
+  };
+
+  // NextAll
+
+  // 這個元素之後的所有同階層元素。
+  ts.fn.nextAll = {
+    value: function(selector) {
+      return this.collectSwap(function() {
+        var $children, $parent, $self, index;
+        $self = ts(this);
+        $parent = $self.parent();
+        $children = selector != null ? $parent.find(`:scope > ${selector}`) : $parent.find(':scope > *');
+        index = $self.index();
+        return $children.slice(index + 1);
+      });
+    }
+  };
+
+  // PrevAll
+
+  // 這個元素之前的所有同階層元素。
+  ts.fn.prevAll = {
+    value: function(selector) {
+      return this.collectSwap(function() {
+        var $children, $parent, $self, index;
+        $self = ts(this);
+        $parent = $self.parent();
+        $children = selector != null ? $parent.find(`:scope > ${selector}`) : $parent.find(':scope > *');
+        index = $self.index();
+        return $children.slice(0, index);
+      });
+    }
+  };
+
+  // AddBack
+
+  // 在目前的選擇器節點陣列中加上先前選擇的所有節點。
+  ts.fn.addBack = {
+    value: function() {
+      if (this.prevObject) {
+        this.prevObject.toArray().forEach((element) => {
+          return this.push(element);
+        });
+      }
+      return this;
+    }
+  };
+
+  // Index
+
+  // 該元素在容器內的索引。
+  ts.fn.index = {
+    value: function() {
+      var index, node;
+      node = this.get(0);
+      index = 0;
+      if (node == null) {
+        return -1;
+      }
+      while ((node = node.previousElementSibling)) {
+        index++;
+      }
+      return index;
+    }
+  };
+
+  // Attr
+
+  // 取得或是建立新的標籤到目前的選擇器元素。
+  ts.fn.attr = {
+    value: function(name, value) {
+      var ref;
+      // 如果有 value 就設置簡單鍵值資料。
+      if (value !== void 0) {
+        return this.each(function() {
+          return this.setAttribute(name, value);
+        });
+      // 如果傳入的是物件就設置多重資料。
+      } else if (typeof name === 'object') {
+        return this.each(function() {
+          var key, results;
+          results = [];
+          for (key in name) {
+            results.push(this.setAttribute(key, name[key]));
+          }
+          return results;
+        });
+      } else {
+        return (ref = this.get()) != null ? ref.getAttribute(name) : void 0;
+      }
+    }
+  };
+
+  // RemoveAttr
+
+  // 移除目前選擇器元素的指定標籤。
+  ts.fn.removeAttr = {
+    value: function(name) {
+      return this.each(function() {
+        return this.removeAttribute(name);
+      });
+    }
+  };
+
+  // AddClass
+
+  // 在目前選擇器元素插入新的樣式類別名稱。
+  ts.fn.addClass = {
+    value: function(names) {
+      var name, newNames;
+      if (typeof names === 'object') {
+        newNames = '';
+        for (name in names) {
+          if (names[name] === true) {
+            newNames += ` ${name}`;
+          }
+        }
+        names = newNames;
+      } else {
+        names = Array.prototype.slice.call(arguments).join(' ');
+      }
+      return this.each(function() {
+        return DOMTokenList.prototype.add.apply(this.classList, names.split(' ').filter(Boolean));
+      });
+    }
+  };
+
+  // RemoveClass
+
+  // 移除目前選擇器元素的指定樣式類別。
+  ts.fn.removeClass = {
+    value: function(names) {
+      var name, newNames;
+      if (typeof names === 'object') {
+        newNames = '';
+        for (name in names) {
+          if (names[name] === true) {
+            newNames += ` ${name}`;
+          }
+        }
+        names = newNames;
+      } else {
+        names = Array.prototype.slice.call(arguments).join(' ');
+      }
+      //console.log @
+      return this.each(function() {
+        return DOMTokenList.prototype.remove.apply(this.classList, names.split(' ').filter(Boolean));
+      });
+    }
+  };
+
+  // ToggleClass
+
+  // 切換目前選擇器元素的樣式。
+  ts.fn.toggleClass = {
+    value: function(names) {
+      return this.each(function() {
+        return names.split(' ').forEach(function(name) {
+          return this.classList.toggle(name);
+        }, this);
+      });
+    }
+  };
+
+  // HasClass
+
+  // 回傳選擇器元素是否帶有指定樣式類別,是布林值。
+  ts.fn.hasClass = {
+    value: function(name) {
+      var ref;
+      return (ref = this.get(0)) != null ? ref.classList.contains(name) : void 0;
+    }
+  };
+
+  // CSS
+
+  // 將選擇器元素套用指定的 CSS 樣式。
+  ts.fn.css = {
+    value: function(name, value) {
+      var key;
+      // 有 name 也有 value 就設置樣式。
+      if (typeof name === 'string' && value !== void 0) {
+        return this.each(function() {
+          return this.style[name] = value;
+        });
+      // 有 name 但沒有 value 就取得樣式。
+      } else if (typeof name === 'string' && value === void 0) {
+        if (this.get() != null) {
+          return document.defaultView.getComputedStyle(this.get(), null).getPropertyValue(name);
+        } else {
+          return null;
+        }
+      // 有 name 但他是 object,就設置多重樣式。
+      } else if (typeof name === 'object') {
+        for (key in name) {
+          this.each(function() {
+            return this.style[key] = name[key];
+          });
+        }
+        return this;
+      }
+    }
+  };
+
+  // Rect
+
+  // 回傳選擇器元素的渲染形狀。
+  ts.fn.rect = {
+    value: function() {
+      var ref;
+      return (ref = this.get(0)) != null ? ref.getBoundingClientRect() : void 0;
+    }
+  };
+
+  // On
+
+  // 綁定並註冊一個事件監聽器。
+  ts.fn.on = {
+    value: function() {
+      var data, events, handler, options, selector;
+      switch (arguments.length) {
+        // Event 與 Handler。
+        case 2:
+          events = arguments[0];
+          handler = arguments[1];
+          break;
+        // Event 與 Selector 與 Handler。
+        // Event 與 Data 與 Handler。
+        // Event 與 Handler 與 Options。
+        case 3:
+          events = arguments[0];
+          handler = arguments[2];
+          switch (typeof arguments[1]) {
+            case "string":
+              selector = arguments[1];
+              break;
+            case "function":
+              handler = arguments[1];
+              options = arguments[2];
+              break;
+            default:
+              data = arguments[1];
+          }
+          break;
+        // Event 與 Selector 與 Data 與 Handler。
+        // Event 與 Selector 與 Handler 與 Options。
+        case 4:
+          events = arguments[0];
+          selector = arguments[1];
+          handler = arguments[3];
+          switch (typeof arguments[2]) {
+            case "function":
+              handler = arguments[2];
+              options = arguments[3];
+              break;
+            default:
+              data = arguments[2];
+          }
+          break;
+        // Event 與 Selector 與 Data 與 Handler 與 Options。
+        case 5:
+          events = arguments[0];
+          selector = arguments[1];
+          data = arguments[2];
+          handler = arguments[3];
+          options = arguments[4];
+      }
+      events = ts.helper.eventAlias(events);
+      // $events.click =
+      // {
+      //     anonymous: [
+      //         {
+      //             once    : true,
+      //             selector: ".button",
+      //             data    : {},
+      //             func    : func()
+      //         }
+      //     ]
+      //     alias1: [
+      //         {
+      //             once    : true,
+      //             selector: ".button",
+      //             data    : {},
+      //             func    : func()
+      //         }
+      //    ]
+      // }
+      return this.each(function() {
+        if (this.addEventListener === void 0) {
+          return;
+        }
+        if (this.$events === void 0) {
+          this.$events = {};
+        }
+        return events.split(' ').forEach(function(eventName) {
+          var event, eventAlias, hasAlias;
+          event = eventName.split('.');
+          // 透過事件的「event.alias」取得「點」後面的別名。
+          hasAlias = event.length > 1;
+          eventName = event[0];
+          eventAlias = hasAlias ? event[1] : null;
+          // 如果事件還沒在這個物件內產生過,就初始化一個事件結構。
+          if (this.$events[eventName] === void 0) {
+            this.$events[eventName] = {
+              anonymous: []
+            };
+            // 然後建立一個管理多個事件的事件管理處理程式。
+            this.addEventListener(eventName, function(event) {
+              var alias, calledAlias, closest, context, hasArgs, index, ref, ref1, ref2, results, single;
+              // 是否有自訂參數。
+              hasArgs = ((ref = event.detail) != null ? (ref1 = ref.args) != null ? ref1.length : void 0 : void 0) > 0;
+              // 是否有呼叫事件別名。
+              calledAlias = (ref2 = event.detail) != null ? ref2.alias : void 0;
+              // 如果該事件已經被移除則停止後續的反應。
+              if (this.$events[eventName] === void 0) {
+                return;
+              }
+              results = [];
+              // 將被觸發的事件裡面的所有處理程式全部呼叫一次。
+              for (alias in this.$events[eventName]) {
+                if (calledAlias && calledAlias !== alias) {
+                  continue;
+                }
+                index = this.$events[eventName][alias].length;
+                results.push((function() {
+                  var results1;
+                  results1 = [];
+                  while (index--) {
+                    if (this.$events[eventName] === void 0) {
+                      continue;
+                    }
+                    if (this.$events[eventName][alias] === void 0) {
+                      continue;
+                    }
+                    single = this.$events[eventName][alias][index];
+                    // 設置事件的上下文。
+                    context = this;
+                    // 如果這個事件有選擇器的話,則使用該選擇器為主。
+                    if (single.selector !== void 0) {
+                      selector = single.selector;
+                      closest = ts(event.target).closest(selector);
+                      // 如果找不到指定選擇棄的元素,就不要觸發此事件。
+                      if (closest.length === 0) {
+                        continue;
+                      } else {
+                        // 替換上下文為選擇器元素。
+                        context = closest.get();
+                      }
+                    }
+                    // 將事件預資料放入事件中供處理函式取得。
+                    event.data = single.data;
+                    if (hasArgs) {
+                      single.func.call(context, event, ...event.detail.args);
+                    } else {
+                      single.func.call(context, event);
+                    }
+                    // 如果這個程式只能被呼叫一次就在處理程式呼叫後移除。
+                    if (single.once === true) {
+                      results1.push(this.$events[eventName][alias].splice(index, 1));
+                    } else {
+                      results1.push(void 0);
+                    }
+                  }
+                  return results1;
+                }).call(this));
+              }
+              return results;
+            });
+          }
+          // 將新的事件處理程式註冊到事件清單中。
+          // 如果有別名,就不要推送到匿名陣列中,我們替這個別名另開物件。
+          if (hasAlias) {
+            if (this.$events[eventName][eventAlias] === void 0) {
+              this.$events[eventName][eventAlias] = [];
+            }
+            return this.$events[eventName][eventAlias].push({
+              func: handler,
+              selector: selector,
+              data: data,
+              once: options != null ? options.once : void 0
+            });
+          } else {
+            // 如果沒有,就照常推進匿名陣列中。
+            return this.$events[eventName].anonymous.push({
+              func: handler,
+              selector: selector,
+              data: data,
+              once: options != null ? options.once : void 0
+            });
+          }
+        }, this);
+      });
+    }
+  };
+
+  // One
+
+  // 綁定一次性的事件監聽器,當被觸發之後就會被移除。
+  ts.fn.one = {
+    value: function(events, handler) {
+      events = ts.helper.eventAlias(events);
+      return this.each(function() {
+        return ts(this).on(events, handler, {
+          once: true
+        });
+      });
+    }
+  };
+
+  // Off
+
+  // 註銷事件監聽器。
+  ts.fn.off = {
+    value: function(events, handler) {
+      events = ts.helper.eventAlias(events);
+      return this.each(function() {
+        if (this.$events === void 0) {
+          return;
+        }
+        return events.split(' ').forEach((eventName) => {
+          var alias, aliasName, event, hasAlias, isAlias, results;
+          // 將事件名稱由中間的「.」切成兩半。
+          event = eventName.split('.');
+          // 如果事件開頭是「.」符號,表示這是個別名,不是事件名稱。
+          isAlias = eventName[0] === '.';
+          // 如果事件分切後有兩個項目,表示這個事件有別名。
+          hasAlias = event.length === 2 && event[0] !== '';
+          if (hasAlias || isAlias) {
+            // 如果有別名的話,取得別名。
+            aliasName = event[1];
+          }
+          // 如果此事件不是只有別名的話,取得事件名稱。
+          eventName = !isAlias ? event[0] : void 0;
+          switch (false) {
+            // 當有指定監聽函式時。
+            case !(handler !== void 0 && this.$events[eventName] !== void 0):
+              return this.$events[eventName].anonymous.forEach((item, index) => {
+                if (handler === item.func) {
+                  return this.$events[eventName].anonymous.splice(index, 1);
+                }
+              });
+            // 當本事件名稱不僅是別名時。
+            case !(!isAlias && hasAlias && this.$events[eventName] !== void 0):
+              // 移除指定事件的別名監聽函式。
+              return delete this.$events[eventName][aliasName];
+            // 當僅有指定別名時。
+            case !(isAlias && !hasAlias):
+              results = [];
+              // 移除所有與此別名有關的事件監聽器。
+              for (event in this.$events) {
+                results.push((function() {
+                  var results1;
+                  results1 = [];
+                  for (alias in this.$events[event]) {
+                    if (aliasName === alias) {
+                      results1.push(delete this.$events[event][aliasName]);
+                    } else {
+                      results1.push(void 0);
+                    }
+                  }
+                  return results1;
+                }).call(this));
+              }
+              return results;
+              break;
+            // 當僅有指定事件名稱時。
+            case this.$events[eventName] === void 0:
+              // 清空該事件的所有事件監聽器。
+              return delete this.$events[eventName];
+          }
+        }, this);
+      });
+    }
+  };
+
+  // Trigger
+
+  // 觸發指定事件。
+  ts.fn.trigger = {
+    value: function(events) {
+      var customArguments;
+      events = ts.helper.eventAlias(events);
+      customArguments = [].slice.call(arguments, 1);
+      return this.each(function() {
+        return events.split(' ').forEach((eventName) => {
+          var alias, event, name;
+          event = eventName.split('.');
+          name = event[0];
+          alias = event.length > 1 ? event[1] : null;
+          event = new CustomEvent(name, {
+            detail: {
+              args: customArguments,
+              alias: alias
+            }
+          });
+          return this.dispatchEvent(event);
+        });
+      });
+    }
+  };
+
+  // Emulate
+
+  // 在指定的秒數過後觸發指定事件,若已被觸發則不再次觸發。
+  // 這能用以強迫讓某個事件發生。
+  ts.fn.emulate = {
+    value: function(event, duration) {
+      return this.each(function() {
+        var called;
+        called = false;
+        ts(this).one(event, function() {
+          return called = true;
+        });
+        return setTimeout(() => {
+          if (!called) {
+            return ts(this).trigger(event);
+          }
+        }, duration);
+      });
+    }
+  };
+
+  // Text
+
+  // 變更或取得選擇器元素的內容文字。
+  ts.fn.text = {
+    value: function(text) {
+      var ref;
+      if (text !== void 0) {
+        return this.each(function() {
+          return this.innerText = text;
+        });
+      } else {
+        return (ref = this.get()) != null ? ref.innerText : void 0;
+      }
+    }
+  };
+
+  // Val
+
+  // 變更或取得選擇器元素的值。
+  ts.fn.val = {
+    value: function(value) {
+      var ref;
+      if (value !== void 0) {
+        return this.each(function() {
+          return this.value = value;
+        });
+      } else {
+        return (ref = this.get()) != null ? ref.value : void 0;
+      }
+    }
+  };
+
+  // HTML
+
+  // 變更或取得選擇器元素的 HTML。
+  ts.fn.html = {
+    value: function(html) {
+      var ref;
+      if (html !== void 0) {
+        return this.each(function() {
+          return this.innerHTML = html;
+        });
+      } else {
+        return (ref = this.get()) != null ? ref.innerHTML : void 0;
+      }
+    }
+  };
+
+  // Empty
+
+  // 將選擇器元素的內容清除,例如值或文字。
+  ts.fn.empty = {
+    value: function() {
+      return this.each(function() {
+        if (this.value !== void 0) {
+          this.value = null;
+        }
+        if (this.innerHTML !== void 0) {
+          this.innerHTML = null;
+        }
+        if (this.innerText !== void 0) {
+          return this.innerText = null;
+        }
+      });
+    }
+  };
+
+  // Prop
+
+  // 變更或取得選擇器元素的屬性,例如 `.src`、`.width`。
+  ts.fn.prop = {
+    value: function(name, value) {
+      var key, ref;
+      // 有 name 也有 value 就設置屬性。
+      if (typeof name === 'string' && value !== void 0) {
+        return this.each(function() {
+          return this[name] = value;
+        });
+      // 有 name 但沒有 value 就取得屬性。
+      } else if (typeof name === 'string' && value === void 0) {
+        return (ref = this.get()) != null ? ref[name] : void 0;
+      // 有 name 但他是 object,就設置多重屬性。
+      } else if (typeof name === 'object') {
+        for (key in name) {
+          this.each(function() {
+            return this[key] = name[key];
+          });
+        }
+        return this;
+      }
+    }
+  };
+
+  // Data
+
+  // 在選擇器元素中存放資料,類似 Attr 但頁面不可見。
+  ts.fn.data = {
+    value: function(name, value) {
+      var key, ref, ref1;
+      // 有 name 也有 value 就設置資料。
+      if (typeof name === 'string' && value !== void 0) {
+        return this.each(function() {
+          if (this.$data === void 0) {
+            this.$data = {};
+          }
+          return this.$data[name] = value;
+        });
+      // 有 name 但沒有 value 就取得資料。
+      } else if (typeof name === 'string' && value === void 0) {
+        return (ref = this.get()) != null ? (ref1 = ref.$data) != null ? ref1[name] : void 0 : void 0;
+      // 有 name 但他是 object,就設置多重樣式。
+      } else if (typeof name === 'object') {
+        for (key in name) {
+          this.each(function() {
+            if (this.$data === void 0) {
+              this.$data = {};
+            }
+            return this.$data[key] = name[key];
+          });
+        }
+        return this;
+      }
+    }
+  };
+
+  // Remove Data
+
+  // 移除指定的資料。
+  ts.fn.removeData = {
+    value: function(name) {
+      return this.each(function() {
+        if (this.$data[name] != null) {
+          return delete this.$data[name];
+        }
+      });
+    }
+  };
+
+  // Has Timer
+
+  // 確認是否有指定的計時器。
+  ts.fn.hasTimer = {
+    value: function(name) {
+      var ref, ref1;
+      return ((ref = this.get(0)) != null ? (ref1 = ref.$timers) != null ? ref1[name] : void 0 : void 0) != null;
+    }
+  };
+
+  // Get Timer
+
+  // 取得計時器內容。
+  ts.fn.getTimer = {
+    value: function(name) {
+      var ref, ref1;
+      return (ref = this.get(0)) != null ? (ref1 = ref.$timers) != null ? ref1[name] : void 0 : void 0;
+    }
+  };
+
+  // Set Timer
+
+  // 設置一個新的計時器。
+  ts.fn.setTimer = {
+    value: function(options) {
+      options = Object.assign({}, {
+        name: '',
+        callback: function() {},
+        interval: 0,
+        looping: false,
+        visible: false
+      }, options);
+      return this.each(function() {
+        var timer;
+        if (this.$timers === void 0) {
+          this.$timers = {};
+        }
+        if (this.$timers[options.name] !== void 0) {
+          clearInterval(this.$timers[options.name].timer);
+        }
+        timer = () => {
+          var ref;
+          // 當設置有說明,頁面不可見的時候就不要繼續計時。
+          if (options.visible && document.hidden) {
+            return;
+          }
+          // 替計時器加上 10 毫秒。
+          this.$timers[options.name].passed += 10;
+          // 如果計時器的經過時間還不到使用者設定的時間
+          // 就返回而不要繼續執行。
+          if (this.$timers[options.name].passed < options.interval) {
+            return;
+          }
+          // 呼叫回呼函式。
+          options.callback();
+          // 如果要循環的話,就在計時器執行後重設時間即可。
+          if (options.looping) {
+            return this.$timers[options.name].passed = 0;
+          } else {
+            // 不然就移除計時器資訊。
+            return clearInterval((ref = this.$timers[options.name]) != null ? ref.timer : void 0);
+          }
+        };
+        // 移除在 DOM 元素內的這個計時器物件。
+        //delete @$timers[options.name]
+
+        // 在此元素內初始化計時器物件。
+        return this.$timers[options.name] = {
+          timer: setInterval(timer, 10),
+          passed: 0,
+          callback: options.callback,
+          interval: options.interval,
+          looping: options.looping,
+          visible: options.visible,
+          initializer: timer,
+          paused: false
+        };
+      });
+    }
+  };
+
+  // Pause Timer
+
+  // 暫停一個計時器。
+  ts.fn.pauseTimer = {
+    value: function(name) {
+      return this.each(function() {
+        var ref;
+        if (((ref = this.$timers) != null ? ref[name] : void 0) == null) {
+          return;
+        }
+        // 清除計數計時器達到暫停效果。
+        clearInterval(this.$timers[name].timer);
+        // 表示暫停。
+        return this.$timers[name].paused = true;
+      });
+    }
+  };
+
+  // Play Timer
+
+  // 重啟一個計時器。
+  ts.fn.playTimer = {
+    value: function(name) {
+      return this.each(function() {
+        var ref;
+        if (((ref = this.$timers) != null ? ref[name] : void 0) == null) {
+          return;
+        }
+        if (!this.$timers[name].paused) {
+          return;
+        }
+        // 重新初始化計數計時器來達到繼續的效果。
+        this.$timers[name].timer = setInterval(this.$timers[name].initializer, 10);
+        // 表示重新啟動。
+        return this.$timers[name].paused = false;
+      });
+    }
+  };
+
+  // Remove Timer
+
+  // 移除一個計時器。
+  ts.fn.removeTimer = {
+    value: function(name) {
+      return this.each(function() {
+        var ref;
+        if (((ref = this.$timers) != null ? ref[name] : void 0) == null) {
+          return;
+        }
+        // 清除計數計時器。
+        clearInterval(this.$timers[name].timer);
+        // 移除在 DOM 元素內的計時器物件。
+        return delete this.$timers[name];
+      });
+    }
+  };
+
+  // Repaint
+
+  // 讓瀏覽器重繪元素。
+  ts.fn.repaint = {
+    value: function() {
+      return this.each(function() {
+        return void(this.offsetHeight);
+      });
+    }
+  };
+
+}).call(this);

+ 179 - 0
upload.php

@@ -0,0 +1,179 @@
+<?php
+$target_dir = "uploads/";
+if (isset($_GET['VB_upload']) && $_GET['VB_upload'] == "true"){
+	$target_file = $target_dir . basename($_FILES["file"]["name"]);
+	$_FILES["fileToUpload"] = $_FILES["file"];
+}else{
+	$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
+}
+$uploadOk = 1;
+$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
+$filename = "";
+$displayMsg = "";
+$jsonReply = false;
+//Check if it is a program request or not
+if (isset($_GET['json']) && $_GET['json'] == "true"){
+	$jsonReply = true;
+}
+// Check if file already exists
+if (file_exists($target_file)) {
+    //echo "Sorry, file already exists.";
+    $uploadOk = 0;
+}
+// Check file size
+if ($_FILES["fileToUpload"]["size"] > 25000000) {
+    //echo "Sorry, your file is too large.";
+    $uploadOk = 0;
+}
+// Allow certain file formats
+if($imageFileType == "php") {
+    $uploadOk = 0;
+}
+// Check if $uploadOk is set to 0 by an error
+if ($uploadOk == 0) {
+    //echo "Sorry, your file was not uploaded.";
+// if everything is ok, try to upload file
+	$displayMsg = "Sorry, your file was not uploaded. (Maybe file already exists / Not allowed format / file larger than 25MB)";
+} else {
+    if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
+        //echo "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded.";
+		$filename =  $_FILES["fileToUpload"]["name"];
+		$displayMsg = "Done.";
+    } else {
+		$displayMsg = "Sorry, there was an error uploading your file.";
+        //echo "Sorry, there was an error uploading your file.";
+    }
+}
+
+if ($filename != ""){
+	//DONE
+	$memodir = "Memo/";
+	$content = "data:file/" . $filename;
+	$content = bin2hex($content);
+	$max = 0;
+		foreach (new DirectoryIterator('Memo/') as $fileInfo) {
+			if ($fileInfo->isDot()) continue;
+			$current = pathinfo($fileInfo->getFilename())['filename'];
+			if (!is_numeric($current)) continue;
+			if ($current > $max) $max = $current;
+		}
+		
+	//Check if the number of files exceed the max
+	if ($max > 1000){
+		foreach (new DirectoryIterator('Memo/') as $fileInfo) {
+				$current = pathinfo($fileInfo->getFilename())['filename'];
+				if (!is_numeric($current)) continue;
+				if ((int)$current != 0){
+					unlink('Memo/' . $current . ".txt");
+				}
+		}
+		$max = 0;
+	}
+	
+	$filename = (int)$max + 1;
+	$myfile = fopen($memodir . $filename . ".txt", "w") or die("Unable to open file!");
+	$txt = $content;
+	fwrite($myfile, $txt);
+	fclose($myfile);
+	//echo $filename;
+	
+	if ($jsonReply == true){
+		if ($uploadOk == 0){
+			header('Content-Type: application/json');
+			echo json_encode(-1);
+		}else{
+			header('Content-Type: application/json');
+			echo json_encode($filename);
+		}
+		exit();
+	}
+}else{
+	if ($jsonReply == true){
+		if ($uploadOk == 0){
+			echo json_encode("Sorry, your file was not uploaded. (Maybe file already exists / Not allowed format / file larger than 25MB)");
+		}
+		exit();
+	}
+}
+?>
+<html>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<head>
+<title>Quick Send</title>
+<link rel="stylesheet" href="tocas.css">
+<script type="text/javascript" src="urlfix.js"></script>
+</head>
+<body>
+<?php
+	if (isset($_GET['rx']) && $_GET['rx'] != ""){
+		header("Location: display.php?id=" . $_GET['rx']);
+		die();
+	}
+?>
+<div class="ts inverted heading fluid slate" style="background-color:#2c2835;color:white;">
+    <span class="large header">Quick Send System</span>
+    <span class="description">Send data between mobile and laptops.<br> Powered by IMUS Laboratory</span>
+    <div class="ts bottom attached tabbed menu" style="color:white;">
+        <a class="item" href="index.php" style="color:#9d9ca3;">Send</a>
+        <a class="item" href="rx.php" style="color:#9d9ca3;">Receive</a>
+        <a class="item" href="img.php" style="color:#9d9ca3;">Image</a>
+        <a class="active item" href="file.php">Files</a>
+    </div>
+</div>
+
+<div class="ts container">
+<br><br>
+<div class="ts stackable grid">
+    <div class="four wide column" align="center">
+		<div id="output"></div>
+		<div class="ts small statistic">
+			<div class="label">QuickSend ID</div>
+			<div class="value" id="sid"><?php
+			$max = 0;
+			foreach (new DirectoryIterator('Memo/') as $fileInfo) {
+				if ($fileInfo->isDot()) continue;
+				$current = pathinfo($fileInfo->getFilename())['filename'];
+				if (!is_numeric($current)) continue;
+				if ($current > $max) $max = $current;
+			}
+			echo $max;
+			?></div>
+		</div>
+	</div>
+    <div class="twelve wide column">
+		<h2 class="ts header"><?php echo $displayMsg;?></h2><br>
+		<a href="file.php" class="ts basic button">Upload Next File</a>
+		<br>
+	</div>
+</div>
+
+<br><br><br><br><br><br>
+<div style="position: fixed;
+    z-index: 100; 
+    bottom: 0; 
+    left: 0;
+    width: 100%;
+	background-color:#2c2835;
+	color:white;">
+<div class="ts container">
+<img class="ts tiny right floated image" src="img/cube.png"></img>
+</div>
+<div align="left" class="ts container">
+<br>
+CopyRight IMUS Laboratory 2018, All right reserved.
+</div>
+</div>
+
+</div>
+<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
+<script type="text/javascript" src="jquery.qrcode.min.js"></script>
+<script>
+var data = <?php echo $max;?>;
+jQuery(function(){
+	jQuery('#output').qrcode("http://imuslab.com/qs/display.php?id=" + data);
+})
+
+
+</script>
+</body>
+</html>

+ 13 - 0
urlfix.js

@@ -0,0 +1,13 @@
+//IMUS url redirect system for website under iframe and redirected subdomains using javascript.
+console.log("IMUS urlfix.js working in process...");
+var dirshort = "qs";
+var url = (window.location != window.parent.location)
+            ? document.referrer
+            : document.location.href;
+if (url.includes("/" + dirshort + "/") == false){ 
+//Switch to sub-domain system
+console.log("Subdomain system not found. Coverting to subdomain system.");
+top.window.location.href = "http://" + dirshort + ".imuslab.com";
+}else{
+console.log("Handling by subdomain redirection system. DONE");	
+}

部分文件因为文件数量过多而无法显示