Compare commits
135 Commits
nocaptcha-
...
v1.7.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f03b03a9ce | ||
|
|
da35e6ed8a | ||
|
|
6cddd7cbfe | ||
|
|
1e6d79af3c | ||
|
|
e731ee38a4 | ||
|
|
bee572f031 | ||
|
|
1a1d7709e6 | ||
|
|
64b91b9185 | ||
|
|
895280fed7 | ||
|
|
5546bacae8 | ||
|
|
172f4d80fe | ||
|
|
3204af9ad6 | ||
|
|
4bc6b7ba48 | ||
|
|
3173fd4b21 | ||
|
|
6deb8a3b95 | ||
|
|
aaa4d1db4d | ||
|
|
32f9b5582b | ||
|
|
00700c1a43 | ||
|
|
02907ca24c | ||
|
|
85424a2527 | ||
|
|
676c7ef3d7 | ||
|
|
9613cf1495 | ||
|
|
f51a02c4d7 | ||
|
|
46b6e2c640 | ||
|
|
450de0ebf4 | ||
|
|
fa5bd1b253 | ||
|
|
87fda22462 | ||
|
|
1f7ae5122e | ||
|
|
94fa2a3285 | ||
|
|
d6e0a6548d | ||
|
|
859a7da47b | ||
|
|
0b6635eaba | ||
|
|
acaa4175f0 | ||
|
|
223cad80a2 | ||
|
|
b0d3001712 | ||
|
|
dd43de1246 | ||
|
|
ad89f9ff71 | ||
|
|
1121e81a1d | ||
|
|
ef4cf86ebe | ||
|
|
ff668004dd | ||
|
|
c40f67c435 | ||
|
|
36ee279e18 | ||
|
|
3101cd02bf | ||
|
|
f34e43ab22 | ||
|
|
16e8e25a23 | ||
|
|
2e628c4c37 | ||
|
|
afad64e953 | ||
|
|
b162396ecb | ||
|
|
59c2614fe1 | ||
|
|
b44f55c38f | ||
|
|
a39920e0ac | ||
|
|
c87279b690 | ||
|
|
3998b6c1a6 | ||
|
|
222e7a3b8c | ||
|
|
8e44c1d06b | ||
|
|
58cbd80d67 | ||
|
|
2865bf31bd | ||
|
|
348b8dabc0 | ||
|
|
516bf90f77 | ||
|
|
f4265e77a9 | ||
|
|
298076d38f | ||
|
|
95c3ef41c2 | ||
|
|
60ace4dce0 | ||
|
|
1c122e7ca1 | ||
|
|
a0a82f2d6c | ||
|
|
80cec994f0 | ||
|
|
d59d213161 | ||
|
|
400d766b10 | ||
|
|
b4af3c7dea | ||
|
|
a27af9cbce | ||
|
|
1ebfd49874 | ||
|
|
ceef09f36b | ||
|
|
1689d330d2 | ||
|
|
0f2e159382 | ||
|
|
9ba1309746 | ||
|
|
70fc6d8a6e | ||
|
|
509dfc6085 | ||
|
|
adc0d5d079 | ||
|
|
0f2d3383a2 | ||
|
|
cee5a1e4b8 | ||
|
|
8ed6ed9a9a | ||
|
|
afa526c14e | ||
|
|
f00d1d501d | ||
|
|
62759636fa | ||
|
|
3dfdf9c231 | ||
|
|
9ba51b72d8 | ||
|
|
dd9120f832 | ||
|
|
b601443388 | ||
|
|
6c8059e8ed | ||
|
|
66fa3dd5e8 | ||
|
|
7a49222c6d | ||
|
|
efb9c866de | ||
|
|
9f9ba37f41 | ||
|
|
f5114a9001 | ||
|
|
569d23d01f | ||
|
|
ec27316ecf | ||
|
|
5f4af1f795 | ||
|
|
87ab7d16f4 | ||
|
|
e46535bc64 | ||
|
|
52a48dbb28 | ||
|
|
e774aa40ce | ||
|
|
50b421acb9 | ||
|
|
190fc28437 | ||
|
|
bcd6bb68a0 | ||
|
|
e583a73009 | ||
|
|
a43657a3a4 | ||
|
|
ec4d855f9a | ||
|
|
f1856f3c74 | ||
|
|
c5c506161c | ||
|
|
1001c15ecf | ||
|
|
6a6999d8ad | ||
|
|
727a8d4757 | ||
|
|
511c0703a2 | ||
|
|
2e0e80e28a | ||
|
|
543900b37a | ||
|
|
65803d9995 | ||
|
|
ce033d8e76 | ||
|
|
70f59f94f7 | ||
|
|
dacca1f8d8 | ||
|
|
9d34d89f27 | ||
|
|
5b8c5c0510 | ||
|
|
89a74c7137 | ||
|
|
5127f68093 | ||
|
|
8e94aa40a0 | ||
|
|
26dea2e4c4 | ||
|
|
4683e2bd3d | ||
|
|
fd2b74a5f5 | ||
|
|
ff9d158626 | ||
|
|
223d2b4c4a | ||
|
|
8f6bad8843 | ||
|
|
9d3d53e525 | ||
|
|
585454d674 | ||
|
|
665668d253 | ||
|
|
0e28538aa5 | ||
|
|
ba0c68bc17 |
7
.gitignore
vendored
@@ -9,7 +9,12 @@
|
||||
!header.php
|
||||
!footer.php
|
||||
!.gitignore
|
||||
!README.md
|
||||
!LICENSE.md
|
||||
!CHANGELOG.md
|
||||
|
||||
# Specifically ignore the config file and the DS_Store
|
||||
# But specifically ignore these things
|
||||
public/config.php
|
||||
public/.DS_Store
|
||||
public/custom.css
|
||||
public/phpqrcode/cache/*
|
||||
|
||||
24
public/CHANGELOG.md → CHANGELOG.md
Normal file → Executable file
@@ -1,6 +1,28 @@
|
||||
Infinity-Squared CHANGELOG
|
||||
Infinity Squared changelog
|
||||
==========================
|
||||
|
||||
2.0 (March 2015)
|
||||
----------------
|
||||
* New, more spaced out design.
|
||||
* SVG based Retina graphics, based on Font Awesome.
|
||||
* Custom social sharing buttons.
|
||||
* Nicer, larger font.
|
||||
* Mobile first design.
|
||||
* Improved error page. Now it has an actual footer, and the errors can be more easily displayed using the `display_error()` function.
|
||||
* Decent antispam system. If the user is logged in, antispam protection is ommited. If not, reCAPTCHA keys can be supplied for Google's new tick-CAPTCHA to be used. If both of those are failed, basic fill-box protection is used.
|
||||
* Shunned jQuery.
|
||||
* Shunned the dependency on the soon-to-be deprecated Google Charts API, in favour of PHP QR Code.
|
||||
* Using a different ZeroClipboard script and updating it's settings to more reliably find copy material.
|
||||
* Dependency system for scripts, so scripts like ZeroClipboard are not loaded where they're not needed, such as on the index page. Dependencies are added to the `dependencies[]` array, and then if the dependency is in the array during loading, the script is loaded.
|
||||
* Updated POT.
|
||||
* Corrected all of the settings code in `index.php` and `results.php`. It should now more reliably detect whether settings are enabled or not.
|
||||
|
||||
1.6 (January 2014)
|
||||
------------------
|
||||
* reCAPTCHA support.
|
||||
* Single new bookmarklet.
|
||||
* Custom CSS styling which will not be overwritten on upgrade.
|
||||
|
||||
1.5 (August 2013)
|
||||
-----------------
|
||||
Big changes:
|
||||
31
LICENSE.md
Executable file
@@ -0,0 +1,31 @@
|
||||
Infinity Squared licensing
|
||||
==========================
|
||||
|
||||
This program is distributed under the terms of the MIT license, with absolutely
|
||||
no guarantee as to whether it works or not.
|
||||
|
||||
Wherever third party code has been used, it will also have been attributed for
|
||||
clarity.
|
||||
|
||||
The MIT License (MIT)
|
||||
---------------------
|
||||
|
||||
Copyright (c) 2015 by the contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
75
README.md
@@ -1,28 +1,67 @@
|
||||
# Infinity Squared
|
||||
Infinity Squared
|
||||
================
|
||||
|
||||
A beautiful public page theme for YOURLS, carefully crafted by [Tom Slominski](http://tomslominski.net/).
|
||||
[](https://www.paypal.me/tomslominski)
|
||||
|
||||

|
||||
Front page of Infinity Squared
|
||||
[Download](https://github.com/tomslominski/infinity-squared/releases)
|
||||
|
||||
#### **[See more screenshots](http://imgur.com/a/2aiQk)**
|
||||
A beautiful public page theme for YOURLS, carefully crafted by [Tom Slominski](https://slomin.ski/). It can be used to give the public access to your short domain, not just registered users.
|
||||
|
||||
## Features
|
||||

|
||||
###### Front page of Infinity Squared 2.0
|
||||
|
||||
* A simple, WordPress Twenty-Ten like look;
|
||||
* User configurable options which are not overwritten on upgrade;
|
||||
* Sharers for Facebook, Twitter, Google+ and LinkedIn;
|
||||
* Unified look across all browsers and systems thanks to Formalize;
|
||||
* A fluid interface, meaning the page will look great on all displays and resolutions;
|
||||
* Ready for translations which are not overwritten on upgrade;
|
||||
* reCAPTCHA support to avoid spam.
|
||||
#### **[See more screenshots](http://imgur.com/a/f4g0x)**
|
||||
|
||||
## Usage
|
||||
Features
|
||||
--------
|
||||
* A clear design, with a responsive design which looks great across all screen sizes and resolutions.
|
||||
* Antispam protection: logged in users can shorten freely, otherwise reCAPTCHA keys can be provided or basic antispam protection will be provided.
|
||||
* Social sharing buttons for Facebook, Twitter, Google+, LinkedIn, Tumblr and App.net.
|
||||
* User configurable settings which are not overwritten on upgrade.
|
||||
* Translation ready (Russian and Polish are included).
|
||||
* Bookmarklets, so that links can be shortened quickly from the bookmarks bar.
|
||||
|
||||
See the project's [Wiki pages](https://github.com/tomslominski/infinity-squared/wiki) at GitHub for the latest installation and upgrade instructions.
|
||||
Installation
|
||||
------------
|
||||
1. Download the [latest release](https://github.com/tomslominski/infinity-squared/releases/latest) from GitHub and enter the folder which houses `index.php`.
|
||||
2. Upload all of the files into the directory where you've installed YOURLS. It doesn't have any additional requirements. If you can run YOURLS, you can run ∞²! Some of the files might collide with the files YOURLS also provides, like `README.md`. You can choose to replace them or not, it doesn't matter.
|
||||
3. Rename `public/config-sample.php` to `public/config.php` and make ∞² suit you.
|
||||
|
||||
## Licensing
|
||||
Upgrade
|
||||
-------
|
||||
1. Download the [latest release](https://github.com/tomslominski/infinity-squared/releases/latest) from GitHub and enter the folder which houses `index.php`.
|
||||
2. Remember to do a backup before you make any changes on your server.
|
||||
3. Replace all of the files from the downloaded release with the release on your server. **Remember that if you've made any changes to the core theme files, they will be overwritten, so be careful!** A `config.php` is not provided with the release, so you don't need to worry about loosing your settings.
|
||||
4. Copy over any new settings from `config-sample.php` into your own `config.php`.
|
||||
|
||||
qTip 2 is dual licensed under [MIT](http://en.wikipedia.org/wiki/MIT_License) or [GPLv2](http://en.wikipedia.org/wiki/GNU_General_Public_License) licenses.
|
||||
Customisation
|
||||
-------------
|
||||
You can customise Infinity Squared by editing the `public/config.php` file. The file explains what each of the settings does and how to modify them.
|
||||
|
||||
Formalize, jQuery and the Infinity Squared itself are also licenced on GPLv2.
|
||||
You can also create a `public/custom.css` style and change the appropriate setting in `config.php` to enable you to add your own CSS which will not be overwritten on upgrade.
|
||||
|
||||
Translating
|
||||
-----------
|
||||
By default, Infinity Squared comes with Polish, Russian and Spanish translations, as well as it's default English language. To enable any of those languages, you need to edit YOURLS' `config.php`, as described [here](https://github.com/YOURLS/YOURLS/wiki/YOURLS-in-your-language#install-yourls-in-your-language).
|
||||
|
||||
If you want to translate Infinity Squared into your own language, [this blog post](http://blog.yourls.org/2013/02/workshop-how-to-create-your-own-translation-file-for-yourls/) from YOURLS describes how to do it. You can find the latest .pot file in `public/languages/isq_translation-source.pot`. Please follow the contributing guidelines below to add your translation to Infinity Squared.
|
||||
|
||||
Contributing
|
||||
------------
|
||||
If you have any issues with the way Infinity Squared works, you want to suggest a feature or you believe you have found a bug, please submit an issue using GitHub's [issue system](https://github.com/tomslominski/infinity-squared/issues). However, please remember that the developers work in this project in their spare time.
|
||||
|
||||
If you'd like to contribute some code to Infinity Squared, please open an issue first to discuss whether your patch will be accepted. If it has been agreed that your patch will be accepted, please fork the repository and submit a pull request when ready.
|
||||
|
||||
Licensing
|
||||
---------
|
||||
Just like YOURLS, Infinity Squared is licensed under the MIT license. Basically, you can do whatever you want with it as long as you give attribution wherever you use it. There is no guarantee that this software will work.
|
||||
|
||||
You can find the full license in the root directory of Infinity Squared, under LICENSE.md.
|
||||
|
||||
Clipboard.js is also licensed under the MIT license.
|
||||
|
||||
Donations
|
||||
---------
|
||||
[](https://www.paypal.me/tomslominski)
|
||||
|
||||
Even though Infinity Squared is free, it takes time to build, so I'm more than happy to accept donations at the above link. Thanks!
|
||||
|
||||
35
footer.php
@@ -1,16 +1,39 @@
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
|
||||
<div class="content">
|
||||
<h2><?php yourls_e( 'The bookmarklet', 'isq_translation') ?></h2>
|
||||
|
||||
<?php $bookmarkletdialog = yourls__( 'Save this as a bookmark', 'isq_translation') // Can't put it where it belongs as there'd be too much char escaping ?>
|
||||
<p><?php yourls_e( 'Add this to your bookmarks or drag it to your bookmarks bar to quickly access shortening functions:', 'isq_translation') ?> <a href="javascript:(function()%7Bvar%20d=document,w=window,enc=encodeURIComponent,e=w.getSelection,k=d.getSelection,x=d.selection,s=(e?e():(k)?k():(x?x.createRange().text:0)),s2=((s.toString()=='')?s:enc(s)),f='<?php echo YOURLS_SITE . '/index.php'; ?>',l=d.location,p='?url='+enc(l.href)+'&title='+enc(d.title)+'&keyword='+s2,u=f+p;try%7Bthrow('ozhismygod');%7Dcatch(z)%7Ba=function()%7Bif(!w.open(u))l.href=u;%7D;if(/Firefox/.test(navigator.userAgent))setTimeout(a,0);else%20a();%7Dvoid(0);%7D)();" onClick="alert('<?php echo $bookmarkletdialog ?>'); return false;" class="bookmarklet"><?php yourls_e( 'Shorten', 'isq_translation') ?></a></p>
|
||||
<?php $bookmarkletdialog = yourls__( 'Save this as a bookmark.', 'isq_translation') // Can't put it where it belongs as there'd be too much char escaping ?>
|
||||
<p><?php yourls_e( 'Add this to your bookmarks or drag it to your bookmarks bar to quickly access shortening functions.', 'isq_translation') ?> </p>
|
||||
<p class="bookmarklet-container"><a href="javascript:(function()%7Bvar%20d=document,w=window,enc=encodeURIComponent,e=w.getSelection,k=d.getSelection,x=d.selection,s=(e?e():(k)?k():(x?x.createRange().text:0)),s2=((s.toString()=='')?s:enc(s)),f='<?php echo YOURLS_SITE . '/index.php'; ?>',l=d.location,p='?url='+enc(l.href)+'&title='+enc(d.title)+'&keyword='+s2,u=f+p;try%7Bthrow('ozhismygod');%7Dcatch(z)%7Ba=function()%7Bif(!w.open(u))l.href=u;%7D;if(/Firefox/.test(navigator.userAgent))setTimeout(a,0);else%20a();%7Dvoid(0);%7D)();" onClick="alert('<?php echo $bookmarkletdialog; ?>'); return false;" class="bookmarklet button"><span class="icon-move"><?php include('public/images/move.svg'); ?></span><?php yourls_e( 'Shorten', 'isq_translation') ?></a></p>
|
||||
<p><?php yourls_e( 'This bookmarklet takes the page URL and title and opens a new tab, where you can fill out a CAPTCHA. If you have selected text before using the bookmarklet, that will be used as the keyword.', 'isq_translation') ?></p>
|
||||
<p><?php yourls_e( 'Support for bookmarklets on mobile varies. For example, they work on Chrome for Android but you have to add and sync them from your desktop.', 'isq_translation') ?></p>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<p><?php yourls_e( 'Powered by <a href="http://yourls.org/">YOURLS</a>. Design by <a href="http://tomslominski.net/">Tom Slominski</a>. Also used: <a href="http://formalize.me/">Formalize</a> and <a href="http://qtip2.com/">qTip²</a>. Find this theme on <a href="https://github.com/tomslominski/infinity-squared">GitHub</a>.', 'isq_translation') ?></p>
|
||||
<footer class="content site-footer">
|
||||
<p><?php yourls_e( 'Powered by <a href="http://yourls.org/">YOURLS</a>. Designed by <a href="https://slomin.ski/">Tom Slominski</a>.', 'isq_translation') ?> <a class="icon-github" href="https://github.com/tomslominski/infinity-squared"><?php include('public/images/github.svg'); ?></a></p>
|
||||
<?php if( 'recaptcha' == is_get_antispam_method() || 'recaptcha_v3' == is_get_antispam_method() ) : ?>
|
||||
<p class="recaptcha-cookie"><?php yourls_e('This site uses cookies for Google reCAPTCHA','isq_translation'); ?>.<p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php global $dependencies; ?>
|
||||
|
||||
<?php if( in_array( 'recaptcha_v3', $dependencies ) ) : ?>
|
||||
<script type="text/template" id="recaptcha-sitekey"><?php echo ISQ::$recaptcha_v3['sitekey']; ?></script>
|
||||
<script src="https://www.google.com/recaptcha/api.js?render=<?php echo ISQ::$recaptcha_v3['sitekey']; ?>"></script>
|
||||
<?php elseif( in_array( 'recaptcha', $dependencies ) ) : ?>
|
||||
<script src="https://www.google.com/recaptcha/api.js"></script>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if( in_array( 'clipboard.js', $dependencies ) ) { ?>
|
||||
<script src="public/js/clipboard.min.js"></script>
|
||||
<?php } ?>
|
||||
|
||||
<?php if( in_array( 'recaptcha_v3', $dependencies ) || in_array( 'clipboard.js', $dependencies ) ) : ?>
|
||||
<script src="public/js/app.js"></script>
|
||||
<?php endif; ?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
129
header.php
@@ -4,93 +4,70 @@
|
||||
require_once( dirname(__FILE__) . '/includes/load-yourls.php' );
|
||||
|
||||
// Ask for Infinity Squared settings
|
||||
if( @include dirname(__FILE__) . '/public/config.php' ) {
|
||||
include( dirname(__FILE__) . '/public/config.php' );
|
||||
class ISQ { public static $general = array(), $links = array(), $social = array(), $recaptcha = array(); }
|
||||
} else {
|
||||
include( dirname(__FILE__) . '/public/config-sample.php' );
|
||||
}
|
||||
|
||||
class ISQ { public static $general = array(), $links = array(), $social = array(), $recaptcha = array(), $recaptcha_v3 = array(); }
|
||||
|
||||
// Load functions
|
||||
require_once( dirname(__FILE__) . '/public/functions.php' );
|
||||
|
||||
// Default dependencies
|
||||
$dependencies = array();
|
||||
|
||||
// Load translations
|
||||
function isq_load_textdomain() {
|
||||
yourls_load_custom_textdomain( 'isq_translation', $site . '/public/languages' );
|
||||
$site = YOURLS_SITE;
|
||||
}
|
||||
isq_load_textdomain();
|
||||
yourls_load_custom_textdomain( 'isq_translation', 'public/languages' );
|
||||
?>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title><?php echo ISQ::$general['name']; ?></title> <!-- Site title defined in theme settings -->
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
|
||||
<link rel="shortcut icon" href="<?php echo YOURLS_SITE; ?>/images/favicon.gif" /> <!-- Default favicon -->
|
||||
<link rel="stylesheet" href="<?php echo YOURLS_SITE; ?>/public/formalize.css" /> <!-- Formalize CSS -->
|
||||
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/qtip2/2.1.1/basic/jquery.qtip.min.css" /><!-- qTip CSS -->
|
||||
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Ubuntu:regular,italic,bold,bolditalic"><!-- Ubuntu from Google Web Fonts -->
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="//fonts.googleapis.com/css?family=Open+Sans:400,700" rel="stylesheet" type="text/css">
|
||||
<link rel="stylesheet" href="<?php echo YOURLS_SITE; ?>/public/style.css" /><!-- Theme CSS -->
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <!-- jQuery -->
|
||||
<script src="<?php echo YOURLS_SITE; ?>/public/js/jquery.formalize.min.js"></script><!-- Formalize JS -->
|
||||
<script src="http://cdnjs.cloudflare.com/ajax/libs/qtip2/2.1.1/basic/jquery.qtip.min.js"></script><!-- qTip JS -->
|
||||
<?php if (!empty(ISQ::$social['plus'])) { ?>
|
||||
<script type="text/javascript" src="https://apis.google.com/js/plusone.js">
|
||||
{lang: "en-GB"}
|
||||
</script>
|
||||
<?php if ( ISQ::$general['customstyle'] ) { ?>
|
||||
<link rel="stylesheet" href="<?php echo YOURLS_SITE; ?>/public/custom.css" /><!-- Custom CSS -->
|
||||
<?php } ?>
|
||||
<script src='https://www.google.com/recaptcha/api.js'></script><!-- reCAPTCHA -->
|
||||
<?php if (!empty(ISQ::$general['clipboard'])) { ?>
|
||||
<script type="text/javascript" src="js/jquery.zclip.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$('button#long-copy').zclip({
|
||||
path:'js/ZeroClipboard.swf',
|
||||
copy:function(){return $('input#long-copy').val();},
|
||||
afterCopy: function() {
|
||||
$("button#long-copy").html('<?php yourls_e( 'Copied!', 'isq_translation'); ?>');
|
||||
}
|
||||
});
|
||||
$('button#short-copy').zclip({
|
||||
path:'js/ZeroClipboard.swf',
|
||||
copy:function(){return $('input#short-copy').val();},
|
||||
afterCopy: function() {
|
||||
$("button#short-copy").html('<?php yourls_e( 'Copied!', 'isq_translation'); ?>');
|
||||
}
|
||||
});
|
||||
$('button#stats-copy').zclip({
|
||||
path:'js/ZeroClipboard.swf',
|
||||
copy:function(){return $('input#stats-copy').val();},
|
||||
afterCopy: function() {
|
||||
$("button#stats-copy").html('<?php yourls_e( 'Copied!', 'isq_translation'); ?>');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php } ?>
|
||||
<script>
|
||||
$(document).ready(function()
|
||||
{
|
||||
$('a.bookmarklet').qtip({
|
||||
});
|
||||
$('label').qtip({
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- App icons generated using http://realfavicongenerator.net -->
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="public/images/app-icons/apple-touch-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="public/images/app-icons/apple-touch-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="public/images/app-icons/apple-touch-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="public/images/app-icons/apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="public/images/app-icons/apple-touch-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="public/images/app-icons/apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="public/images/app-icons/apple-touch-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="public/images/app-icons/apple-touch-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="public/images/app-icons/apple-touch-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" href="public/images/app-icons/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="public/images/app-icons/android-chrome-192x192.png" sizes="192x192">
|
||||
<link rel="icon" type="image/png" href="public/images/app-icons/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="public/images/app-icons/favicon-16x16.png" sizes="16x16">
|
||||
<link rel="manifest" href="public/images/app-icons/manifest.json">
|
||||
<link rel="shortcut icon" href="public/images/app-icons/favicon.ico">
|
||||
<meta name="msapplication-TileColor" content="#2b5797">
|
||||
<meta name="msapplication-TileImage" content="public/images/app-icons/mstile-144x144.png">
|
||||
<meta name="msapplication-config" content="public/images/app-icons/browserconfig.xml">
|
||||
<meta name="theme-color" content="#013f6d">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<body class="load">
|
||||
|
||||
<div id="container">
|
||||
<header>
|
||||
<h1><a href="<?php echo YOURLS_SITE; ?>"><?php echo ISQ::$general['name']; ?></a></h1>
|
||||
<ul class="menu">
|
||||
<li><a href="<?php echo YOURLS_SITE; ?>"><?php echo ISQ::$general['name']; ?></a></li>
|
||||
<li><a href="<?php echo ISQ::$links['url_1']; ?>"><?php echo ISQ::$links['name_1']; ?></a></li>
|
||||
<li><a href="<?php echo ISQ::$links['url_2']; ?>"><?php echo ISQ::$links['name_2']; ?></a></li>
|
||||
<li><a href="<?php echo ISQ::$links['url_3']; ?>"><?php echo ISQ::$links['name_3']; ?></a></li>
|
||||
<li><a href="<?php echo ISQ::$links['url_4']; ?>"><?php echo ISQ::$links['name_4']; ?></a></li>
|
||||
<li><a href="<?php echo ISQ::$links['url_5']; ?>"><?php echo ISQ::$links['name_5']; ?></a></li>
|
||||
<li><a href="<?php echo ISQ::$links['url_6']; ?>"><?php echo ISQ::$links['name_6']; ?></a></li>
|
||||
<li><a href="<?php echo ISQ::$links['url_7']; ?>"><?php echo ISQ::$links['name_7']; ?></a></li>
|
||||
<li><a href="<?php echo ISQ::$links['url_8']; ?>"><?php echo ISQ::$links['name_8']; ?></a></li>
|
||||
<li><a href="<?php echo ISQ::$links['url_9']; ?>"><?php echo ISQ::$links['name_9']; ?></a></li>
|
||||
<li><a href="<?php echo ISQ::$links['url_10']; ?>"><?php echo ISQ::$links['name_10']; ?></a></li>
|
||||
</ul>
|
||||
<div class="wrapper">
|
||||
|
||||
<header class="content site-header">
|
||||
<a href="<?php echo YOURLS_SITE; ?>" class="site-title">
|
||||
<h1><?php echo ISQ::$general['name']; ?></h1>
|
||||
</a>
|
||||
<nav class="menu">
|
||||
<?php
|
||||
foreach( ISQ::$links as $menuItem ) {
|
||||
echo '<a href="' . $menuItem['link'] . '">' . $menuItem['name'] . '</a>';
|
||||
};
|
||||
?>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<div class="paragraph">
|
||||
|
||||
66
index.php
@@ -1,20 +1,70 @@
|
||||
<?php include('header.php');
|
||||
|
||||
$url = yourls_sanitize_url( $_REQUEST['url'] );
|
||||
$url = isset( $_REQUEST['url'] ) ? yourls_sanitize_url( $_REQUEST['url'] ) : '' ;
|
||||
$keyword = isset( $_REQUEST['keyword'] ) ? yourls_sanitize_keyword( $_REQUEST['keyword'] ) : '' ;
|
||||
$title = isset( $_REQUEST['title'] ) ? yourls_sanitize_title( $_REQUEST['title'] ) : '' ;
|
||||
|
||||
?>
|
||||
|
||||
<div class="content index">
|
||||
<h2><?php yourls_e( 'Enter a new URL to shorten', 'isq_translation'); ?></h2>
|
||||
<h3><?php yourls_e( 'Hover over the labels to see more information', 'isq_translation'); ?></h3>
|
||||
<form method="post" action="result.php">
|
||||
<p><label for="url" title="<?php yourls_e( 'Paste the long URL here', 'isq_translation'); ?>"><?php yourls_e( 'Long URL (required):', 'isq_translation'); ?></label> <input type="text" id="url" class="right" name="url" value="<?php echo($url); ?>" /></p>
|
||||
<p><label for="keyword" title="<?php yourls_e( 'A keyword replaces the default short string', 'isq_translation'); ?>"><?php yourls_e( 'Custom keyword:', 'isq_translation'); ?></label> <input type="text" id="keyword" class="right" name="keyword" value="<?php echo($keyword); ?>" /></p>
|
||||
<p><label for="title" title="<?php yourls_e( 'Optional title used when sharing a link from YOURLS using social sharers', 'isq_translation'); ?>"><?php yourls_e( 'Optional title:', 'isq_translation'); ?></label> <input type="text" id="title" class="right" name="title" value="<?php echo($title); ?>" /></p>
|
||||
<div class="recaptcha-container"><label title="<?php yourls_e( 'Verification used to ensure the user is not a bot', 'isq_translation'); ?>"><?php yourls_e( 'reCAPTCHA:', 'isq_translation'); ?></label> <div class="g-recaptcha right" data-sitekey="<?php echo ISQ::$recaptcha['sitekey']; ?>"></div></div>
|
||||
<form method="post" action="result.php" class="newurl" novalidate>
|
||||
<div class="form-item full-width">
|
||||
<p><label for="url" class="primary"><?php yourls_e( 'Long URL', 'isq_translation'); ?></label></p>
|
||||
<p><label for="url" class="secondary"><?php yourls_e( 'Paste the long URL here. This is required.', 'isq_translation'); ?></label></p>
|
||||
<input type="url" id="url" name="url" value="<?php echo($url); ?>" autofocus>
|
||||
</div>
|
||||
|
||||
<p><input type="submit" value="<?php yourls_e( 'Shorten', 'isq_translation'); ?>" /></p>
|
||||
<div class="halves">
|
||||
<div class="form-item half-width left">
|
||||
<p><label for="keyword" class="primary"><?php yourls_e( 'Custom keyword', 'isq_translation'); ?></label></p>
|
||||
<p><label for="keyword" class="secondary"><?php yourls_e( 'A keyword replaces the default short string.', 'isq_translation'); ?></label></p>
|
||||
<input type="text" id="keyword" name="keyword" autocorrect="off" autocapitalize="none" value="<?php echo($keyword); ?>">
|
||||
</div>
|
||||
|
||||
<div class="form-item half-width right">
|
||||
<p><label for="title" class="primary"><?php yourls_e( 'Custom title', 'isq_translation'); ?></label></p>
|
||||
<p><label for="title" class="secondary"><?php yourls_e( 'Optional title used when sharing a link from YOURLS using social sharers.', 'isq_translation'); ?></label></p>
|
||||
<input type="text" id="title" name="title" value="<?php echo($title); ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
switch( is_get_antispam_method() ) {
|
||||
case 'login': ?>
|
||||
<input type="hidden" name="antispam_method" value="user_login" class="hidden">
|
||||
<?php break;
|
||||
|
||||
case 'recaptcha_v3':
|
||||
$dependencies[] = 'recaptcha_v3';
|
||||
?>
|
||||
<input type="hidden" name="antispam_method" value="recaptcha_v3" class="hidden">
|
||||
<input type="hidden" name="recaptcha_token" id="recaptcha_token" class="hidden">
|
||||
<?php break;
|
||||
|
||||
case 'recaptcha':
|
||||
$dependencies[] = 'recaptcha';
|
||||
?>
|
||||
<input type="hidden" name="antispam_method" value="recaptcha" class="hidden">
|
||||
|
||||
<div class="form-item recaptcha-container">
|
||||
<p><label class="primary" title=""><?php yourls_e( 'Verification', 'isq_translation'); ?></label></p>
|
||||
<p><label class="secondary"><?php yourls_e( 'reCAPTCHA verification used to ensure you are not a bot.', 'isq_translation'); ?></label></p>
|
||||
<div class="g-recaptcha" data-sitekey="<?php echo ISQ::$recaptcha['sitekey']; ?>"></div>
|
||||
</div>
|
||||
<?php break;
|
||||
|
||||
default: ?>
|
||||
<input type="hidden" name="antispam_method" value="basic" class="hidden">
|
||||
<input type="hidden" name="basic_antispam" class="hidden">
|
||||
<?php break;
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="form-item submit-container">
|
||||
<input type="submit" class="button" value="<?php yourls_e( 'Shorten', 'isq_translation'); ?>">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php include('footer.php'); ?>
|
||||
|
||||
@@ -1,54 +1,62 @@
|
||||
<?php
|
||||
|
||||
// Copy and rename your file to config.php in this directory to edit your settings
|
||||
// Copy and rename your file to config.php in the /public/ directory to edit your settings
|
||||
// 0, FALSE or '' to disable
|
||||
// Pretty much everything else to enable, such as 1, TRUE or any string
|
||||
|
||||
// General settings
|
||||
// 1 to enable, 0 to disable
|
||||
// GENERAL SETTINGS
|
||||
ISQ::$general = array(
|
||||
'name' => 'URL shortener', // The name of your URL shortener
|
||||
'qr' => 1, // Do you want to display a QR code?
|
||||
'clipboard' => 1 // Do you want to enable zeroClipboard? (uses flash)
|
||||
'qr' => TRUE, // Do you want to display a QR code?
|
||||
'customstyle' => TRUE // Do you want to enable the custom stylesheet, found in public/custom.css?
|
||||
);
|
||||
|
||||
// Menu- The width of ∞² menu allows you to have about 10 links
|
||||
// Leave empty to disable
|
||||
// MENU LINKS
|
||||
// Add more comma seperated arrays to add more links
|
||||
ISQ::$links = array(
|
||||
'name_1' => 'Tom Slominski',
|
||||
'url_1' => 'http://tomslominski.net/',
|
||||
'name_2' => 'Get ∞²!',
|
||||
'url_2' => 'https://github.com/tomslominski/infinity-squared/',
|
||||
'name_3' => '',
|
||||
'url_3' => '',
|
||||
'name_4' => '',
|
||||
'url_4' => '',
|
||||
'name_5' => '',
|
||||
'url_5' => '',
|
||||
'name_6' => '',
|
||||
'url_6' => '',
|
||||
'name_7' => '',
|
||||
'url_7' => '',
|
||||
'name_8' => '',
|
||||
'url_8' => '',
|
||||
'name_9' => '',
|
||||
'url_9' => '',
|
||||
'name_10' => '',
|
||||
'url_10' => ''
|
||||
array(
|
||||
'name' => ISQ::$general['name'],
|
||||
'link' => YOURLS_SITE
|
||||
),
|
||||
array(
|
||||
'name' => 'Tom Slominski',
|
||||
'link' => 'https://slomin.ski/'
|
||||
),
|
||||
array(
|
||||
'name' => yourls__( 'Get ∞²!', 'isq_translation' ),
|
||||
'link' => 'https://github.com/tomslominski/infinity-squared/'
|
||||
),
|
||||
array(
|
||||
'name' => yourls__( 'Admin area', 'isq_translation' ),
|
||||
'link' => YOURLS_SITE . '/admin/'
|
||||
)
|
||||
);
|
||||
|
||||
// Social sharing
|
||||
// 1 to enable, 0 to disable
|
||||
// SOCIAL SHARING
|
||||
ISQ::$social = array(
|
||||
'facebook' => 1,
|
||||
'twitter' => 1,
|
||||
'plus' => 1,
|
||||
'linkedin' => 1,
|
||||
'tumblr' => 1
|
||||
'twitter' => TRUE,
|
||||
'appdotnet' => TRUE,
|
||||
'facebook' => TRUE,
|
||||
'linkedin' => TRUE,
|
||||
'tumblr' => TRUE,
|
||||
'googleplus' => TRUE,
|
||||
'vk' => TRUE,
|
||||
);
|
||||
|
||||
// reCAPTCHA API keys
|
||||
// reCAPTCHA API KEYS
|
||||
// Get yourls from https://www.google.com/recaptcha/admin
|
||||
// If you don't want to use reCAPTCHA, that's cool. Leave this empty, and basic
|
||||
// antispam protection will be provided.
|
||||
ISQ::$recaptcha = array(
|
||||
'sitekey' => '',
|
||||
'secret' => ''
|
||||
);
|
||||
|
||||
// Separate API keys for reCAPTCHA v3
|
||||
ISQ::$recaptcha_v3 = array(
|
||||
'sitekey' => '',
|
||||
'secret' => '',
|
||||
'threshold' => '0.5',
|
||||
);
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>Generated by IcoMoon</metadata>
|
||||
<defs>
|
||||
<font id="icons" horiz-adv-x="512">
|
||||
<font-face units-per-em="512" ascent="480" descent="-32" />
|
||||
<missing-glyph horiz-adv-x="512" />
|
||||
<glyph unicode=" " d="" horiz-adv-x="256" />
|
||||
<glyph unicode="" d="M512 221.714q0-7.428-5.428-12.857l-73.143-73.143q-5.428-5.428-12.857-5.428t-12.857 5.428-5.428 12.857v36.572h-109.714v-109.714h36.572q7.428 0 12.857-5.428t5.428-12.857-5.428-12.857l-73.143-73.143q-5.428-5.429-12.857-5.429t-12.857 5.429l-73.143 73.143q-5.428 5.428-5.428 12.857t5.428 12.857 12.857 5.428h36.571v109.714h-109.715v-36.572q0-7.428-5.428-12.857t-12.857-5.428-12.857 5.428l-73.143 73.143q-5.428 5.428-5.428 12.857t5.428 12.857l73.143 73.143q5.428 5.428 12.857 5.428t12.857-5.428 5.428-12.857v-36.571h109.715v109.714h-36.572q-7.428 0-12.857 5.428t-5.429 12.857 5.428 12.857l73.143 73.143q5.429 5.428 12.857 5.428t12.857-5.428l73.143-73.143q5.428-5.429 5.428-12.857t-5.428-12.857-12.857-5.428h-36.572v-109.714h109.714v36.572q0 7.428 5.428 12.857t12.857 5.428 12.857-5.428l73.143-73.143q5.428-5.429 5.428-12.857z" />
|
||||
</font></defs></svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -1,302 +0,0 @@
|
||||
/* `Widths
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
.input_tiny {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.input_small {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.input_medium {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.input_large {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.input_xlarge {
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.input_xxlarge {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.input_full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/*
|
||||
Added via JS to <textarea> and class="input_full".
|
||||
Applies only to IE7. Other browsers don't need it.
|
||||
*/
|
||||
.input_full_wrap {
|
||||
display: block;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
/* `UI Consistency
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
input[type="search"]::-webkit-search-decoration {
|
||||
display: none;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
textarea {
|
||||
-moz-background-clip: padding;
|
||||
-webkit-background-clip: padding;
|
||||
background-clip: padding-box;
|
||||
margin: 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
button,
|
||||
input[type="reset"],
|
||||
input[type="submit"],
|
||||
input[type="button"] {
|
||||
-webkit-appearance: none;
|
||||
-moz-border-radius: 11px;
|
||||
-webkit-border-radius: 11px;
|
||||
border-radius: 11px;
|
||||
background: #ddd url(../img/button.png) repeat-x;
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(1, #ddd));
|
||||
background: -moz-linear-gradient(top center, #fff 0%, #ddd 100%);
|
||||
border: 1px solid;
|
||||
border-color: #ddd #bbb #999;
|
||||
cursor: pointer;
|
||||
color: #333;
|
||||
font: bold 12px/1.2 Arial, sans-serif;
|
||||
outline: 0;
|
||||
overflow: visible;
|
||||
padding: 3px 10px 4px;
|
||||
text-shadow: #fff 0 1px 1px;
|
||||
width: auto;
|
||||
|
||||
/* IE7 */
|
||||
*padding-top: 2px;
|
||||
*padding-bottom: 0px;
|
||||
}
|
||||
|
||||
button {
|
||||
/* IE7 */
|
||||
*padding-top: 1px;
|
||||
*padding-bottom: 1px;
|
||||
}
|
||||
|
||||
button[disabled],
|
||||
input[type="reset"][disabled],
|
||||
input[type="submit"][disabled],
|
||||
input[type="button"][disabled] {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
textarea,
|
||||
select,
|
||||
input[type="date"],
|
||||
input[type="datetime"],
|
||||
input[type="datetime-local"],
|
||||
input[type="email"],
|
||||
input[type="month"],
|
||||
input[type="number"],
|
||||
input[type="password"],
|
||||
input[type="search"],
|
||||
input[type="tel"],
|
||||
input[type="text"],
|
||||
input[type="time"],
|
||||
input[type="url"],
|
||||
input[type="week"] {
|
||||
-webkit-appearance: none;
|
||||
-moz-border-radius: 0;
|
||||
-webkit-border-radius: 0;
|
||||
border-radius: 0;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
border: 1px solid;
|
||||
border-color: #848484 #c1c1c1 #e1e1e1;
|
||||
color: #000;
|
||||
outline: 0;
|
||||
padding: 2px 3px;
|
||||
font-size: 13px;
|
||||
font-family: Arial, sans-serif;
|
||||
height: 1.8em;
|
||||
|
||||
/* IE7 */
|
||||
*padding-top: 2px;
|
||||
*padding-bottom: 1px;
|
||||
*height: auto;
|
||||
}
|
||||
|
||||
/*
|
||||
Separate rule for Firefox.
|
||||
Cannot stack with WebKit's.
|
||||
*/
|
||||
input.placeholder_text,
|
||||
textarea.placeholder_text,
|
||||
input:-moz-placeholder,
|
||||
textarea:-moz-placeholder {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
::-webkit-input-placeholder {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
textarea[disabled],
|
||||
select[disabled],
|
||||
input[type="date"][disabled],
|
||||
input[type="datetime"][disabled],
|
||||
input[type="datetime-local"][disabled],
|
||||
input[type="email"][disabled],
|
||||
input[type="month"][disabled],
|
||||
input[type="number"][disabled],
|
||||
input[type="password"][disabled],
|
||||
input[type="search"][disabled],
|
||||
input[type="tel"][disabled],
|
||||
input[type="text"][disabled],
|
||||
input[type="time"][disabled],
|
||||
input[type="url"][disabled],
|
||||
input[type="week"][disabled] {
|
||||
background-color: #eee;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
button:focus,
|
||||
button:active,
|
||||
input:focus,
|
||||
input:active,
|
||||
select:focus,
|
||||
select:active,
|
||||
textarea:focus,
|
||||
textarea:active {
|
||||
-moz-box-shadow: #06f 0 0 7px;
|
||||
-webkit-box-shadow: #06f 0 0 7px;
|
||||
box-shadow: #06f 0 0 7px;
|
||||
|
||||
/* for Opera */
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
input[type="file"]:focus,
|
||||
input[type="file"]:active,
|
||||
input[type="radio"]:focus,
|
||||
input[type="radio"]:active,
|
||||
input[type="checkbox"]:focus,
|
||||
input[type="checkbox"]:active {
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.is_webkit select {
|
||||
/* Tweaks for Safari + Chrome. */
|
||||
background-image: url(../img/select_arrow.gif);
|
||||
background-repeat: no-repeat;
|
||||
background-position: right center;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
textarea,
|
||||
select[multiple] {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
select[multiple],
|
||||
.is_webkit select[multiple] {
|
||||
background-image: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
textarea {
|
||||
min-height: 40px;
|
||||
overflow: auto;
|
||||
resize: vertical;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
optgroup {
|
||||
color: #000;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* `IE6
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Everything below this line is for IE6.
|
||||
Delete it if you don't support it! :)
|
||||
|
||||
Classes are added dynamically via JS,
|
||||
because IE6 doesn't support attribute
|
||||
selectors: .ie6_button, .ie6_input, etc.
|
||||
|
||||
Note: These style rules are somewhat
|
||||
duplicated because IE6 bombs out when
|
||||
it sees attribute selectors. Example:
|
||||
|
||||
.ie6_button {
|
||||
This works in IE6.
|
||||
}
|
||||
|
||||
.ie6_button,
|
||||
input[type=submit] {
|
||||
This doesn't work.
|
||||
}
|
||||
*/
|
||||
|
||||
.ie6_button,
|
||||
* html button {
|
||||
background: #ddd url(../img/button.png) repeat-x;
|
||||
border: 1px solid;
|
||||
border-color: #ddd #bbb #999;
|
||||
cursor: pointer;
|
||||
color: #333;
|
||||
font: bold 12px/1.2 Arial, sans-serif;
|
||||
padding: 2px 10px 0px;
|
||||
overflow: visible;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
* html button {
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
|
||||
.ie6_input,
|
||||
* html textarea,
|
||||
* html select {
|
||||
background: #fff;
|
||||
border: 1px solid;
|
||||
border-color: #848484 #c1c1c1 #e1e1e1;
|
||||
color: #000;
|
||||
padding: 2px 3px 1px;
|
||||
font-size: 13px;
|
||||
font-family: Arial, sans-serif;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
* html select {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
.placeholder_text,
|
||||
.ie6_input_disabled,
|
||||
.ie6_button_disabled {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.ie6_input_disabled {
|
||||
background: #eee;
|
||||
}
|
||||
67
public/functions.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Return which method is being used for preventing spam,
|
||||
* based on the site config.
|
||||
*
|
||||
* @return string login/recaptcha_v3/recaptcha/basic
|
||||
*/
|
||||
function is_get_antispam_method() {
|
||||
if( 1 == yourls_is_valid_user() ) {
|
||||
return 'login';
|
||||
} elseif( isset( ISQ::$recaptcha_v3['sitekey'] ) && ISQ::$recaptcha_v3['sitekey'] && isset( ISQ::$recaptcha_v3['secret'] ) && ISQ::$recaptcha_v3['secret'] ) {
|
||||
return 'recaptcha_v3';
|
||||
} elseif( isset( ISQ::$recaptcha['sitekey'] ) && ISQ::$recaptcha['sitekey'] && isset( ISQ::$recaptcha['secret'] ) && ISQ::$recaptcha['secret'] ) {
|
||||
return 'recaptcha';
|
||||
} else {
|
||||
return 'basic';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Terminate the request without shortening the URL and
|
||||
* display an error.
|
||||
*
|
||||
* @param string $message Error message.
|
||||
* @param string $action Action message, defaults to "Go home".
|
||||
*/
|
||||
function display_error( $message, $action = null ) {
|
||||
echo '<div class="content error">';
|
||||
echo '<p class="message">' . $message . '</p>';
|
||||
|
||||
echo '<p class="action">';
|
||||
if( !empty( $action ) ) {
|
||||
echo $action;
|
||||
} else {
|
||||
echo '<a href="' . YOURLS_SITE . '" class="button">' . yourls__( '← Go home and try again', 'isq_translation' ) . '</a>';
|
||||
}
|
||||
echo '</p>';
|
||||
echo '</div>';
|
||||
|
||||
include('footer.php');
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get remote file, either using CURL or file_get_contents
|
||||
* depending on server configuration.
|
||||
*
|
||||
* @param string $url Remote file URL.
|
||||
* @return string Remote file contents.
|
||||
*/
|
||||
function get_remote_file( $url ) {
|
||||
if( function_exists( 'curl_init' ) ) {
|
||||
$curl = curl_init();
|
||||
curl_setopt( $curl, CURLOPT_URL, $url );
|
||||
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
|
||||
$output = curl_exec( $curl );
|
||||
curl_close( $curl );
|
||||
return $output;
|
||||
} elseif( ini_get( 'allow_url_fopen' ) ) {
|
||||
return file_get_contents( $url );
|
||||
} else {
|
||||
display_error( yourls__( 'Your server doesn\'t support reCAPTCHA. Ask your host to install cURL or turn on allow_url_fopen.', 'isq_translation' ) );
|
||||
}
|
||||
}
|
||||
BIN
public/images/app-icons/android-chrome-144x144.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
public/images/app-icons/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
public/images/app-icons/android-chrome-36x36.png
Normal file
|
After Width: | Height: | Size: 901 B |
BIN
public/images/app-icons/android-chrome-48x48.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
public/images/app-icons/android-chrome-72x72.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
public/images/app-icons/android-chrome-96x96.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
public/images/app-icons/apple-touch-icon-114x114.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
public/images/app-icons/apple-touch-icon-120x120.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
public/images/app-icons/apple-touch-icon-144x144.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
public/images/app-icons/apple-touch-icon-152x152.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
public/images/app-icons/apple-touch-icon-180x180.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
public/images/app-icons/apple-touch-icon-57x57.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
public/images/app-icons/apple-touch-icon-60x60.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
public/images/app-icons/apple-touch-icon-72x72.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
public/images/app-icons/apple-touch-icon-76x76.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
public/images/app-icons/apple-touch-icon-precomposed.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
public/images/app-icons/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
12
public/images/app-icons/browserconfig.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square70x70logo src="public/images/app-icons/mstile-70x70.png"/>
|
||||
<square150x150logo src="public/images/app-icons/mstile-150x150.png"/>
|
||||
<square310x310logo src="public/images/app-icons/mstile-310x310.png"/>
|
||||
<wide310x150logo src="public/images/app-icons/mstile-310x150.png"/>
|
||||
<TileColor>#2b5797</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
||||
BIN
public/images/app-icons/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 340 B |
BIN
public/images/app-icons/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 770 B |
BIN
public/images/app-icons/favicon-96x96.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
public/images/app-icons/favicon.ico
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
41
public/images/app-icons/manifest.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "\u221e\u00b2",
|
||||
"icons": [
|
||||
{
|
||||
"src": "public\/images\/app-icons\/android-chrome-36x36.png",
|
||||
"sizes": "36x36",
|
||||
"type": "image\/png",
|
||||
"density": "0.75"
|
||||
},
|
||||
{
|
||||
"src": "public\/images\/app-icons\/android-chrome-48x48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image\/png",
|
||||
"density": "1.0"
|
||||
},
|
||||
{
|
||||
"src": "public\/images\/app-icons\/android-chrome-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image\/png",
|
||||
"density": "1.5"
|
||||
},
|
||||
{
|
||||
"src": "public\/images\/app-icons\/android-chrome-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image\/png",
|
||||
"density": "2.0"
|
||||
},
|
||||
{
|
||||
"src": "public\/images\/app-icons\/android-chrome-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image\/png",
|
||||
"density": "3.0"
|
||||
},
|
||||
{
|
||||
"src": "public\/images\/app-icons\/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image\/png",
|
||||
"density": "4.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
public/images/app-icons/mstile-144x144.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
public/images/app-icons/mstile-150x150.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
public/images/app-icons/mstile-310x150.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
public/images/app-icons/mstile-310x310.png
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
public/images/app-icons/mstile-70x70.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
1
public/images/appdotnet.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64.1 64.1" enable-background="new 0 0 64.1 64.1"><path d="M32 7.9L0 56.2h6.6l7.3-11.4h36.4l7.3 11.4h6.6L32 7.9zM18 39.5l14-21.1 14 21.1H18z"/></svg>
|
||||
|
After Width: | Height: | Size: 201 B |
12
public/images/clippy.svg
Executable file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="14px" height="16px" viewBox="0 0 14 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 3.8.3 (29802) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>clippy</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Octicons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="clippy" fill="#000000">
|
||||
<path d="M2,13 L6,13 L6,14 L2,14 L2,13 L2,13 Z M7,7 L2,7 L2,8 L7,8 L7,7 L7,7 Z M9,10 L9,8 L6,11 L9,14 L9,12 L14,12 L14,10 L9,10 L9,10 Z M4.5,9 L2,9 L2,10 L4.5,10 L4.5,9 L4.5,9 Z M2,12 L4.5,12 L4.5,11 L2,11 L2,12 L2,12 Z M11,13 L12,13 L12,15 C11.98,15.28 11.89,15.52 11.7,15.7 C11.51,15.88 11.28,15.98 11,16 L1,16 C0.45,16 0,15.55 0,15 L0,4 C0,3.45 0.45,3 1,3 L4,3 C4,1.89 4.89,1 6,1 C7.11,1 8,1.89 8,3 L11,3 C11.55,3 12,3.45 12,4 L12,9 L11,9 L11,6 L1,6 L1,15 L11,15 L11,13 L11,13 Z M2,5 L10,5 C10,4.45 9.55,4 9,4 L8,4 C7.45,4 7,3.55 7,3 C7,2.45 6.55,2 6,2 C5.45,2 5,2.45 5,3 C5,3.55 4.55,4 4,4 L3,4 C2.45,4 2,4.45 2,5 L2,5 Z" id="Shape"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
1
public/images/facebook.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 59.4 59.4" enable-background="new 0 0 59.4 59.4"><path d="M45.1.4v9.4h-5.6c-2 0-3.4.4-4.1 1.3-.7.9-1.1 2.1-1.1 3.9v6.8h10.5l-1.4 10.6h-9.1v27.1H23.4V32.3h-9.1V21.8h9.1V14c0-4.4 1.2-7.9 3.7-10.3C29.6 1.2 32.9 0 37 0c3.5 0 6.2.1 8.1.4z"/></svg>
|
||||
|
After Width: | Height: | Size: 295 B |
5
public/images/github.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 54.9 53.5" enable-background="new 0 0 54.9 53.5" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M54.9 27.4c0 6-1.7 11.4-5.2 16.1c-3.5 4.8-8 8.1-13.5 9.9c-0.6 0.1-1.1 0-1.4-0.2c-0.3-0.3-0.4-0.6-0.4-1.1v-7.5 c0-2.3-0.6-4-1.9-5.1c1.4-0.1 2.6-0.4 3.7-0.6s2.2-0.8 3.4-1.4c1.2-0.6 2.1-1.4 2.9-2.4s1.4-2.2 1.9-3.8s0.7-3.4 0.7-5.4 c0-2.9-0.9-5.3-2.8-7.4c0.9-2.2 0.8-4.6-0.3-7.3c-0.7-0.2-1.6-0.1-2.9 0.4c-1.3 0.5-2.4 1-3.3 1.6l-1.4 0.9 c-2.2-0.6-4.5-0.9-6.9-0.9c-2.4 0-4.6 0.3-6.9 0.9c-0.4-0.3-0.9-0.6-1.5-1s-1.6-0.8-3-1.4s-2.4-0.7-3.1-0.5c-1 2.7-1.1 5.1-0.2 7.3 c-1.9 2-2.8 4.5-2.8 7.4c0 2 0.2 3.8 0.7 5.4c0.5 1.5 1.1 2.8 1.9 3.8c0.8 1 1.7 1.8 2.9 2.4c1.2 0.6 2.3 1.1 3.4 1.4 c1.1 0.3 2.3 0.5 3.7 0.6c-1 0.9-1.5 2.1-1.8 3.7c-0.5 0.2-1 0.4-1.6 0.5c-0.6 0.1-1.2 0.2-2 0.2s-1.6-0.3-2.3-0.8 c-0.8-0.5-1.4-1.3-2-2.2c-0.5-0.8-1-1.4-1.7-1.9s-1.3-0.8-1.8-0.9l-0.7-0.1c-0.5 0-0.8 0.1-1 0.2c-0.2 0.1-0.2 0.2-0.2 0.4 c0.1 0.2 0.2 0.3 0.3 0.5c0.1 0.2 0.3 0.3 0.5 0.4l0.2 0.2c0.5 0.2 1 0.7 1.6 1.4c0.5 0.7 0.9 1.3 1.1 1.8l0.4 0.8 c0.3 0.9 0.8 1.6 1.6 2.2c0.7 0.6 1.5 0.9 2.4 1.1c0.9 0.2 1.7 0.2 2.5 0.2s1.5 0 2-0.1l0.8-0.1c0 0.9 0 2 0 3.2c0 1.2 0 1.9 0 1.9 c0 0.4-0.2 0.8-0.5 1.1c-0.3 0.3-0.8 0.4-1.4 0.2c-5.5-1.8-10-5.1-13.5-9.9C1.7 38.8 0 33.4 0 27.4c0-5 1.2-9.6 3.7-13.8 c2.5-4.2 5.8-7.5 10-10C17.9 1.2 22.5 0 27.4 0c5 0 9.6 1.2 13.8 3.7c4.2 2.5 7.5 5.8 10 10C53.6 17.9 54.9 22.5 54.9 27.4z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
1
public/images/googleplus.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 59.4 59.4" enable-background="new 0 0 59.4 59.4"><path d="M26.6 28.4c0 .9.4 1.7 1.1 2.5s1.7 1.6 2.8 2.4 2.2 1.7 3.2 2.6c1.1 1 2 2.2 2.8 3.7.8 1.5 1.1 3.2 1.1 5.1 0 2.1-.6 4.2-1.7 6.2-1.7 2.9-4.2 5-7.5 6.4-3.3 1.4-6.9 2.1-10.6 2.1-3.1 0-6.1-.5-8.8-1.5-2.7-1-4.8-2.6-6.1-4.9-.9-1.4-1.3-3-1.3-4.7 0-1.9.5-3.7 1.6-5.4 1.1-1.6 2.5-3 4.2-4.1 3.1-2 7.9-3.1 14.4-3.6-.8-1-1.3-1.9-1.7-2.6-.4-.8-.6-1.6-.6-2.6 0-.9.2-1.9.8-3-1.1.1-1.9.1-2.4.1-3.5 0-6.5-1.1-8.9-3.4-2.4-2.3-3.6-5.2-3.6-8.7 0-2 .4-3.8 1.3-5.7.9-1.8 2-3.4 3.5-4.7 1.8-1.6 4-2.7 6.5-3.5 2.4-.7 5-1.1 7.7-1.1h14.9l-4.9 3.1h-4.7c1.8 1.5 3.1 3.1 4 4.8.9 1.7 1.4 3.6 1.4 5.7 0 1.7-.3 3.3-.9 4.6-.6 1.4-1.3 2.5-2.1 3.3-.8.8-1.7 1.6-2.5 2.3-.8.7-1.5 1.4-2.1 2.2-.6.8-.9 1.6-.9 2.4zm-5.2 27.8c1.4 0 2.7-.2 4-.5 1.3-.3 2.5-.8 3.5-1.4 1.1-.6 2-1.5 2.6-2.6.7-1.1 1-2.4 1-3.9 0-.6-.1-1.2-.2-1.8-.2-.6-.3-1.1-.5-1.5-.2-.4-.5-.9-1-1.5s-.8-1-1.1-1.2c-.2-.3-.7-.7-1.4-1.2s-1.1-.9-1.3-1c-.2-.1-.7-.5-1.5-1.1-.8-.6-1.2-.9-1.3-.9-.4 0-1-.1-1.7-.1-1.3 0-2.5.1-3.8.2-1.2.2-2.5.5-3.8.9s-2.5 1-3.5 1.6c-1 .7-1.8 1.6-2.4 2.7-.6 1.1-1 2.4-1 3.8 0 1.7.4 3.1 1.2 4.4.8 1.3 1.9 2.3 3.3 3 1.3.7 2.8 1.2 4.2 1.6 1.7.3 3.2.5 4.7.5zm0-31.2c.9 0 1.8-.2 2.8-.6 1-.4 1.7-.9 2.4-1.6 1.3-1.4 1.9-3.2 1.9-5.7 0-1.4-.2-2.9-.6-4.5-.4-1.6-1-3.1-1.7-4.6-.8-1.5-1.8-2.7-3-3.7-1.3-1-2.7-1.5-4.2-1.5-1 0-2 .2-2.9.7-1 .5-1.7 1.1-2.3 1.9-1.1 1.4-1.7 3.3-1.7 5.7 0 1.1.1 2.3.4 3.5.2 1.2.6 2.5 1.1 3.7.5 1.2 1.1 2.3 1.9 3.3.7 1 1.6 1.8 2.7 2.4.8.7 1.9 1 3.2 1zm29-.1H58v3.9h-7.6v7.8h-3.8v-7.8H39v-3.9h7.6v-7.8h3.8v7.8z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
1
public/images/linkedin.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 54.9 54.9" enable-background="new 0 0 54.9 54.9"><path d="M13.2 7.3c0 1.7-.6 3.2-1.8 4.4-1.2 1.2-2.8 1.8-4.8 1.8h-.1c-2 0-3.5-.6-4.7-1.8C.6 10.5 0 9.1 0 7.3c0-1.8.6-3.2 1.8-4.4C3 1.7 4.6 1.2 6.6 1.2s3.6.6 4.8 1.7c1.2 1.2 1.8 2.7 1.8 4.4zm-.7 11v35.4H.7V18.3h11.8zm42.4 15.1v20.3H43.1v-19c0-2.5-.5-4.5-1.4-5.9s-2.5-2.1-4.5-2.1c-1.5 0-2.8.4-3.8 1.2-1 .8-1.8 1.8-2.3 3.1-.3.7-.4 1.7-.4 2.9v19.8H19c0-9.5.1-17.2.1-23.1V18.3h11.7v5.1h-.1c.5-.8 1-1.4 1.5-2 .5-.6 1.2-1.2 2-1.9s1.9-1.2 3.1-1.6c1.2-.4 2.6-.6 4.1-.6 4.1 0 7.3 1.4 9.8 4.1 2.4 2.8 3.7 6.7 3.7 12z"/></svg>
|
||||
|
After Width: | Height: | Size: 615 B |
BIN
public/images/logo.sketch
Normal file
1
public/images/logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="868" height="330" viewBox="0 0 868 330" xmlns="http://www.w3.org/2000/svg"><title>logo 2</title><g stroke="#000" fill="none" fill-rule="evenodd"><path d="M395 243c4.1.5 12.9 1.6 17.2 1.6 55.1 0 96-34.5 111.8-79.6-13.6-11.5-22.7-20-39-25-5.6 32-36.7 57-72 57-7.9 0-15.3-1.2-22.5-3.4" stroke-width="17.01"/><path d="M343.9 166.5c-14.6-12.4-27.9-26.7-41-38.8-.8-.7-.8-1.9-.1-2.7 29.9-30.7 65.9-68.4 110.4-68.4 24.9 0 45.6 12.1 57.2 31.4 21.7 2.5 41.3 11.3 59.3 23.3C523.4 51.1 478.8 9 416.5 9 353 9 311.2 52.5 271.2 92.5c-.7.7-1.9.7-2.7 0-37.7-37.8-81-83.5-139-83.5C59.8 9 9 63.7 9 126.4c0 68.2 47.6 117.3 114.1 117.3 63.5 0 105.3-43.4 145.3-83.5.7-.7 1.9-.7 2.7 0 20.3 20.3 42.2 42.9 67.1 59.5m-101.4-92c-29.9 30.7-65.9 68.4-110.4 68.4-38.8 0-67.4-29.3-67.4-69.8 0-37.3 30.1-69.8 69.8-69.8 45.3 0 77.5 40 108 68.4.7.9.7 2.1 0 2.8z" stroke-width="16.075"/><path d="M473 87.3c-4.1-.5-10.8 0-15.1 0-55.1 0-99.2 32.6-114.9 77.7 13 13 29 23 45.4 27.8 5.6-32 33.4-57.9 68.7-57.9 7.9 0 15.3 1.2 22.5 3.4" stroke-width="17.01"/><path d="M524.1 164.4c14.6 12.4 27.9 26.7 41 38.8.8.7.8 1.9.1 2.7-29.9 30.7-65.9 68.4-110.4 68.4-24.9 0-45.6-12.1-57.2-31.4-21.7-2.5-41.3-11.3-59.3-23.3 6.5 60.2 51.8 102.2 113.3 102.2 63.5 0 105.3-43.4 145.3-83.5.7-.7 1.9-.7 2.7 0 37.7 37.8 81 83.5 139 83.5 69.8 0 120.5-54.7 120.5-117.3 0-68.2-46.8-117.3-114.1-117.3-63.5 0-105.3 43.4-145.3 83.5-.7.7-1.9.7-2.7 0-20.3-20.3-42.2-42.9-67.1-59.5m209.4 163.2c-45.3 0-77.5-40-108-68.4-.8-.7-.8-1.9-.1-2.7 29.9-30.7 65.9-68.4 110.4-68.4 38.8 0 67.4 29.3 67.4 69.8.1 37.2-30 69.7-69.7 69.7z" stroke-width="16.075"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
5
public/images/move.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M64 32c0 0.6-0.2 1.2-0.7 1.6l-9.1 9.1c-0.5 0.5-1 0.7-1.6 0.7s-1.2-0.2-1.6-0.7c-0.5-0.5-0.7-1-0.7-1.6v-4.6H36.6v13.7h4.6c0.6 0 1.2 0.2 1.6 0.7 0.5 0.5 0.7 1 0.7 1.6s-0.2 1.2-0.7 1.6l-9.1 9.1c-0.5 0.5-1 0.7-1.6 0.7s-1.2-0.2-1.6-0.7l-9.1-9.1c-0.5-0.5-0.7-1-0.7-1.6s0.2-1.2 0.7-1.6c0.5-0.5 1-0.7 1.6-0.7h4.6V36.6H13.7v4.6c0 0.6-0.2 1.2-0.7 1.6 -0.5 0.5-1 0.7-1.6 0.7s-1.2-0.2-1.6-0.7l-9.1-9.1C0.2 33.2 0 32.6 0 32s0.2-1.2 0.7-1.6l9.1-9.1c0.5-0.5 1-0.7 1.6-0.7s1.2 0.2 1.6 0.7c0.5 0.5 0.7 1 0.7 1.6v4.6h13.7V13.7h-4.6c-0.6 0-1.2-0.2-1.6-0.7 -0.5-0.5-0.7-1-0.7-1.6s0.2-1.2 0.7-1.6l9.1-9.1C30.8 0.2 31.4 0 32 0c0.6 0 1.2 0.2 1.6 0.7l9.1 9.1c0.5 0.5 0.7 1 0.7 1.6s-0.2 1.2-0.7 1.6c-0.5 0.5-1 0.7-1.6 0.7h-4.6v13.7h13.7v-4.6c0-0.6 0.2-1.2 0.7-1.6 0.5-0.5 1-0.7 1.6-0.7s1.2 0.2 1.6 0.7l9.1 9.1C63.8 30.8 64 31.4 64 32z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
1
public/images/tumblr.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 59.4 59.4" enable-background="new 0 0 59.4 59.4"><path d="M43.9 47.5l2.9 8.5c-.5.8-1.9 1.6-4 2.4-2.1.7-4.2 1.1-6.3 1.1-2.5 0-4.7-.3-6.8-.9-2.1-.7-3.8-1.5-5.1-2.6-1.3-1.1-2.5-2.4-3.4-3.8s-1.6-2.9-2-4.3c-.4-1.4-.6-2.8-.6-4.2V24.1h-6v-7.7c1.7-.6 3.2-1.4 4.6-2.5 1.4-1 2.4-2.1 3.2-3.2.8-1.1 1.5-2.3 2.1-3.6.6-1.3 1-2.5 1.2-3.5.2-1 .4-2.1.5-3.2 0-.1.1-.2.2-.3.2-.1.3-.1.4-.1h8.7v15.1h11.9v9h-12v18.5c0 .7.1 1.4.2 2 .2.6.4 1.2.8 1.9.4.6 1 1.1 1.8 1.5.8.4 1.8.5 2.9.5 1.9 0 3.5-.4 4.8-1z"/></svg>
|
||||
|
After Width: | Height: | Size: 542 B |
1
public/images/twitter.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 56.3 56.3" enable-background="new 0 0 56.3 56.3"><path d="M56.3 10.7c-1.6 2.3-3.5 4.3-5.8 6v1.5c0 3.1-.5 6.2-1.4 9.3-.9 3.1-2.3 6-4.1 8.9-1.8 2.8-4 5.3-6.6 7.5-2.5 2.2-5.6 3.9-9.2 5.2-3.6 1.3-7.4 1.9-11.5 1.9-6.4 0-12.3-1.7-17.7-5.2.8.1 1.8.2 2.8.2 5.4 0 10.1-1.6 14.3-4.9-2.5 0-4.7-.8-6.7-2.3-2-1.5-3.3-3.4-4.1-5.7.8.1 1.5.2 2.2.2 1 0 2-.1 3-.4-2.7-.5-4.9-1.9-6.6-4-1.8-2.1-2.6-4.6-2.6-7.3v-.1c1.6.9 3.4 1.4 5.2 1.5-1.6-1-2.8-2.4-3.8-4.1-.9-1.7-1.4-3.5-1.4-5.5 0-2.1.5-4 1.6-5.8 2.9 3.5 6.4 6.4 10.5 8.5 4.1 2.1 8.6 3.3 13.3 3.6-.2-.9-.3-1.8-.3-2.6 0-3.2 1.1-5.9 3.4-8.2s5-3.4 8.2-3.4c3.3 0 6.1 1.2 8.4 3.6 2.6-.5 5-1.4 7.3-2.8-.9 2.7-2.6 4.9-5.1 6.4 2.3-.4 4.5-1 6.7-2z"/></svg>
|
||||
|
After Width: | Height: | Size: 733 B |
1
public/images/vk.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="548.358" height="548.358" viewBox="0 0 548.358 548.358"><path d="M545.45 400.298c-.663-1.43-1.282-2.618-1.857-3.57-9.514-17.134-27.695-38.166-54.532-63.1l-.566-.572-.284-.28-.287-.287h-.288c-12.18-11.612-19.893-19.42-23.123-23.416-5.91-7.614-7.234-15.32-4.004-23.13 2.282-5.9 10.854-18.36 25.696-37.397 7.807-10.09 13.99-18.175 18.556-24.267 32.93-43.78 47.208-71.756 42.828-83.94l-1.7-2.846c-1.144-1.714-4.094-3.282-8.847-4.712-4.763-1.427-10.852-1.663-18.277-.712l-82.224.568c-1.333-.472-3.235-.428-5.713.144-2.475.572-3.713.86-3.713.86l-1.43.714-1.137.86c-.952.567-2 1.566-3.142 2.994-1.137 1.423-2.088 3.093-2.848 4.996-8.952 23.03-19.13 44.444-30.553 64.238-7.043 11.803-13.51 22.032-19.418 30.693-5.9 8.658-10.848 15.037-14.842 19.126-4 4.093-7.61 7.372-10.852 9.85-3.237 2.477-5.708 3.524-7.42 3.14-1.714-.382-3.33-.762-4.858-1.142-2.663-1.713-4.805-4.044-6.42-6.994-1.622-2.95-2.714-6.663-3.285-11.136-.57-4.476-.905-8.326-1-11.563-.09-3.233-.05-7.806.144-13.706.198-5.902.287-9.896.287-11.99 0-7.234.142-15.085.425-23.555.288-8.47.52-15.18.716-20.125.195-4.95.285-10.185.285-15.705s-.336-9.85-1-12.99c-.656-3.14-1.663-6.185-2.99-9.138-1.335-2.95-3.29-5.232-5.853-6.852-2.57-1.618-5.763-2.902-9.564-3.856-10.09-2.284-22.936-3.52-38.547-3.71-35.4-.38-58.147 1.905-68.235 6.854-3.997 2.09-7.614 4.948-10.848 8.562-3.427 4.19-3.905 6.475-1.43 6.85 11.42 1.712 19.507 5.805 24.266 12.276l1.715 3.43c1.334 2.473 2.666 6.853 4 13.133 1.33 6.28 2.19 13.227 2.567 20.837.95 13.897.95 25.793 0 35.69-.953 9.9-1.853 17.606-2.712 23.126-.86 5.52-2.143 9.993-3.855 13.418-1.715 3.426-2.856 5.52-3.428 6.28-.57.76-1.047 1.24-1.425 1.427-2.474.948-5.047 1.43-7.71 1.43-2.667 0-5.9-1.333-9.707-4-3.805-2.665-7.754-6.327-11.847-10.99-4.092-4.666-8.708-11.185-13.85-19.56-5.136-8.373-10.466-18.27-15.986-29.69l-4.567-8.282c-2.855-5.327-6.755-13.085-11.704-23.266-4.952-10.185-9.33-20.037-13.134-29.554-1.522-3.997-3.807-7.04-6.852-9.134l-1.43-.86c-.95-.76-2.474-1.566-4.566-2.426-2.095-.86-4.28-1.475-6.567-1.854l-78.23.568c-7.993 0-13.417 1.81-16.273 5.428l-1.143 1.71c-.572.954-.86 2.476-.86 4.57 0 2.095.57 4.665 1.714 7.708 11.42 26.84 23.84 52.725 37.257 77.66 13.42 24.933 25.08 45.018 34.974 60.236 9.897 15.23 19.985 29.602 30.264 43.112 10.28 13.515 17.083 22.176 20.412 25.98 3.333 3.813 5.95 6.663 7.854 8.566l7.14 6.85c4.567 4.57 11.275 10.042 20.126 16.417 8.853 6.38 18.654 12.66 29.408 18.85 10.756 6.182 23.27 11.226 37.546 15.127 14.275 3.905 28.17 5.472 41.684 4.716h32.834c6.66-.575 11.704-2.67 15.133-6.283l1.136-1.43c.765-1.137 1.48-2.902 2.14-5.277.668-2.38 1-5 1-7.85-.195-8.184.428-15.56 1.852-22.125 1.423-6.564 3.045-11.513 4.86-14.846 1.812-3.33 3.858-6.14 6.135-8.418 2.282-2.283 3.908-3.666 4.862-4.142.947-.48 1.704-.804 2.275-1 4.568-1.52 9.944-.047 16.136 4.43 6.188 4.473 11.99 9.996 17.42 16.56 5.424 6.57 11.942 13.94 19.554 22.124 7.617 8.186 14.277 14.27 19.985 18.274l5.707 3.426c3.812 2.286 8.76 4.38 14.853 6.283 6.08 1.9 11.41 2.377 15.984 1.426l73.087-1.14c7.23 0 12.855-1.197 16.845-3.572 3.998-2.38 6.373-5 7.14-7.85.763-2.855.804-6.093.144-9.713-.678-3.61-1.345-6.135-2.01-7.562z"/></svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 85 B |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 52 B |
|
Before Width: | Height: | Size: 700 B |
61
public/js/app.js
Normal file
@@ -0,0 +1,61 @@
|
||||
function filterNodeListById( nodeList, id ) {
|
||||
|
||||
var elements = Array.prototype.slice.call( nodeList );
|
||||
|
||||
for (var i = elements.length - 1; i >= 0; i--) {
|
||||
if( elements[i].id == id ) {
|
||||
return elements[i];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Clipboard.js
|
||||
if( document.querySelectorAll( '.copy-button' ).length > 0 ) {
|
||||
|
||||
var clipboard = new Clipboard( '.copy-button' );
|
||||
var clipboardTimeout = 2000;
|
||||
|
||||
clipboard.on( 'success', function( event ) {
|
||||
var errorElement = filterNodeListById( event.trigger.parentNode.childNodes, 'copy-success' );
|
||||
|
||||
errorElement.className += " visible";
|
||||
|
||||
window.setTimeout( function() {
|
||||
errorElement.className = errorElement.className.replace(/\bvisible\b/,'');
|
||||
}, clipboardTimeout );
|
||||
} );
|
||||
|
||||
clipboard.on( 'error', function( event ) {
|
||||
var errorElement = filterNodeListById( event.trigger.parentNode.childNodes, 'copy-error' );
|
||||
var osClass;
|
||||
|
||||
if( /iPhone|iPad/i.test(navigator.userAgent) ) {
|
||||
osClass = 'mobile';
|
||||
} else if ( /Mac/i.test(navigator.userAgent) ) {
|
||||
osClass = 'macos';
|
||||
} else if ( /Windows/i.test(navigator.userAgent) || /X11/i.test(navigator.userAgent) ) {
|
||||
osClass = 'pc';
|
||||
} else {
|
||||
osClass = 'other';
|
||||
}
|
||||
|
||||
errorElement.className += " visible " + osClass;
|
||||
|
||||
window.setTimeout( function() {
|
||||
errorElement.className = errorElement.className.replace(/\bvisible\b/,'');
|
||||
}, clipboardTimeout );
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
// reCAPTCHA
|
||||
if( 'object' === typeof grecaptcha ) {
|
||||
grecaptcha.ready( function() {
|
||||
var sitekey = document.querySelectorAll( '#recaptcha-sitekey' )[0].innerHTML;
|
||||
|
||||
grecaptcha.execute( sitekey, {action: 'homepage'} ).then( function( token ) {
|
||||
document.querySelectorAll( '#recaptcha_token' )[0].value = token;
|
||||
});
|
||||
});
|
||||
}
|
||||
7
public/js/clipboard.min.js
vendored
Executable file
1
public/js/jquery.formalize.min.js
vendored
@@ -1 +0,0 @@
|
||||
var FORMALIZE=function(a,b,c,d){var e="placeholder"in c.createElement("input"),f="autofocus"in c.createElement("input"),g="webkitAppearance"in c.createElement("select").style,h=!!a.browser.msie&&parseInt(a.browser.version,10)===6,i=!!a.browser.msie&&parseInt(a.browser.version,10)===7;return{go:function(){for(var a in FORMALIZE.init)FORMALIZE.init[a]()},init:{detect_webkit:function(){!g||a(c.documentElement).addClass("is_webkit")},full_input_size:function(){!!i&&!!a("textarea, input.input_full").length&&a("textarea, input.input_full").wrap('<span class="input_full_wrap"></span>')},ie6_skin_inputs:function(){if(!!h&&!!a("input, select, textarea").length){var b=/button|submit|reset/,c=/date|datetime|datetime-local|email|month|number|password|range|search|tel|text|time|url|week/;a("input").each(function(){var d=a(this);this.getAttribute("type").match(b)?(d.addClass("ie6_button"),this.disabled&&d.addClass("ie6_button_disabled")):this.getAttribute("type").match(c)&&(d.addClass("ie6_input"),this.disabled&&d.addClass("ie6_input_disabled"))}),a("textarea, select").each(function(){this.disabled&&a(this).addClass("ie6_input_disabled")})}},autofocus:function(){!f&&!!a(":input[autofocus]").length&&a(":input[autofocus]:visible:first").focus()},placeholder:function(){!e&&!!a(":input[placeholder]").length&&(FORMALIZE.misc.add_placeholder(),a(":input[placeholder]").each(function(){var b=a(this),c=b.attr("placeholder");b.focus(function(){b.val()===c&&b.val("").removeClass("placeholder_text")}).blur(function(){FORMALIZE.misc.add_placeholder()}),b.closest("form").submit(function(){b.val()===c&&b.val("").removeClass("placeholder_text")}).bind("reset",function(){setTimeout(FORMALIZE.misc.add_placeholder,50)})}))}},misc:{add_placeholder:function(){!e&&!!a(":input[placeholder]").length&&a(":input[placeholder]").each(function(){var b=a(this),c=b.attr("placeholder");(!b.val()||b.val()===c)&&b.val(c).addClass("placeholder_text")})}}}}(jQuery,this,this.document);jQuery(document).ready(function(){FORMALIZE.go()})
|
||||
BIN
public/languages/isq_translation-de_DE.mo
Normal file
173
public/languages/isq_translation-de_DE.po
Normal file
@@ -0,0 +1,173 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: POEditor.com\n"
|
||||
"Project-Id-Version: infinitysqaure\n"
|
||||
"Language: de\n"
|
||||
|
||||
#: footer.php:3
|
||||
msgid "The bookmarklet"
|
||||
msgstr "Das Lesezeichen"
|
||||
|
||||
#: footer.php:5
|
||||
msgid "Save this as a bookmark."
|
||||
msgstr "Speichere dies als Lesezeichen."
|
||||
|
||||
#: footer.php:6
|
||||
msgid "Add this to your bookmarks or drag it to your bookmarks bar to quickly access shortening functions."
|
||||
msgstr "Füge dies zu deinen Lesezeichen hinzu oder ziehe es in deine Lesezeichenleiste, um schnell auf die Verkürzungsfunktionen zuzugreifen."
|
||||
|
||||
#: footer.php:7 index.php:59
|
||||
msgid "Shorten"
|
||||
msgstr "Verkürzen"
|
||||
|
||||
#: footer.php:8
|
||||
msgid "This bookmarklet takes the page URL and title and opens a new tab, where you can fill out a CAPTCHA. If you have selected text before using the bookmarklet, that will be used as the keyword."
|
||||
msgstr "Dieses Lesezeichen verwendet die Seiten-URL und den Titel und öffnet eine neue Registerkarte, auf der Sie ein CAPTCHA ausfüllen können. Wenn du vor der Verwendung des Lesezeichens Text ausgewählt hast, wird dieser als Schlüsselwort verwendet."
|
||||
|
||||
#: footer.php:9
|
||||
msgid "Support for bookmarklets on mobile varies. For example, they work on Chrome for Android but you have to add and sync them from your desktop."
|
||||
msgstr "Die Unterstützung für Lesezeichen auf Mobilgeräten ist unterschiedlich. Zum Beispiel funktionieren sie unter Chrome für Android, aber Sie müssen sie von Ihrem Desktop aus hinzufügen und synchronisieren."
|
||||
|
||||
#: footer.php:13
|
||||
msgid "Powered by <a href=\"http://yourls.org/\">YOURLS</a>. Designed by <a href=\"http://tomslominski.net/\">Tom Slominski</a>."
|
||||
msgstr "Unterstützt von <a href=\"http://yourls.org/\"> YOURLS </a>. Entworfen von <a href=\"http://tomslominski.net/\"> Tom Slominski </a>."
|
||||
|
||||
#: footer.php:15
|
||||
msgid "This site uses cookies for Google reCAPTCHA"
|
||||
msgstr "Diese Website verwendet Cookies für Google reCAPTCHA"
|
||||
|
||||
#: index.php:10
|
||||
msgid "Enter a new URL to shorten"
|
||||
msgstr "Gebe eine neue URL zum Kürzen ein"
|
||||
|
||||
#: index.php:13
|
||||
msgid "Long URL"
|
||||
msgstr "Lange URL"
|
||||
|
||||
#: index.php:14
|
||||
msgid "Paste the long URL here. This is required."
|
||||
msgstr "Füge hier die lange URL ein. Dies ist erforderlich."
|
||||
|
||||
#: index.php:20
|
||||
msgid "Custom keyword"
|
||||
msgstr "Benutzerdefiniertes Schlüsselwort"
|
||||
|
||||
#: index.php:21
|
||||
msgid "A keyword replaces the default short string."
|
||||
msgstr "Ein Schlüsselwort ersetzt die Standard-Kurzzeichenfolge."
|
||||
|
||||
#: index.php:26
|
||||
msgid "Custom title"
|
||||
msgstr "Benutzerdefinierter Titel"
|
||||
|
||||
#: index.php:27
|
||||
msgid "Optional title used when sharing a link from YOURLS using social sharers."
|
||||
msgstr "Optionaler Titel, der verwendet wird, wenn ein Link von YOURLS mithilfe von Social Sharern freigegeben wird."
|
||||
|
||||
#: index.php:44
|
||||
msgid "Verification"
|
||||
msgstr "Überprüfung"
|
||||
|
||||
#: index.php:45
|
||||
msgid "reCAPTCHA verification used to ensure you are not a bot."
|
||||
msgstr "Die reCAPTCHA-Überprüfung wird verwendet, um sicherzustellen, dass du kein Bot bist."
|
||||
|
||||
#: public/config-sample.php:26
|
||||
msgid "Get ∞²!"
|
||||
msgstr "Hole dir ∞²!"
|
||||
|
||||
#: public/config-sample.php:30
|
||||
msgid "Admin area"
|
||||
msgstr "Admin-Bereich"
|
||||
|
||||
#: result.php:12
|
||||
msgid "← Go home and try again"
|
||||
msgstr "& larr; Geh nach Hause und versuche es erneut"
|
||||
|
||||
#: result.php:22
|
||||
msgid "You haven't entered a URL to shorten."
|
||||
msgstr "Du hast keine zu verkürzende URL eingegeben."
|
||||
|
||||
#: result.php:27
|
||||
msgid "The keyword %1$s is reserved."
|
||||
msgstr "Das Schlüsselwort% 1 $ s ist reserviert."
|
||||
|
||||
#: result.php:32
|
||||
msgid "The keyword %1$s is taken."
|
||||
msgstr "Das Schlüsselwort% 1 $ s wird verwendet."
|
||||
|
||||
#: result.php:50
|
||||
msgid "Are you a bot? Google certainly thinks you are."
|
||||
msgstr "Bist du ein Bot? Google glaubt sicherlich, dass du einer bist."
|
||||
|
||||
#: result.php:58
|
||||
msgid "Are you a bot? The verification was not completed successfully."
|
||||
msgstr "Bist du ein Bot? Die Überprüfung wurde nicht erfolgreich abgeschlossen."
|
||||
|
||||
#: result.php:64
|
||||
msgid "Are you a bot? No antispam protection was completed successfully."
|
||||
msgstr "Bist du ein Bot? Es wurde kein Antispam-Schutz erfolgreich abgeschlossen."
|
||||
|
||||
#: result.php:84
|
||||
msgid "The URL could not be shortened."
|
||||
msgstr "Die URL konnte nicht gekürzt werden."
|
||||
|
||||
#: result.php:101
|
||||
msgid "Your short URL"
|
||||
msgstr "Deine kurze URL"
|
||||
|
||||
#: result.php:105
|
||||
msgid "Original URL"
|
||||
msgstr "Ursprüngliche URL"
|
||||
|
||||
#: result.php:108 result.php:124 result.php:139
|
||||
msgid "Copy to clipboard"
|
||||
msgstr "In die Zwischenablage kopieren"
|
||||
|
||||
#: result.php:109 result.php:125 result.php:140
|
||||
msgid "Copied to clipboard"
|
||||
msgstr "In die Zwischenablage kopiert"
|
||||
|
||||
#: result.php:111 result.php:127 result.php:142
|
||||
msgid "Press ⌘+C to copy"
|
||||
msgstr "Drücke zum Kopieren ⌘ + C."
|
||||
|
||||
#: result.php:112 result.php:128 result.php:143
|
||||
msgid "Press Ctrl+C to copy"
|
||||
msgstr "Drücke zum Kopieren Strg + C."
|
||||
|
||||
#: result.php:113 result.php:129 result.php:144
|
||||
msgid "Tap copy"
|
||||
msgstr "Tippe auf Kopieren"
|
||||
|
||||
#: result.php:114 result.php:130 result.php:145
|
||||
msgid "Failed to copy"
|
||||
msgstr "Kopieren fehlgeschlagen"
|
||||
|
||||
#: result.php:121
|
||||
msgid "Short URL"
|
||||
msgstr "Kurze URL"
|
||||
|
||||
#: result.php:136
|
||||
msgid "Stats"
|
||||
msgstr "Statistiken"
|
||||
|
||||
#: result.php:153
|
||||
msgid "Share"
|
||||
msgstr "Teilen"
|
||||
|
||||
#: result.php:154
|
||||
msgid "Share your short URL"
|
||||
msgstr "Teile deine kurze URL"
|
||||
|
||||
#: result.php:175
|
||||
msgid "QR code"
|
||||
msgstr "QR-Code"
|
||||
|
||||
#: result.php:176
|
||||
msgid "Share your link with external devices"
|
||||
msgstr "Teile deinen Link mit externen Geräten"
|
||||
|
||||
BIN
public/languages/isq_translation-es_ES.mo
Normal file
216
public/languages/isq_translation-es_ES.po
Normal file
@@ -0,0 +1,216 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Infinity Squared\n"
|
||||
"POT-Creation-Date: 2016-11-04 12:57+0100\n"
|
||||
"PO-Revision-Date: 2016-11-04 12:58+0100\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: es_ES\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.8.11\n"
|
||||
"X-Poedit-KeywordsList: yourls__;yourls_e;yourls_s;yourls_se;"
|
||||
"yourls_esc_attr__;yourls_esc_html__;yourls_x;yourls_ex;yourls_esc_attr_x;"
|
||||
"yourls_esc_html_x;yourls_n:1,2;yourls_nx:1,2;yourls_n_noop:1,2;"
|
||||
"yourls_nx_noop:1,2\n"
|
||||
"X-Poedit-Basepath: ../..\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-SearchPath-0: public/languages\n"
|
||||
"X-Poedit-SearchPath-1: .\n"
|
||||
|
||||
#: footer.php:3
|
||||
msgid "The bookmarklet"
|
||||
msgstr "El marcador"
|
||||
|
||||
#: footer.php:5
|
||||
msgid "Save this as a bookmark."
|
||||
msgstr "Guardar como marcador"
|
||||
|
||||
#: footer.php:6
|
||||
msgid ""
|
||||
"Add this to your bookmarks or drag it to your bookmarks bar to quickly "
|
||||
"access shortening functions."
|
||||
msgstr ""
|
||||
"Añada esto a sus marcadores, o arrástrelo a su barra de marcadores para "
|
||||
"acceder rápidamente a las funciones de acortado de urls"
|
||||
|
||||
#: footer.php:7 index.php:59
|
||||
msgid "Shorten"
|
||||
msgstr "Acortar"
|
||||
|
||||
#: footer.php:8
|
||||
msgid ""
|
||||
"This bookmarklet takes the page URL and title and opens a new tab, where you "
|
||||
"can fill out a CAPTCHA. If you have selected text before using the "
|
||||
"bookmarklet, that will be used as the keyword."
|
||||
msgstr ""
|
||||
"Este marcador toma la URL de la página y el título y abre una nueva pestaña, "
|
||||
"donde puede llenar una CAPTCHA. Si ha seleccionado texto antes de utilizar "
|
||||
"el marcador, se utilizará como palabra clave."
|
||||
|
||||
#: footer.php:9
|
||||
msgid ""
|
||||
"Support for bookmarklets on mobile varies. For example, they work on Chrome "
|
||||
"for Android but you have to add and sync them from your desktop."
|
||||
msgstr ""
|
||||
"Soporte para marcadores en el móvil. Por ejemplo, trabajan en Chrome para "
|
||||
"Android, pero tienes que añadirlos y sincronizarlos desde tu escritorio."
|
||||
|
||||
#: footer.php:13
|
||||
msgid ""
|
||||
"Powered by <a href=\"http://yourls.org/\">YOURLS</a>. Designed by <a href="
|
||||
"\"http://tomslominski.net/\">Tom Slominski</a>."
|
||||
msgstr ""
|
||||
"Desarrollado por <a href=\"http://yourls.org/\"> YOURLS </a>. Diseñado por "
|
||||
"<a href=\"http://tomslominski.net/\"> Tom Slominski </a>."
|
||||
|
||||
#: footer.php:15
|
||||
msgid "This site uses cookies for Google reCAPTCHA"
|
||||
msgstr "Este sitio usa cookies para Google reCAPTCHA"
|
||||
|
||||
#: index.php:10
|
||||
msgid "Enter a new URL to shorten"
|
||||
msgstr "Introduzca una url para acortarla"
|
||||
|
||||
#: index.php:13
|
||||
msgid "Long URL"
|
||||
msgstr "URL Larga"
|
||||
|
||||
#: index.php:14
|
||||
msgid "Paste the long URL here. This is required."
|
||||
msgstr "Pegue la URL larga aquí (Este campo es obligatorio)"
|
||||
|
||||
#: index.php:20
|
||||
msgid "Custom keyword"
|
||||
msgstr "Personalizar palabra clave"
|
||||
|
||||
#: index.php:21
|
||||
msgid "A keyword replaces the default short string."
|
||||
msgstr "Una palabra clave, reemplaza la cadena de caracteres por defecto"
|
||||
|
||||
#: index.php:26
|
||||
msgid "Custom title"
|
||||
msgstr "Título personalizadon"
|
||||
|
||||
#: index.php:27
|
||||
msgid ""
|
||||
"Optional title used when sharing a link from YOURLS using social sharers."
|
||||
msgstr ""
|
||||
"Título opcional usado cuando compartes en una red social un enlace usando "
|
||||
"los botones de abajo"
|
||||
|
||||
#: index.php:44
|
||||
msgid "Verification"
|
||||
msgstr "Verificación"
|
||||
|
||||
#: index.php:45
|
||||
msgid "reCAPTCHA verification used to ensure you are not a bot."
|
||||
msgstr "Verificación reCAPTCHA para asegurar que no eres un robot"
|
||||
|
||||
#: public/config-sample.php:26
|
||||
msgid "Get ∞²!"
|
||||
msgstr "¡Obtener ∞²!"
|
||||
|
||||
#: public/config-sample.php:30
|
||||
msgid "Admin area"
|
||||
msgstr "Área de administración"
|
||||
|
||||
#: result.php:12
|
||||
msgid "← Go home and try again"
|
||||
msgstr "← Ir a inicio e intentarlo de nuevo"
|
||||
|
||||
#: result.php:22
|
||||
msgid "You haven't entered a URL to shorten."
|
||||
msgstr ""
|
||||
"No has introducido una URL para acortar, por favor vuelva atrás e inténtelo "
|
||||
"de nuevo"
|
||||
|
||||
#: result.php:27
|
||||
#, php-format
|
||||
msgid "The keyword %1$s is reserved."
|
||||
msgstr "La palabra clave %1$s está reservada"
|
||||
|
||||
#: result.php:32
|
||||
#, php-format
|
||||
msgid "The keyword %1$s is taken."
|
||||
msgstr "La palabra clave %1$s ya está en uso"
|
||||
|
||||
#: result.php:50
|
||||
msgid "Are you a bot? Google certainly thinks you are."
|
||||
msgstr ""
|
||||
"¿Eres un robot?. Google piensa que si... Por favor, vuelva atrás e inténtelo "
|
||||
"de nuevo"
|
||||
|
||||
#: result.php:58
|
||||
msgid "Are you a bot? The verification was not completed successfully."
|
||||
msgstr ""
|
||||
"¿Eres un robot? La verificación no se ha completado correctamente. Por "
|
||||
"favor, vuelva atrás e inténtelo de nuevo"
|
||||
|
||||
#: result.php:64
|
||||
msgid "Are you a bot? No antispam protection was completed successfully."
|
||||
msgstr ""
|
||||
"¿Eres un robot?. La protección anti spam no se ha completado correctamente. "
|
||||
"Por favor, vuelva atrás e inténtelo de nuevo"
|
||||
|
||||
#: result.php:84
|
||||
msgid "The URL could not be shortened."
|
||||
msgstr "La URL no se ha podido acortar"
|
||||
|
||||
#: result.php:101
|
||||
msgid "Your short URL"
|
||||
msgstr "Su URL acortada"
|
||||
|
||||
#: result.php:105
|
||||
msgid "Original URL"
|
||||
msgstr "URL Original"
|
||||
|
||||
#: result.php:108 result.php:124 result.php:139
|
||||
msgid "Copy to clipboard"
|
||||
msgstr "Copiar al portapapeles"
|
||||
|
||||
#: result.php:109 result.php:125 result.php:140
|
||||
msgid "Copied to clipboard"
|
||||
msgstr "Copiado al portapapeles"
|
||||
|
||||
#: result.php:111 result.php:127 result.php:142
|
||||
msgid "Press ⌘+C to copy"
|
||||
msgstr "Pulse ⌘+C para copiar"
|
||||
|
||||
#: result.php:112 result.php:128 result.php:143
|
||||
msgid "Press Ctrl+C to copy"
|
||||
msgstr "Haga clic en un enlace y presione CTRL +C para copiarlo."
|
||||
|
||||
#: result.php:113 result.php:129 result.php:144
|
||||
msgid "Tap copy"
|
||||
msgstr "Tocar para copiar"
|
||||
|
||||
#: result.php:114 result.php:130 result.php:145
|
||||
msgid "Failed to copy"
|
||||
msgstr "Falló al copiar"
|
||||
|
||||
#: result.php:121
|
||||
msgid "Short URL"
|
||||
msgstr "Su URL acortada"
|
||||
|
||||
#: result.php:136
|
||||
msgid "Stats"
|
||||
msgstr "Estadísticas"
|
||||
|
||||
#: result.php:153
|
||||
msgid "Share"
|
||||
msgstr "Compartir"
|
||||
|
||||
#: result.php:154
|
||||
msgid "Share your short URL"
|
||||
msgstr "Compartir su URL corta"
|
||||
|
||||
#: result.php:175
|
||||
msgid "QR code"
|
||||
msgstr "Código QR"
|
||||
|
||||
#: result.php:176
|
||||
msgid "Share your link with external devices"
|
||||
msgstr "Comparta su enlace con dispositivos externos"
|
||||
BIN
public/languages/isq_translation-ru_RU.mo
Normal file
220
public/languages/isq_translation-ru_RU.po
Normal file
@@ -0,0 +1,220 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: 2016-11-27 12:21+0300\n"
|
||||
"PO-Revision-Date: 2016-11-27 20:56+0300\n"
|
||||
"Last-Translator: Pavel Mezhuev <pavel@onlyfriends.info>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: ru_RU\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.8.11\n"
|
||||
"X-Poedit-Basepath: ../../..\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"X-Poedit-KeywordsList: yourls_e;yourls__\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-SearchPath-0: trunk\n"
|
||||
"X-Poedit-SearchPathExcluded-0: trunk/js\n"
|
||||
"X-Poedit-SearchPathExcluded-1: trunk/admin\n"
|
||||
"X-Poedit-SearchPathExcluded-2: trunk/includes\n"
|
||||
"X-Poedit-SearchPathExcluded-3: trunk/yourls-*.php\n"
|
||||
|
||||
#: footer.php:3
|
||||
msgid "The bookmarklet"
|
||||
msgstr "Букмарклет"
|
||||
|
||||
#: footer.php:5
|
||||
msgid "Save this as a bookmark."
|
||||
msgstr "Сохраните это как закладку"
|
||||
|
||||
#: footer.php:6
|
||||
msgid ""
|
||||
"Add this to your bookmarks or drag it to your bookmarks bar to quickly "
|
||||
"access shortening functions."
|
||||
msgstr ""
|
||||
"Перетащите это на панель закладок для быстрого доступа к функции сокращения "
|
||||
"ссылок."
|
||||
|
||||
#: footer.php:7 index.php:59
|
||||
msgid "Shorten"
|
||||
msgstr "Сократить"
|
||||
|
||||
#: footer.php:8
|
||||
msgid ""
|
||||
"This bookmarklet takes the page URL and title and opens a new tab, where you "
|
||||
"can fill out a CAPTCHA. If you have selected text before using the "
|
||||
"bookmarklet, that will be used as the keyword."
|
||||
msgstr ""
|
||||
"Букмарклет позволяет быстро создать короткую ссылку, использую адрес и "
|
||||
"заголовок текущей страницы. Если перед использованием букмарклета выделить "
|
||||
"на странице текст, то он будет использован как ключевое слово."
|
||||
|
||||
#: footer.php:9
|
||||
msgid ""
|
||||
"Support for bookmarklets on mobile varies. For example, they work on Chrome "
|
||||
"for Android but you have to add and sync them from your desktop."
|
||||
msgstr ""
|
||||
"Поддержка букмарклетов на мобильных устройствах не гарантируются. Например, "
|
||||
"они работают в Chrome для Android, но сперва вы должны добавить их на "
|
||||
"стационарном компьютере и провести синхронизацию."
|
||||
|
||||
#: footer.php:13
|
||||
msgid ""
|
||||
"Powered by <a href=\"http://yourls.org/\">YOURLS</a>. Designed by <a href="
|
||||
"\"http://tomslominski.net/\">Tom Slominski</a>."
|
||||
msgstr ""
|
||||
"Работает на <a href=\"http://yourls.org/\">YOURLS</a>. Дизайн <a href="
|
||||
"\"http://tomslominski.net/\">Tom Slominski</a>."
|
||||
|
||||
#: footer.php:15
|
||||
msgid "This site uses cookies for Google reCAPTCHA"
|
||||
msgstr "Этот сайт использует куки-файлы для Google reCAPTCHA"
|
||||
|
||||
#: index.php:10
|
||||
msgid "Enter a new URL to shorten"
|
||||
msgstr "Пожалуйста, введите URL"
|
||||
|
||||
#: index.php:13
|
||||
msgid "Long URL"
|
||||
msgstr "Исходная ссылка"
|
||||
|
||||
#: index.php:14
|
||||
msgid "Paste the long URL here. This is required."
|
||||
msgstr "Укажите ссылку, которую требуется сократить. Обязательно к заполнению."
|
||||
|
||||
#: index.php:20
|
||||
msgid "Custom keyword"
|
||||
msgstr "Ключевое слово"
|
||||
|
||||
#: index.php:21
|
||||
msgid "A keyword replaces the default short string."
|
||||
msgstr "Заменяет короткий адрес по умолчанию."
|
||||
|
||||
#: index.php:26
|
||||
msgid "Custom title"
|
||||
msgstr "Наименование"
|
||||
|
||||
#: index.php:27
|
||||
msgid ""
|
||||
"Optional title used when sharing a link from YOURLS using social sharers."
|
||||
msgstr "При размещении ссылки в социальных сетях."
|
||||
|
||||
#: index.php:44
|
||||
msgid "Verification"
|
||||
msgstr "Проверка"
|
||||
|
||||
#: index.php:45
|
||||
msgid "reCAPTCHA verification used to ensure you are not a bot."
|
||||
msgstr "reCAPTCHA используется для защиты от спама."
|
||||
|
||||
#: public/config-sample.php:26
|
||||
msgid "Get ∞²!"
|
||||
msgstr "Получить ∞²!"
|
||||
|
||||
#: public/config-sample.php:30
|
||||
msgid "Admin area"
|
||||
msgstr "Администратор"
|
||||
|
||||
#: result.php:12
|
||||
msgid "← Go home and try again"
|
||||
msgstr "← Вернуться и попробовать снова"
|
||||
|
||||
#: result.php:22
|
||||
msgid "You haven't entered a URL to shorten."
|
||||
msgstr "Вы не указали ссылку, которую требуется сократить."
|
||||
|
||||
#: result.php:27
|
||||
#, php-format
|
||||
msgid "The keyword %1$s is reserved."
|
||||
msgstr "Ключевое слово %1$s зарезервировано."
|
||||
|
||||
#: result.php:32
|
||||
#, php-format
|
||||
msgid "The keyword %1$s is taken."
|
||||
msgstr "Ключевое слово %1$s уже используется."
|
||||
|
||||
#: result.php:50
|
||||
msgid "Are you a bot? Google certainly thinks you are."
|
||||
msgstr "Вы бот? Пожалуйста вернитесь и попробуйте снова."
|
||||
|
||||
#: result.php:58
|
||||
msgid "Are you a bot? The verification was not completed successfully."
|
||||
msgstr "Вы бот? Проверка не была успешно завершена."
|
||||
|
||||
#: result.php:64
|
||||
msgid "Are you a bot? No antispam protection was completed successfully."
|
||||
msgstr "Вы бот? Проверка не была успешно завершена."
|
||||
|
||||
#: result.php:84
|
||||
msgid "The URL could not be shortened."
|
||||
msgstr ""
|
||||
|
||||
#: result.php:101
|
||||
msgid "Your short URL"
|
||||
msgstr "Ваша короткая ссылка"
|
||||
|
||||
#: result.php:105
|
||||
msgid "Original URL"
|
||||
msgstr "Исходная ссылка"
|
||||
|
||||
#: result.php:108 result.php:124 result.php:139
|
||||
msgid "Copy to clipboard"
|
||||
msgstr "Скопировать в буфер обмена"
|
||||
|
||||
#: result.php:109 result.php:125 result.php:140
|
||||
msgid "Copied to clipboard"
|
||||
msgstr "Cкопировано в буфер обмена"
|
||||
|
||||
#: result.php:111 result.php:127 result.php:142
|
||||
msgid "Press ⌘+C to copy"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:112 result.php:128 result.php:143
|
||||
msgid "Press Ctrl+C to copy"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:113 result.php:129 result.php:144
|
||||
msgid "Tap copy"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:114 result.php:130 result.php:145
|
||||
msgid "Failed to copy"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:121
|
||||
msgid "Short URL"
|
||||
msgstr "Короткая ссылка"
|
||||
|
||||
#: result.php:136
|
||||
msgid "Stats"
|
||||
msgstr "Статистика"
|
||||
|
||||
#: result.php:153
|
||||
msgid "Share"
|
||||
msgstr "Поделиться"
|
||||
|
||||
#: result.php:154
|
||||
msgid "Share your short URL"
|
||||
msgstr "Поделиться короткой ссылкой в социальных сетях"
|
||||
|
||||
#: result.php:175
|
||||
msgid "QR code"
|
||||
msgstr "QR-код"
|
||||
|
||||
#: result.php:176
|
||||
msgid "Share your link with external devices"
|
||||
msgstr "Поделиться короткой ссылкой с другим устройством"
|
||||
|
||||
#~ msgid "Copied!"
|
||||
#~ msgstr "Скопировано!"
|
||||
|
||||
#~ msgid "← Go back and try again"
|
||||
#~ msgstr "← Вернуться и попробовать снова"
|
||||
|
||||
#~ msgid "The keyword %1$s is restricted."
|
||||
#~ msgstr "Ключевое слово %1$s запрещено."
|
||||
|
||||
#~ msgid "Click on a link and press Ctrl+C to quickly copy it."
|
||||
#~ msgstr "Для копирования щёлкните по ссылке и нажмите Ctrl+C."
|
||||
197
public/languages/isq_translation-source.pot
Executable file
@@ -0,0 +1,197 @@
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Infinity Squared\n"
|
||||
"POT-Creation-Date: 2016-11-04 12:50+0100\n"
|
||||
"PO-Revision-Date: 2015-03-22 19:25-0000\n"
|
||||
"Last-Translator: Tom Slominski <me@tomslominski>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.8.11\n"
|
||||
"X-Poedit-KeywordsList: yourls__;yourls_e;yourls_s;yourls_se;"
|
||||
"yourls_esc_attr__;yourls_esc_html__;yourls_x;yourls_ex;yourls_esc_attr_x;"
|
||||
"yourls_esc_html_x;yourls_n:1,2;yourls_nx:1,2;yourls_n_noop:1,2;"
|
||||
"yourls_nx_noop:1,2\n"
|
||||
"X-Poedit-Basepath: ../..\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-SearchPath-0: public/languages\n"
|
||||
"X-Poedit-SearchPath-1: .\n"
|
||||
|
||||
#: footer.php:3
|
||||
msgid "The bookmarklet"
|
||||
msgstr ""
|
||||
|
||||
#: footer.php:5
|
||||
msgid "Save this as a bookmark."
|
||||
msgstr ""
|
||||
|
||||
#: footer.php:6
|
||||
msgid ""
|
||||
"Add this to your bookmarks or drag it to your bookmarks bar to quickly "
|
||||
"access shortening functions."
|
||||
msgstr ""
|
||||
|
||||
#: footer.php:7 index.php:59
|
||||
msgid "Shorten"
|
||||
msgstr ""
|
||||
|
||||
#: footer.php:8
|
||||
msgid ""
|
||||
"This bookmarklet takes the page URL and title and opens a new tab, where you "
|
||||
"can fill out a CAPTCHA. If you have selected text before using the "
|
||||
"bookmarklet, that will be used as the keyword."
|
||||
msgstr ""
|
||||
|
||||
#: footer.php:9
|
||||
msgid ""
|
||||
"Support for bookmarklets on mobile varies. For example, they work on Chrome "
|
||||
"for Android but you have to add and sync them from your desktop."
|
||||
msgstr ""
|
||||
|
||||
#: footer.php:13
|
||||
msgid ""
|
||||
"Powered by <a href=\"http://yourls.org/\">YOURLS</a>. Designed by <a href="
|
||||
"\"http://tomslominski.net/\">Tom Slominski</a>."
|
||||
msgstr ""
|
||||
|
||||
#: footer.php:15
|
||||
msgid "This site uses cookies for Google reCAPTCHA"
|
||||
msgstr ""
|
||||
|
||||
#: index.php:10
|
||||
msgid "Enter a new URL to shorten"
|
||||
msgstr ""
|
||||
|
||||
#: index.php:13
|
||||
msgid "Long URL"
|
||||
msgstr ""
|
||||
|
||||
#: index.php:14
|
||||
msgid "Paste the long URL here. This is required."
|
||||
msgstr ""
|
||||
|
||||
#: index.php:20
|
||||
msgid "Custom keyword"
|
||||
msgstr ""
|
||||
|
||||
#: index.php:21
|
||||
msgid "A keyword replaces the default short string."
|
||||
msgstr ""
|
||||
|
||||
#: index.php:26
|
||||
msgid "Custom title"
|
||||
msgstr ""
|
||||
|
||||
#: index.php:27
|
||||
msgid ""
|
||||
"Optional title used when sharing a link from YOURLS using social sharers."
|
||||
msgstr ""
|
||||
|
||||
#: index.php:44
|
||||
msgid "Verification"
|
||||
msgstr ""
|
||||
|
||||
#: index.php:45
|
||||
msgid "reCAPTCHA verification used to ensure you are not a bot."
|
||||
msgstr ""
|
||||
|
||||
#: public/config-sample.php:26
|
||||
msgid "Get ∞²!"
|
||||
msgstr ""
|
||||
|
||||
#: public/config-sample.php:30
|
||||
msgid "Admin area"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:12
|
||||
msgid "← Go home and try again"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:22
|
||||
msgid "You haven't entered a URL to shorten."
|
||||
msgstr ""
|
||||
|
||||
#: result.php:27
|
||||
#, php-format
|
||||
msgid "The keyword %1$s is reserved."
|
||||
msgstr ""
|
||||
|
||||
#: result.php:32
|
||||
#, php-format
|
||||
msgid "The keyword %1$s is taken."
|
||||
msgstr ""
|
||||
|
||||
#: result.php:50
|
||||
msgid "Are you a bot? Google certainly thinks you are."
|
||||
msgstr ""
|
||||
|
||||
#: result.php:58
|
||||
msgid "Are you a bot? The verification was not completed successfully."
|
||||
msgstr ""
|
||||
|
||||
#: result.php:64
|
||||
msgid "Are you a bot? No antispam protection was completed successfully."
|
||||
msgstr ""
|
||||
|
||||
#: result.php:84
|
||||
msgid "The URL could not be shortened."
|
||||
msgstr ""
|
||||
|
||||
#: result.php:101
|
||||
msgid "Your short URL"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:105
|
||||
msgid "Original URL"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:108 result.php:124 result.php:139
|
||||
msgid "Copy to clipboard"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:109 result.php:125 result.php:140
|
||||
msgid "Copied to clipboard"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:111 result.php:127 result.php:142
|
||||
msgid "Press ⌘+C to copy"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:112 result.php:128 result.php:143
|
||||
msgid "Press Ctrl+C to copy"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:113 result.php:129 result.php:144
|
||||
msgid "Tap copy"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:114 result.php:130 result.php:145
|
||||
msgid "Failed to copy"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:121
|
||||
msgid "Short URL"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:136
|
||||
msgid "Stats"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:153
|
||||
msgid "Share"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:154
|
||||
msgid "Share your short URL"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:175
|
||||
msgid "QR code"
|
||||
msgstr ""
|
||||
|
||||
#: result.php:176
|
||||
msgid "Share your link with external devices"
|
||||
msgstr ""
|
||||
BIN
public/languages/isq_translation-zh_CN.mo
Normal file
204
public/languages/isq_translation-zh_CN.po
Normal file
@@ -0,0 +1,204 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Infinity Squared\n"
|
||||
"POT-Creation-Date: 2019-05-26 04:25+0800\n"
|
||||
"PO-Revision-Date: 2019-05-26 04:55+0800\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.2.3\n"
|
||||
"X-Poedit-KeywordsList: yourls__;yourls_e;yourls_s;yourls_se;"
|
||||
"yourls_esc_attr__;yourls_esc_html__;yourls_x;yourls_ex;yourls_esc_attr_x;"
|
||||
"yourls_esc_html_x;yourls_n:1,2;yourls_nx:1,2;yourls_n_noop:1,2;"
|
||||
"yourls_nx_noop:1,2\n"
|
||||
"X-Poedit-Basepath: ../..\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"Last-Translator: wordlesswind <i@qingly.me>\n"
|
||||
"Language: zh_CN\n"
|
||||
"X-Poedit-SearchPath-0: public/languages\n"
|
||||
"X-Poedit-SearchPath-1: .\n"
|
||||
|
||||
#: footer.php:3
|
||||
msgid "The bookmarklet"
|
||||
msgstr "书签"
|
||||
|
||||
#: footer.php:5
|
||||
msgid "Save this as a bookmark."
|
||||
msgstr "将其另存为书签。"
|
||||
|
||||
#: footer.php:6
|
||||
msgid ""
|
||||
"Add this to your bookmarks or drag it to your bookmarks bar to quickly "
|
||||
"access shortening functions."
|
||||
msgstr "将其添加到书签或将其拖拽到书签栏中,以便快速访问缩短功能。"
|
||||
|
||||
#: footer.php:7 index.php:59
|
||||
msgid "Shorten"
|
||||
msgstr "缩短"
|
||||
|
||||
#: footer.php:8
|
||||
msgid ""
|
||||
"This bookmarklet takes the page URL and title and opens a new tab, where you "
|
||||
"can fill out a CAPTCHA. If you have selected text before using the "
|
||||
"bookmarklet, that will be used as the keyword."
|
||||
msgstr ""
|
||||
"此书签会获取页面的URL和标题,并打开一个新标签页,您可以在其中填写验证码。如果"
|
||||
"您在使用书签之前选择了文本,那么它将成为关键字。"
|
||||
|
||||
#: footer.php:9
|
||||
msgid ""
|
||||
"Support for bookmarklets on mobile varies. For example, they work on Chrome "
|
||||
"for Android but you have to add and sync them from your desktop."
|
||||
msgstr ""
|
||||
"对移动设备上的书签的支持各不相同。例如,它们适用于 Android 的 Chrome,但您必"
|
||||
"须从桌面添加并同步它们。"
|
||||
|
||||
#: footer.php:13
|
||||
msgid ""
|
||||
"Powered by <a href=\"http://yourls.org/\">YOURLS</a>. Designed by <a href="
|
||||
"\"http://tomslominski.net/\">Tom Slominski</a>."
|
||||
msgstr ""
|
||||
"由 <a href=\"http://yourls.org/\">YOURLS</a> 驱动。由 <a href=\"http://"
|
||||
"tomslominski.net/\">Tom Slominski </a>设计。"
|
||||
|
||||
#: footer.php:15
|
||||
msgid "This site uses cookies for Google reCAPTCHA"
|
||||
msgstr "本网站需要 cookies 来使用 Google reCAPTCHA"
|
||||
|
||||
#: index.php:10
|
||||
msgid "Enter a new URL to shorten"
|
||||
msgstr "输入要缩短的新网址"
|
||||
|
||||
#: index.php:13
|
||||
msgid "Long URL"
|
||||
msgstr "长网址"
|
||||
|
||||
#: index.php:14
|
||||
msgid "Paste the long URL here. This is required."
|
||||
msgstr "必须在此粘贴长网址。"
|
||||
|
||||
#: index.php:20
|
||||
msgid "Custom keyword"
|
||||
msgstr "自定义关键字"
|
||||
|
||||
#: index.php:21
|
||||
msgid "A keyword replaces the default short string."
|
||||
msgstr "关键字将替换默认的短字符串。"
|
||||
|
||||
#: index.php:26
|
||||
msgid "Custom title"
|
||||
msgstr "自定义标题"
|
||||
|
||||
#: index.php:27
|
||||
msgid ""
|
||||
"Optional title used when sharing a link from YOURLS using social sharers."
|
||||
msgstr "可选标题,在 YOURLS 使用 social sharers 分享链接时采用"
|
||||
|
||||
#: index.php:44
|
||||
msgid "Verification"
|
||||
msgstr "验证"
|
||||
|
||||
#: index.php:45
|
||||
msgid "reCAPTCHA verification used to ensure you are not a bot."
|
||||
msgstr "reCAPTCHA 验证用于确保您不是机器人。"
|
||||
|
||||
#: public/config-sample.php:26
|
||||
msgid "Get ∞²!"
|
||||
msgstr "获取 ∞²!"
|
||||
|
||||
#: public/config-sample.php:30
|
||||
msgid "Admin area"
|
||||
msgstr "管理界面"
|
||||
|
||||
#: result.php:12
|
||||
msgid "← Go home and try again"
|
||||
msgstr "返回首页并再试一次"
|
||||
|
||||
#: result.php:22
|
||||
msgid "You haven't entered a URL to shorten."
|
||||
msgstr "您尚未输入要缩短的网址。"
|
||||
|
||||
#: result.php:27
|
||||
#, php-format
|
||||
msgid "The keyword %1$s is reserved."
|
||||
msgstr "关键字 %1$s 已被保留。"
|
||||
|
||||
#: result.php:32
|
||||
#, php-format
|
||||
msgid "The keyword %1$s is taken."
|
||||
msgstr "关键字 %1$s 已被使用。"
|
||||
|
||||
#: result.php:50
|
||||
msgid "Are you a bot? Google certainly thinks you are."
|
||||
msgstr "您是机器人吗?Google 毫无疑问地认为您是。"
|
||||
|
||||
#: result.php:58
|
||||
msgid "Are you a bot? The verification was not completed successfully."
|
||||
msgstr "您是机器人吗? 验证没有顺利完成。"
|
||||
|
||||
#: result.php:64
|
||||
#, fuzzy
|
||||
msgid "Are you a bot? No antispam protection was completed successfully."
|
||||
msgstr "您是机器人吗?防垃圾邮件保护已成功完成。"
|
||||
|
||||
#: result.php:84
|
||||
msgid "The URL could not be shortened."
|
||||
msgstr "该网址无法被缩短。"
|
||||
|
||||
#: result.php:101
|
||||
msgid "Your short URL"
|
||||
msgstr "您的短网址"
|
||||
|
||||
#: result.php:105
|
||||
msgid "Original URL"
|
||||
msgstr "原始网址"
|
||||
|
||||
#: result.php:108 result.php:124 result.php:139
|
||||
msgid "Copy to clipboard"
|
||||
msgstr "复制到剪贴板"
|
||||
|
||||
#: result.php:109 result.php:125 result.php:140
|
||||
msgid "Copied to clipboard"
|
||||
msgstr "已复制到剪贴板"
|
||||
|
||||
#: result.php:111 result.php:127 result.php:142
|
||||
msgid "Press ⌘+C to copy"
|
||||
msgstr "按 ⌘+ C 进行复制"
|
||||
|
||||
#: result.php:112 result.php:128 result.php:143
|
||||
msgid "Press Ctrl+C to copy"
|
||||
msgstr "按 Ctrl + C 进行复制"
|
||||
|
||||
#: result.php:113 result.php:129 result.php:144
|
||||
msgid "Tap copy"
|
||||
msgstr "点击复制"
|
||||
|
||||
#: result.php:114 result.php:130 result.php:145
|
||||
msgid "Failed to copy"
|
||||
msgstr "无法复制"
|
||||
|
||||
#: result.php:121
|
||||
msgid "Short URL"
|
||||
msgstr "短网址"
|
||||
|
||||
#: result.php:136
|
||||
msgid "Stats"
|
||||
msgstr "统计"
|
||||
|
||||
#: result.php:153
|
||||
msgid "Share"
|
||||
msgstr "分享"
|
||||
|
||||
#: result.php:154
|
||||
msgid "Share your short URL"
|
||||
msgstr "分享您的短网址"
|
||||
|
||||
#: result.php:175
|
||||
msgid "QR code"
|
||||
msgstr "二维码"
|
||||
|
||||
#: result.php:176
|
||||
msgid "Share your link with external devices"
|
||||
msgstr "与外部设备分享您的链接"
|
||||
586
public/phpqrcode/qrarea.php
Executable file
@@ -0,0 +1,586 @@
|
||||
<?php
|
||||
/*
|
||||
* PHP QR Code encoder
|
||||
*
|
||||
* Area finding for SVG and CANVAS output
|
||||
*
|
||||
* Based on libqrencode C library distributed under LGPL 2.1
|
||||
* Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* PHP QR Code is distributed under LGPL 3
|
||||
* Copyright (C) 2010-2013 Dominik Dzienia <deltalab at poczta dot fm>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
// N
|
||||
// W E
|
||||
// S
|
||||
|
||||
define('QR_AREA_N', 0);
|
||||
define('QR_AREA_E', 1);
|
||||
define('QR_AREA_S', 2);
|
||||
define('QR_AREA_W', 3);
|
||||
|
||||
define('QR_AREA_X', 0);
|
||||
define('QR_AREA_Y', 1);
|
||||
|
||||
define('QR_AREA_TRACKER', 0);
|
||||
define('QR_AREA_PATH', 1);
|
||||
define('QR_AREA_POINT', 2);
|
||||
define('QR_AREA_RECT', 3);
|
||||
define('QR_AREA_LSHAPE', 4);
|
||||
|
||||
/** @addtogroup OutputGroup */
|
||||
/** @{ */
|
||||
|
||||
class QRareaGroup {
|
||||
public $total = 0;
|
||||
public $vertical = false;
|
||||
public $horizontal = false;
|
||||
public $points = array();
|
||||
public $id = 0;
|
||||
public $paths = array();
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function __construct($selfId, $sx, $sy)
|
||||
{
|
||||
$this->total = 1;
|
||||
$this->points = array(array($sx,$sy,false));
|
||||
$this->id = $selfId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//##########################################################################
|
||||
|
||||
class QRarea {
|
||||
|
||||
public $width = 0;
|
||||
private $tab = array();
|
||||
private $tab_edges = array();
|
||||
private $groups = array();
|
||||
private $curr_group = 0;
|
||||
public $paths = array();
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function __construct($source_tab)
|
||||
{
|
||||
$py = 0;
|
||||
$this->width = count($source_tab);
|
||||
$this->tab = array();
|
||||
$this->tab_edges = array();
|
||||
$this->paths = array();
|
||||
|
||||
foreach ($source_tab as $line) {
|
||||
$arr = array();
|
||||
$arr_edge = array();
|
||||
$px=0;
|
||||
|
||||
foreach (str_split($line) as $item) {
|
||||
|
||||
if ($py<7 && $px<7)
|
||||
$item = 0;
|
||||
|
||||
if ($py<7 && $px>=($this->width-7))
|
||||
$item = 0;
|
||||
|
||||
if ($py>=($this->width-7) && $px<7)
|
||||
$item = 0;
|
||||
|
||||
$arr[] = (int)$item;
|
||||
$arr_edge[] = array(false, false, false, false);
|
||||
|
||||
$px++;
|
||||
}
|
||||
|
||||
$this->tab[] = $arr;
|
||||
$this->tab_edges[] = $arr_edge;
|
||||
$py++;
|
||||
}
|
||||
|
||||
$this->paths[] = array(QR_AREA_TRACKER, 0,0);
|
||||
$this->paths[] = array(QR_AREA_TRACKER, 0,($this->width-7));
|
||||
$this->paths[] = array(QR_AREA_TRACKER, ($this->width-7),0);
|
||||
|
||||
$this->groups = array();
|
||||
$this->curr_group = 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function getGroups()
|
||||
{
|
||||
return $this->groups;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function getPaths()
|
||||
{
|
||||
return $this->paths;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function getWidth()
|
||||
{
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function dumpTab()
|
||||
{
|
||||
echo "<style>";
|
||||
echo "td { height: 2.5em; color: black; font-size: 8px;
|
||||
border-top: 1px solid silver; border-left: 1px solid silver }";
|
||||
echo "table { border-bottom: 1px solid silver; border-right: 1px solid silver }";
|
||||
echo "</style>";
|
||||
echo "<table border=0 cellpadding=0 cellspacing=0>";
|
||||
|
||||
$colorTab = array();
|
||||
|
||||
foreach($this->tab as $line) {
|
||||
foreach($line as $item) {
|
||||
if (!isset($colorTab[$item])) {
|
||||
$colorTab[$item] = 'hsl('.mt_rand(0, 360).', '.floor((mt_rand(0, 25))+75).'%, 50%)';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach($this->tab as $line) {
|
||||
echo "<tr>";
|
||||
foreach($line as $item) {
|
||||
if ($item == 0) {
|
||||
echo "<td> </td>";
|
||||
} else {
|
||||
echo "<td style='text-align:center;width: 4em;background:".$colorTab[$item]."'>".$item."</td>";
|
||||
}
|
||||
}
|
||||
echo "</tr>";
|
||||
}
|
||||
echo "</table>";
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function dumpEdges()
|
||||
{
|
||||
$style_off = '1px dotted silver;';
|
||||
$style_on = '3px solid red;';
|
||||
|
||||
$colorAlloc = array();
|
||||
|
||||
echo "<table border='0'>";
|
||||
$py = 0;
|
||||
foreach($this->tab_edges as $line) {
|
||||
$px = 0;
|
||||
echo "<tr>";
|
||||
foreach($line as $item) {
|
||||
|
||||
$styles = 'border-top:';
|
||||
if ($item[QR_AREA_N])
|
||||
$styles .= $style_on;
|
||||
else $styles .= $style_off;
|
||||
|
||||
$styles .= 'border-bottom:';
|
||||
if ($item[QR_AREA_S])
|
||||
$styles .= $style_on;
|
||||
else $styles .= $style_off;
|
||||
|
||||
$styles .= 'border-right:';
|
||||
if ($item[QR_AREA_E])
|
||||
$styles .= $style_on;
|
||||
else $styles .= $style_off;
|
||||
|
||||
$styles .= 'border-left:';
|
||||
if ($item[QR_AREA_W])
|
||||
$styles .= $style_on;
|
||||
else $styles .= $style_off;
|
||||
|
||||
$color = '';
|
||||
$grp = $this->tab[$py][$px];
|
||||
|
||||
if ($grp>0) {
|
||||
if (!isset($colorAlloc[$grp])) {
|
||||
$colorAlloc[$grp] = 'hsl('.mt_rand(0, 360).', '.floor((mt_rand(0, 25))+75).'%, 50%)';
|
||||
}
|
||||
|
||||
$color = 'background:'.$colorAlloc[$grp];
|
||||
}
|
||||
|
||||
if ($grp == 0)
|
||||
$grp = ' ';
|
||||
|
||||
echo "<td style='text-align:center;width:1.5em;".$styles.$color."'>".$grp."</td>";
|
||||
$px++;
|
||||
}
|
||||
echo "</tr>";
|
||||
$py++;
|
||||
}
|
||||
echo "</table>";
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
private static function rle(&$stringData)
|
||||
{
|
||||
$outArray = array();
|
||||
$symbolArray = str_split($stringData);
|
||||
$last = '';
|
||||
$run = 1;
|
||||
|
||||
while (count($symbolArray) > 0) {
|
||||
$symbol = array_shift($symbolArray);
|
||||
|
||||
if ($symbol != $last) {
|
||||
if ($run > 1)
|
||||
$outArray[] = $run;
|
||||
|
||||
if ($last != '')
|
||||
$outArray[] = $last;
|
||||
|
||||
$run = 1;
|
||||
$last = $symbol;
|
||||
} else {
|
||||
$run++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($run > 1)
|
||||
$outArray[] = $run;
|
||||
|
||||
$outArray[] = $last;
|
||||
|
||||
$stringData = $outArray;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
private function getAt($posx, $posy)
|
||||
{
|
||||
if (($posx<0)||($posy<0)||($posx>=$this->width)||($posy>=$this->width))
|
||||
return 0;
|
||||
|
||||
return $this->tab[$posy][$posx];
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
private function getOnElem($elem, $deltax = 0, $deltay = 0)
|
||||
{
|
||||
$posx = $elem[0]+$deltax;
|
||||
$posy = $elem[1]+$deltay;
|
||||
|
||||
if (($posx<0)||($posy<0)||($posx>=$this->width)||($posy>=$this->width))
|
||||
return 0;
|
||||
|
||||
return $this->tab[$posy][$posx];
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
private function addGroupElement($groupId, $h, $v, $sx, $sy)
|
||||
{
|
||||
$this->groups[$groupId]->total++;
|
||||
if ($h)
|
||||
$this->groups[$groupId]->horizontal = true;
|
||||
if ($v)
|
||||
$this->groups[$groupId]->vertical = true;
|
||||
$this->groups[$groupId]->points[] = array($sx, $sy, false);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function detectGroups()
|
||||
{
|
||||
for ($sy = 0; $sy < $this->width; $sy++) {
|
||||
for ($sx = 0; $sx < $this->width; $sx++) {
|
||||
|
||||
if ($this->tab[$sy][$sx] == 1) { // non-allocated
|
||||
|
||||
$gid_left = 0;
|
||||
$gid_top = 0;
|
||||
|
||||
$grouped = false;
|
||||
|
||||
if ($sx>0) {
|
||||
|
||||
$gid_left = $this->tab[$sy][$sx-1]; // previous on left
|
||||
|
||||
if ($gid_left > 1) { // if already in group
|
||||
$this->tab[$sy][$sx] = $gid_left;
|
||||
$grouped = true;
|
||||
$this->addGroupElement($gid_left, true, false, $sx, $sy);
|
||||
}
|
||||
}
|
||||
|
||||
if ($sy > 0) {
|
||||
|
||||
$gid_top = $this->tab[$sy-1][$sx]; // previous on top
|
||||
|
||||
if ($gid_top > 1) { //if in group
|
||||
if (!$grouped) { // and not grouped
|
||||
|
||||
$this->tab[$sy][$sx] = $gid_top;
|
||||
$grouped = true;
|
||||
|
||||
$this->addGroupElement($gid_top, false, true, $sx, $sy);
|
||||
|
||||
} else if($gid_top != $gid_left) { // was in left group
|
||||
|
||||
$grouped = true;
|
||||
|
||||
$this->groups[$gid_top]->vertical = true;
|
||||
$this->groups[$gid_top]->horizontal = true;
|
||||
|
||||
$this->groups[$gid_top]->total = $this->groups[$gid_top]->total + $this->groups[$gid_left]->total;
|
||||
|
||||
foreach($this->groups[$gid_left]->points as $elem)
|
||||
$this->tab[$elem[1]][$elem[0]] = $gid_top;
|
||||
|
||||
$this->groups[$gid_top]->points = array_values(array_merge($this->groups[$gid_top]->points, $this->groups[$gid_left]->points));
|
||||
unset($this->groups[$gid_left]);
|
||||
|
||||
//refarb group
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$grouped) {
|
||||
$this->curr_group++;
|
||||
$this->tab[$sy][$sx] = $this->curr_group;
|
||||
$this->groups[$this->curr_group] = new QRareaGroup($this->curr_group, $sx, $sy);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
private function detectSquare($group)
|
||||
{
|
||||
$max_x = 0;
|
||||
$max_y = 0;
|
||||
$min_x = $this->width;
|
||||
$min_y = $this->width;
|
||||
|
||||
foreach($group->points as $elem) {
|
||||
$min_x = min($min_x, $elem[QR_AREA_X]);
|
||||
$max_x = max($max_x, $elem[QR_AREA_X]);
|
||||
$min_y = min($min_y, $elem[QR_AREA_Y]);
|
||||
$max_y = max($max_y, $elem[QR_AREA_Y]);
|
||||
}
|
||||
|
||||
return array($min_x, $min_y, $max_x+1, $max_y+1);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function detectAreas()
|
||||
{
|
||||
$squares = array();
|
||||
$points = array();
|
||||
$lshapes = array();
|
||||
|
||||
foreach ($this->groups as $groupId=>&$group) {
|
||||
if ($group->total > 3) {
|
||||
|
||||
if ((!$group->vertical)||(!$group->horizontal)) {
|
||||
|
||||
$squareCoord = $this->detectSquare($group);
|
||||
array_unshift($squareCoord, QR_AREA_RECT);
|
||||
|
||||
$this->paths[] = $squareCoord;
|
||||
|
||||
} else {
|
||||
|
||||
$this->detectPaths($group);
|
||||
unset($group->points);
|
||||
|
||||
foreach($group->paths as &$path)
|
||||
self::rle($path[2]);
|
||||
|
||||
$this->paths[] = array(QR_AREA_PATH, $group->paths);
|
||||
}
|
||||
} else if (($group->total == 3)&&($group->vertical)&&($group->horizontal)) {
|
||||
$squareCoord = $this->detectSquare($group);
|
||||
$variant = 0;
|
||||
|
||||
if ($this->getOnElem($squareCoord, 0, 0) != $group->id)
|
||||
$variant = 0;
|
||||
|
||||
if ($this->getOnElem($squareCoord, 1, 0) != $group->id)
|
||||
$variant = 1;
|
||||
|
||||
if ($this->getOnElem($squareCoord, 0, 1) != $group->id)
|
||||
$variant = 2;
|
||||
|
||||
if ($this->getOnElem($squareCoord, 1, 1) != $group->id)
|
||||
$variant = 3;
|
||||
|
||||
$lshapes[] = $squareCoord[QR_AREA_X];
|
||||
$lshapes[] = $squareCoord[QR_AREA_Y];
|
||||
$lshapes[] = $variant;
|
||||
|
||||
} else if ($group->total >= 2) {
|
||||
$squareCoord = $this->detectSquare($group);
|
||||
$squares = array_merge($squares, $squareCoord);
|
||||
} else if ($group->total == 1) {
|
||||
$points[] = $group->points[0][0];
|
||||
$points[] = $group->points[0][1];
|
||||
}
|
||||
}
|
||||
|
||||
if (count($points) > 0) {
|
||||
array_unshift($points, QR_AREA_POINT);
|
||||
$this->paths[] = $points;
|
||||
}
|
||||
|
||||
if (count($squares) > 0) {
|
||||
array_unshift($squares, QR_AREA_RECT);
|
||||
$this->paths[] = $squares;
|
||||
}
|
||||
|
||||
if (count($lshapes) > 0) {
|
||||
array_unshift($lshapes, QR_AREA_LSHAPE);
|
||||
$this->paths[] = $lshapes;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
private function reserveEdgeOnElem($elem, $edgeNo)
|
||||
{
|
||||
$this->tab_edges[$elem[QR_AREA_Y]][$elem[QR_AREA_X]][$edgeNo] = true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
private function reserveEdge($px, $py, $edgeNo)
|
||||
{
|
||||
$this->tab_edges[$py][$px][$edgeNo] = true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
private function markAdjacentEdges($group)
|
||||
{
|
||||
foreach($group->points as $elem) {
|
||||
if ($this->getOnElem($elem, -1, 0) == $group->id)
|
||||
$this->reserveEdgeOnElem($elem, QR_AREA_W);
|
||||
|
||||
if ($this->getOnElem($elem, +1, 0) == $group->id)
|
||||
$this->reserveEdgeOnElem($elem, QR_AREA_E);
|
||||
|
||||
if ($this->getOnElem($elem, 0, -1) == $group->id)
|
||||
$this->reserveEdgeOnElem($elem, QR_AREA_N);
|
||||
|
||||
if ($this->getOnElem($elem, 0, +1) == $group->id)
|
||||
$this->reserveEdgeOnElem($elem, QR_AREA_S);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
private function detectPaths(&$group)
|
||||
{
|
||||
$this->markAdjacentEdges($group);
|
||||
|
||||
$elem = $group->points[0];
|
||||
$waylist = $this->findPath($group, $elem[QR_AREA_X], $elem[QR_AREA_Y]);
|
||||
$group->paths[] = array($elem[QR_AREA_X], $elem[QR_AREA_Y], $waylist);
|
||||
|
||||
$tab = array();
|
||||
foreach($group->points as $elem) {
|
||||
|
||||
$edgeTab = $this->tab_edges[$elem[QR_AREA_Y]][$elem[QR_AREA_X]];
|
||||
|
||||
if (!( $edgeTab[QR_AREA_N]
|
||||
&& $edgeTab[QR_AREA_E]
|
||||
&& $edgeTab[QR_AREA_S]
|
||||
&& $edgeTab[QR_AREA_W])) {
|
||||
|
||||
if (!$edgeTab[QR_AREA_S]) {
|
||||
|
||||
$waylistw = $this->findPath($group, $elem[QR_AREA_X], $elem[QR_AREA_Y]+1);
|
||||
$group->paths[] = array($elem[QR_AREA_X], $elem[QR_AREA_Y]+1, $waylistw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
private function findPath($group, $sx, $sy)
|
||||
{
|
||||
$px = $sx;
|
||||
$py = $sy;
|
||||
|
||||
$waylist = '';
|
||||
$dir = '';
|
||||
$lastdir = '';
|
||||
|
||||
$moves = array(
|
||||
// magic :)
|
||||
0=>'', 1=>'L', 2=>'T', 3=>'L', 4=>'B', 5=>'B', 6=>'B,T', 7=>'B'
|
||||
,8=>'R', 9=>'R,L', 10=>'T', 11=>'L',12=>'R',13=>'R',14=>'T',15=>''
|
||||
);
|
||||
|
||||
do
|
||||
{
|
||||
$Q = ($this->getAt($px-1, $py-1) == $group->id)?1:0;
|
||||
$Q += ($this->getAt($px, $py-1) == $group->id)?2:0;
|
||||
$Q += ($this->getAt($px-1, $py) == $group->id)?4:0;
|
||||
$Q += ($this->getAt($px, $py) == $group->id)?8:0;
|
||||
|
||||
if ($moves[$Q] == '')
|
||||
throw new Exception('It should NEVER happened!');
|
||||
|
||||
$move_expl = explode(',', $moves[$Q]);
|
||||
$have_way = false;
|
||||
|
||||
$dir = '';
|
||||
|
||||
while ((count($move_expl) > 0)&&($have_way == false)) {
|
||||
$way = array_shift($move_expl);
|
||||
|
||||
if (($have_way==false)&&($way=='R')&&($this->tab_edges[$py][$px][QR_AREA_N]==false)) {
|
||||
$have_way = true;
|
||||
$dir = $way;
|
||||
$this->reserveEdge($px, $py, QR_AREA_N);
|
||||
$px++;
|
||||
}
|
||||
|
||||
if (($have_way==false)&&($way=='B')&&($this->tab_edges[$py][$px-1][QR_AREA_E]==false)) {
|
||||
$have_way = true;
|
||||
$dir = $way;
|
||||
$this->reserveEdge($px-1, $py, QR_AREA_E);
|
||||
$py++;
|
||||
}
|
||||
|
||||
if (($have_way==false)&&($way=='L')&&($this->tab_edges[$py-1][$px-1][QR_AREA_S]==false)) {
|
||||
$have_way = true;
|
||||
$dir = $way;
|
||||
$this->reserveEdge($px-1, $py-1, QR_AREA_S);
|
||||
$px--;
|
||||
}
|
||||
|
||||
if (($have_way==false)&&($way=='T')&&($this->tab_edges[$py-1][$px][QR_AREA_W]==false)) {
|
||||
$have_way = true;
|
||||
$dir = $way;
|
||||
$this->reserveEdge($px, $py-1, QR_AREA_W);
|
||||
$py--;
|
||||
}
|
||||
}
|
||||
|
||||
$waylist .= $dir;
|
||||
|
||||
} while (!(($px==$sx)&&($py==$sy)));
|
||||
|
||||
return $waylist;
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
235
public/phpqrcode/qrbitstream.php
Executable file
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
/*
|
||||
* PHP QR Code encoder
|
||||
*
|
||||
* Bitstream class
|
||||
*
|
||||
* Based on libqrencode C library distributed under LGPL 2.1
|
||||
* Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* PHP QR Code is distributed under LGPL 3
|
||||
* Copyright (C) 2010-2013 Dominik Dzienia <deltalab at poczta dot fm>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @addtogroup CoreGroup */
|
||||
/** @{ */
|
||||
|
||||
/**
|
||||
PHP bit stream.
|
||||
Class implementing array of bits (= 1 or 0 ints). Allows to initialize and append
|
||||
bits from given Integer or array of Bytes.
|
||||
*/
|
||||
class QRbitstream {
|
||||
|
||||
/**
|
||||
Array containing bit data stream
|
||||
*/
|
||||
public $data = array();
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
@return Integer size of byte stream
|
||||
*/
|
||||
public function size()
|
||||
{
|
||||
return count($this->data);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
Allocates bit stream, fills bit data stream with 0's.
|
||||
This operation is __destructive__, will replace orginal stream contents!
|
||||
@param Integer $setLength desired target stream size
|
||||
@return Integer 0 on success, other on failure
|
||||
*/
|
||||
public function allocate($setLength)
|
||||
{
|
||||
$this->data = array_fill(0, $setLength, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
Creates new bit stream from given Integer number.
|
||||
@param Integer $bits bit count
|
||||
@param Integer $num integer to convert
|
||||
@return QRbitstream bit stream object containing first $bits bits from $num in order from LSB to MSB
|
||||
*/
|
||||
public static function newFromNum($bits, $num)
|
||||
{
|
||||
$bstream = new QRbitstream();
|
||||
$bstream->allocate($bits);
|
||||
|
||||
$mask = 1 << ($bits - 1);
|
||||
for($i=0; $i<$bits; $i++) {
|
||||
if($num & $mask) {
|
||||
$bstream->data[$i] = 1;
|
||||
} else {
|
||||
$bstream->data[$i] = 0;
|
||||
}
|
||||
$mask = $mask >> 1;
|
||||
}
|
||||
|
||||
return $bstream;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
Creates new bit stream from given byte array.
|
||||
@param Integer $size size of array
|
||||
@param Array $data array ob bytes
|
||||
@return QRbitstream bit stream object containing bit contents of given bytes array
|
||||
*/
|
||||
public static function newFromBytes($size, $data)
|
||||
{
|
||||
$bstream = new QRbitstream();
|
||||
$bstream->allocate($size * 8);
|
||||
$p=0;
|
||||
|
||||
for($i=0; $i<$size; $i++) {
|
||||
$mask = 0x80;
|
||||
for($j=0; $j<8; $j++) {
|
||||
if($data[$i] & $mask) {
|
||||
$bstream->data[$p] = 1;
|
||||
} else {
|
||||
$bstream->data[$p] = 0;
|
||||
}
|
||||
$p++;
|
||||
$mask = $mask >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
return $bstream;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
Appends given bit stream at end of this stream.
|
||||
@param QRbitstream $arg bit stream to be appended
|
||||
@return Integer status of append operation, 0 when success, -1 when $arg is null
|
||||
*/
|
||||
public function append(QRbitstream $arg)
|
||||
{
|
||||
if (is_null($arg)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if($arg->size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if($this->size() == 0) {
|
||||
$this->data = $arg->data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
$this->data = array_values(array_merge($this->data, $arg->data));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
Appends bit stream cteated from given Integer number at end of current stream.
|
||||
@param Integer $bits bit count
|
||||
@param Integer $num integer to convert
|
||||
@return Integer status of append operation, status of append operation, 0 when success, -1 otherwise
|
||||
*/
|
||||
public function appendNum($bits, $num)
|
||||
{
|
||||
if ($bits == 0)
|
||||
return 0;
|
||||
|
||||
$b = QRbitstream::newFromNum($bits, $num);
|
||||
|
||||
if(is_null($b))
|
||||
return -1;
|
||||
|
||||
$ret = $this->append($b);
|
||||
unset($b);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
Appends bit stream created from from given byte array at end of current stream.
|
||||
@param Integer $size size of array
|
||||
@param Array $data array ob bytes
|
||||
@return Integer status of append operation, status of append operation, 0 when success, -1 otherwise
|
||||
*/
|
||||
public function appendBytes($size, $data)
|
||||
{
|
||||
if ($size == 0)
|
||||
return 0;
|
||||
|
||||
$b = QRbitstream::newFromBytes($size, $data);
|
||||
|
||||
if(is_null($b))
|
||||
return -1;
|
||||
|
||||
$ret = $this->append($b);
|
||||
unset($b);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
Converts current bit stream into byte array.
|
||||
@returns Array array of bytes
|
||||
*/
|
||||
public function toByte()
|
||||
{
|
||||
|
||||
$size = $this->size();
|
||||
|
||||
if($size == 0) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$data = array_fill(0, (int)(($size + 7) / 8), 0);
|
||||
$bytes = (int)($size / 8);
|
||||
|
||||
$p = 0;
|
||||
|
||||
for($i=0; $i<$bytes; $i++) {
|
||||
$v = 0;
|
||||
for($j=0; $j<8; $j++) {
|
||||
$v = $v << 1;
|
||||
$v |= $this->data[$p];
|
||||
$p++;
|
||||
}
|
||||
$data[$i] = $v;
|
||||
}
|
||||
|
||||
if($size & 7) {
|
||||
$v = 0;
|
||||
for($j=0; $j<($size & 7); $j++) {
|
||||
$v = $v << 1;
|
||||
$v |= $this->data[$p];
|
||||
$p++;
|
||||
}
|
||||
$data[$bytes] = $v;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** @}*/
|
||||
363
public/phpqrcode/qrcanvas.php
Executable file
@@ -0,0 +1,363 @@
|
||||
<?php
|
||||
/*
|
||||
* PHP QR Code encoder
|
||||
*
|
||||
* CANVAS output
|
||||
*
|
||||
* Based on libqrencode C library distributed under LGPL 2.1
|
||||
* Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* PHP QR Code is distributed under LGPL 3
|
||||
* Copyright (C) 2010-2013 Dominik Dzienia <deltalab at poczta dot fm>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @addtogroup OutputGroup */
|
||||
/** @{ */
|
||||
|
||||
class QRcanvasOutput extends QRarea {
|
||||
|
||||
public function __construct($source_tab)
|
||||
{
|
||||
parent::__construct($source_tab);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function encodeNum($num)
|
||||
{
|
||||
$addTab = array(0=>'', 1=>'z', 2=>'Z', 3=>'+');
|
||||
$map = '0123456789abcdefghijklmnopqrstuvwxyABCDEFGHIJKLMNOPQRSTUVWXY';
|
||||
$mapPos = $num % 60;
|
||||
$mapAdd = (int)($num / 60);
|
||||
|
||||
return $addTab[$mapAdd].$map[$mapPos];
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function compact_path(&$pathTab)
|
||||
{
|
||||
if (count($pathTab) == 0) {
|
||||
$pathTab = '';
|
||||
} else {
|
||||
$pathTab = count($pathTab).','.join(',', $pathTab);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function compact_points(&$pointsTab)
|
||||
{
|
||||
if (count($pointsTab) == 0) {
|
||||
$pointsTab = '';
|
||||
} else {
|
||||
$compacted = '';
|
||||
foreach ($pointsTab as $point)
|
||||
$compacted .= self::encodeNum($point);
|
||||
$pointsTab = $compacted;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function compactCanvasCommands($ops)
|
||||
{
|
||||
$accumulated = array();
|
||||
|
||||
$accumulated['SR'] = array();
|
||||
$accumulated['WR'] = array();
|
||||
$accumulated['SP'] = array();
|
||||
$accumulated['WP'] = array();
|
||||
$accumulated['SB'] = array();
|
||||
$accumulated['WB'] = array();
|
||||
$accumulated['SO'] = array();
|
||||
|
||||
while (count($ops) > 0) {
|
||||
$color = array_shift($ops);
|
||||
$opcode = array_shift($ops);
|
||||
|
||||
if (($opcode == 'R') || ($opcode == 'P')) {
|
||||
|
||||
do {
|
||||
$num = array_shift($ops);
|
||||
if (is_int($num)) {
|
||||
$accumulated[$color.$opcode][] = $num;
|
||||
} else {
|
||||
array_unshift($ops, $num);
|
||||
}
|
||||
|
||||
} while ((count($ops) > 0)&&(is_int($num)));
|
||||
|
||||
|
||||
} else if ($opcode == 'B') {
|
||||
|
||||
array_shift($ops);
|
||||
|
||||
$px = array_shift($ops);
|
||||
$py = array_shift($ops);
|
||||
|
||||
array_shift($ops);
|
||||
|
||||
$conftab = array();
|
||||
$num = array_shift($ops);
|
||||
|
||||
while ((count($ops) > 0)&&(!($num === 'E'))) {
|
||||
$conftab[] = $num;
|
||||
$num = array_shift($ops);
|
||||
}
|
||||
|
||||
$cc = count($conftab);
|
||||
$deltas = '';
|
||||
|
||||
$lastposx = $px;
|
||||
$lastposy = $py;
|
||||
|
||||
for($pos=0;$pos <$cc; $pos+=2) {
|
||||
|
||||
$dx = $lastposx - $conftab[$pos];
|
||||
$dy = $lastposy - $conftab[$pos+1];
|
||||
|
||||
$lastposx = $conftab[$pos];
|
||||
$lastposy = $conftab[$pos+1];
|
||||
|
||||
if ($dx < 0) {
|
||||
$deltas .= chr(ord('a')-1-$dx);
|
||||
} else if ($dx > 0) {
|
||||
$deltas .= chr(ord('A')-1+$dx);
|
||||
} else {
|
||||
$deltas .= '0';
|
||||
}
|
||||
|
||||
if ($dy < 0) {
|
||||
$deltas .= chr(ord('a')-1-$dy);
|
||||
} else if ($dy > 0) {
|
||||
$deltas .= chr(ord('A')-1+$dy);
|
||||
} else {
|
||||
$deltas .= '0';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$deltas = strtr($deltas, array(
|
||||
'00'=>'1',
|
||||
'aa'=>'2',
|
||||
'aA'=>'3',
|
||||
'Aa'=>'4',
|
||||
'AA'=>'5',
|
||||
'aB'=>'6',
|
||||
'Ab'=>'7',
|
||||
'bA'=>'8',
|
||||
'Ba'=>'9'
|
||||
));
|
||||
|
||||
$accumulated[$color.$opcode][] = join(',', array($px, $py, $deltas));
|
||||
} else if ($opcode == 'O') {
|
||||
$px = array_shift($ops);
|
||||
$py = array_shift($ops);
|
||||
|
||||
$accumulated[$color.$opcode][] = join(',', array($px, $py));
|
||||
}
|
||||
}
|
||||
|
||||
self::compact_points($accumulated['SR']);
|
||||
self::compact_points($accumulated['WR']);
|
||||
self::compact_points($accumulated['SP']);
|
||||
self::compact_points($accumulated['WP']);
|
||||
|
||||
self::compact_path($accumulated['SB']);
|
||||
self::compact_path($accumulated['WB']);
|
||||
|
||||
if (count($accumulated['SO']) > 0)
|
||||
$accumulated['SO'] = join(',',$accumulated['SO']);
|
||||
else $accumulated['SO'] = '';
|
||||
|
||||
$mapping = array(
|
||||
'SO'=>'O',
|
||||
'SB'=>'B',
|
||||
'WB'=>'b',
|
||||
'SR'=>'R',
|
||||
'WR'=>'r',
|
||||
'SP'=>'P',
|
||||
'WP'=>'p'
|
||||
);
|
||||
|
||||
$whole = array();
|
||||
|
||||
foreach($mapping as $key=>$symb) {
|
||||
if ($accumulated[$key]!='')
|
||||
$whole[] = $symb.','.$accumulated[$key];
|
||||
}
|
||||
|
||||
return join(',', $whole);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function getCanvasOps()
|
||||
{
|
||||
$ops = array();
|
||||
|
||||
foreach ($this->paths as $path) {
|
||||
switch ($path[0]) {
|
||||
case QR_AREA_PATH:
|
||||
$pNum = 0;
|
||||
|
||||
foreach($path[1] as $pathDetails) {
|
||||
if ($pNum == 0) {
|
||||
$ops[] = 'S';
|
||||
} else if ($pNum > 0) {
|
||||
$ops[] = 'W';
|
||||
}
|
||||
|
||||
$ops[] = 'B';
|
||||
|
||||
$px = array_shift($pathDetails);
|
||||
$py = array_shift($pathDetails);
|
||||
|
||||
$ops[] = 'M';
|
||||
$ops[] = $px;
|
||||
$ops[] = $py;
|
||||
|
||||
$rle_steps = array_shift($pathDetails);
|
||||
|
||||
$lastOp = '';
|
||||
|
||||
while(count($rle_steps) > 0) {
|
||||
|
||||
$delta = 1;
|
||||
|
||||
$operator = array_shift($rle_steps);
|
||||
if (($operator != 'R') && ($operator != 'L') && ($operator != 'T') && ($operator != 'B')) {
|
||||
$delta = (int)$operator;
|
||||
$operator = array_shift($rle_steps);
|
||||
}
|
||||
|
||||
if ($operator == 'R') $px += $delta;
|
||||
if ($operator == 'L') $px -= $delta;
|
||||
if ($operator == 'T') $py -= $delta;
|
||||
if ($operator == 'B') $py += $delta;
|
||||
|
||||
if ($lastOp != 'T')
|
||||
$ops[] = 'T';
|
||||
|
||||
$ops[] = $px;
|
||||
$ops[] = $py;
|
||||
|
||||
$lastOp = 'T';
|
||||
}
|
||||
|
||||
$ops[] = 'E';
|
||||
|
||||
$pNum++;
|
||||
}
|
||||
|
||||
break;
|
||||
case QR_AREA_POINT:
|
||||
|
||||
$symb = array_shift($path);
|
||||
|
||||
$ops[] = 'S';
|
||||
|
||||
$lastOp = '';
|
||||
|
||||
while(count($path) > 0) {
|
||||
$px = array_shift($path);
|
||||
$py = array_shift($path);
|
||||
|
||||
if ($lastOp != 'P')
|
||||
$ops[] = 'P';
|
||||
|
||||
$ops[] = $px;
|
||||
$ops[] = $py;
|
||||
|
||||
$lastOp = 'P';
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case QR_AREA_RECT:
|
||||
|
||||
$symb = array_shift($path);
|
||||
|
||||
$ops[] = 'S';
|
||||
|
||||
$lastOp = '';
|
||||
|
||||
while(count($path) > 0) {
|
||||
$px = array_shift($path);
|
||||
$py = array_shift($path);
|
||||
$ex = array_shift($path);
|
||||
$ey = array_shift($path);
|
||||
|
||||
if ($lastOp != 'R')
|
||||
$ops[] = 'R';
|
||||
|
||||
$ops[] = $px;
|
||||
$ops[] = $py;
|
||||
$ops[] = $ex-$px;
|
||||
$ops[] = $ey-$py;
|
||||
|
||||
$lastOp = 'R';
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case QR_AREA_LSHAPE:
|
||||
|
||||
$symb = array_shift($path);
|
||||
|
||||
while(count($path) > 0) {
|
||||
$px = array_shift($path);
|
||||
$py = array_shift($path);
|
||||
$mode = (int)array_shift($path);
|
||||
|
||||
$pxd = ($mode % 2)?1:0;
|
||||
$pyd = ($mode > 1)?1:0;
|
||||
|
||||
$ops[] = 'S';
|
||||
$ops[] = 'R';
|
||||
$ops[] = $px;
|
||||
$ops[] = $py;
|
||||
$ops[] = 2;
|
||||
$ops[] = 2;
|
||||
|
||||
$ops[] = 'W';
|
||||
$ops[] = 'P';
|
||||
$ops[] = $px+$pxd;
|
||||
$ops[] = $py+$pyd;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case QR_AREA_TRACKER:
|
||||
|
||||
$symb = array_shift($path);
|
||||
|
||||
$px = array_shift($path);
|
||||
$py = array_shift($path);
|
||||
|
||||
$ops[] = 'S';
|
||||
$ops[] = 'O';
|
||||
$ops[] = $px;
|
||||
$ops[] = $py;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return self::compactCanvasCommands($ops);
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
51
public/phpqrcode/qrconfig.php
Executable file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/** \defgroup QR_DEFCONFIGS Global Config
|
||||
Global config file (contains global configuration-releted constants).
|
||||
Before version 2.0.0 only way to configure all calls. From version 2.0.0 values
|
||||
used here are treated as __defaults__ but culd be overwriten by additional config.
|
||||
parrameters passed to functions.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Mask cache switch.
|
||||
__Boolean__ Speciffies does mask ant template caching is enabled.
|
||||
- __true__ - disk cache is used, more disk reads are performed but less CPU power is required,
|
||||
- __false__ - mask and format templates are calculated each time in memory */
|
||||
define('QR_CACHEABLE', true);
|
||||
|
||||
/** Cache dir path.
|
||||
__String__ Used when QR_CACHEABLE === true. Specifies absolute server path
|
||||
for masks and format templates cache dir */
|
||||
define('QR_CACHE_DIR', dirname(__FILE__).DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR);
|
||||
|
||||
/** Default error logs dir.
|
||||
__String__ Absolute server path for log directory. */
|
||||
define('QR_LOG_DIR', dirname(__FILE__).DIRECTORY_SEPARATOR);
|
||||
|
||||
/** If best mask is found.
|
||||
__Boolean__ Speciffies mask searching strategy:
|
||||
- __true__ - estimates best mask (as QR-Code spec recomends by default) but may be extremally slow
|
||||
- __false__ - check only one mask (specified by __QR_DEFAULT_MASK__), gives significant performance boost but (propably) results in worst quality codes
|
||||
*/
|
||||
define('QR_FIND_BEST_MASK', true);
|
||||
|
||||
/** Configure random mask checking.
|
||||
Specifies algorithm for mask selection when __QR_FIND_BEST_MASK__ is set to __true__.
|
||||
- if Boolean __false__ - checks all masks available
|
||||
- if Integer __1..7__ - value tells count of randomly selected masks need to be checked
|
||||
*/
|
||||
define('QR_FIND_FROM_RANDOM', false);
|
||||
|
||||
/** Default an only mask to apply.
|
||||
__Integer__ Specifies mask no (1..8) to be aplied every time, used when __QR_FIND_BEST_MASK__ is set to __false__.
|
||||
*/
|
||||
define('QR_DEFAULT_MASK', 2);
|
||||
|
||||
/** Maximum allowed png image width (in pixels).
|
||||
__Integer__ Maximal width/height of generated raster image.
|
||||
Tune to make sure GD and PHP can handle such big images.
|
||||
*/
|
||||
define('QR_PNG_MAXIMUM_SIZE', 1024);
|
||||
|
||||
/** @}*/
|
||||
74
public/phpqrcode/qrconst.php
Executable file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* PHP QR Code encoder
|
||||
*
|
||||
* Common constants
|
||||
*
|
||||
* Based on libqrencode C library distributed under LGPL 2.1
|
||||
* Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* PHP QR Code is distributed under LGPL 3
|
||||
* Copyright (C) 2010-2013 Dominik Dzienia <deltalab at poczta dot fm>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
/** \defgroup QR_CONST Global Constants
|
||||
Constant used globally for function arguments.
|
||||
Make PHP calls a little bit more clear, in place of missing (in dynamicaly typed language) enum types.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @name QR-Code Encoding Modes */
|
||||
/** @{ */
|
||||
|
||||
/** null encoding, used when no encoding was speciffied yet */
|
||||
define('QR_MODE_NUL', -1);
|
||||
/** Numerical encoding, only numbers (0-9) */
|
||||
define('QR_MODE_NUM', 0);
|
||||
/** AlphaNumerical encoding, numbers (0-9) uppercase text (A-Z) and few special characters (space, $, %, *, +, -, ., /, :) */
|
||||
define('QR_MODE_AN', 1);
|
||||
/** 8-bit encoding, raw 8 bit encoding */
|
||||
define('QR_MODE_8', 2);
|
||||
/** Kanji encoding */
|
||||
define('QR_MODE_KANJI', 3);
|
||||
/** Structure, internal encoding for structure-related data */
|
||||
define('QR_MODE_STRUCTURE', 4);
|
||||
/**@}*/
|
||||
|
||||
/** @name QR-Code Levels of Error Correction
|
||||
Constants speciffy ECC level from lowest __L__ to the highest __H__.
|
||||
Higher levels are recomended for Outdoor-presented codes, but generates bigger codes.
|
||||
*/
|
||||
/** @{*/
|
||||
/** ~7% of codewords can be restored */
|
||||
define('QR_ECLEVEL_L', 0);
|
||||
/** ~15% of codewords can be restored */
|
||||
define('QR_ECLEVEL_M', 1);
|
||||
/** ~25% of codewords can be restored */
|
||||
define('QR_ECLEVEL_Q', 2);
|
||||
/** ~30% of codewords can be restored */
|
||||
define('QR_ECLEVEL_H', 3);
|
||||
/** @}*/
|
||||
|
||||
/** @name QR-Code Supported output formats */
|
||||
/** @{*/
|
||||
define('QR_FORMAT_TEXT', 0);
|
||||
define('QR_FORMAT_PNG', 1);
|
||||
/** @}*/
|
||||
|
||||
/** @}*/
|
||||
784
public/phpqrcode/qrencode.php
Executable file
@@ -0,0 +1,784 @@
|
||||
<?php
|
||||
/*
|
||||
* PHP QR Code encoder
|
||||
*
|
||||
* Main encoder classes.
|
||||
*
|
||||
* Based on libqrencode C library distributed under LGPL 2.1
|
||||
* Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* PHP QR Code is distributed under LGPL 3
|
||||
* Copyright (C) 2010-2013 Dominik Dzienia <deltalab at poczta dot fm>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @defgroup CoreGroup Standard API Core
|
||||
Core encoder classes */
|
||||
|
||||
/** @addtogroup CoreGroup */
|
||||
/** @{ */
|
||||
|
||||
//##########################################################################
|
||||
/**
|
||||
Data block with raw data and it's Error Correction Code data.
|
||||
*/
|
||||
class QRrsblock {
|
||||
public $dataLength;
|
||||
public $data = array();
|
||||
public $eccLength;
|
||||
public $ecc = array();
|
||||
|
||||
/** Data block Constructor
|
||||
@param Integer $dl length of data stream
|
||||
@param Array $data data stream
|
||||
@param Integer $el ECC length
|
||||
@param Array $el ECC stream (modified, by reference)
|
||||
@param QRrsItem $rs RS encoding item
|
||||
*/
|
||||
public function __construct($dl, $data, $el, &$ecc, QRrsItem $rs)
|
||||
{
|
||||
$rs->encode_rs_char($data, $ecc);
|
||||
|
||||
$this->dataLength = $dl;
|
||||
$this->data = $data;
|
||||
$this->eccLength = $el;
|
||||
$this->ecc = $ecc;
|
||||
}
|
||||
};
|
||||
|
||||
//##########################################################################
|
||||
/** Raw Code holder.
|
||||
Contains encoded code data before there are spatialy distributed into frame and masked.
|
||||
Here goes dividing data into blocks and calculating ECC stream. */
|
||||
class QRrawcode {
|
||||
|
||||
public $version; ///< __Integer__ code Version
|
||||
public $datacode = array(); ///< __Array__ data stream
|
||||
public $ecccode = array(); ///< __Array__ ECC Stream
|
||||
public $blocks; ///< __Integer__ RS Blocks count
|
||||
public $rsblocks = array(); ///< __Array__ of RSblock, ECC code blocks
|
||||
public $count; ///< __Integer__ position of currently processed ECC code
|
||||
public $dataLength; ///< __Integer__ data stream length
|
||||
public $eccLength; ///< __Integer__ ECC stream length
|
||||
public $b1; ///< __Integer__ width of code in pixels, used as a modulo base for column overflow
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Raw Code holder Constructor
|
||||
@param QRinput $input input stream
|
||||
*/
|
||||
public function __construct(QRinput $input)
|
||||
{
|
||||
$spec = array(0,0,0,0,0);
|
||||
|
||||
$this->datacode = $input->getByteStream();
|
||||
if(is_null($this->datacode)) {
|
||||
throw new Exception('null imput string');
|
||||
}
|
||||
|
||||
QRspec::getEccSpec($input->getVersion(), $input->getErrorCorrectionLevel(), $spec);
|
||||
|
||||
$this->version = $input->getVersion();
|
||||
$this->b1 = QRspec::rsBlockNum1($spec);
|
||||
$this->dataLength = QRspec::rsDataLength($spec);
|
||||
$this->eccLength = QRspec::rsEccLength($spec);
|
||||
$this->ecccode = array_fill(0, $this->eccLength, 0);
|
||||
$this->blocks = QRspec::rsBlockNum($spec);
|
||||
|
||||
$ret = $this->init($spec);
|
||||
if($ret < 0) {
|
||||
throw new Exception('block alloc error');
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->count = 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Initializes Raw Code according to current code speciffication
|
||||
@param Array $spec code speciffigation, as provided by QRspec
|
||||
*/
|
||||
public function init(array $spec)
|
||||
{
|
||||
$dl = QRspec::rsDataCodes1($spec);
|
||||
$el = QRspec::rsEccCodes1($spec);
|
||||
$rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
|
||||
|
||||
|
||||
$blockNo = 0;
|
||||
$dataPos = 0;
|
||||
$eccPos = 0;
|
||||
for($i=0; $i<QRspec::rsBlockNum1($spec); $i++) {
|
||||
$ecc = array_slice($this->ecccode,$eccPos);
|
||||
$this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs);
|
||||
$this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc);
|
||||
|
||||
$dataPos += $dl;
|
||||
$eccPos += $el;
|
||||
$blockNo++;
|
||||
}
|
||||
|
||||
if(QRspec::rsBlockNum2($spec) == 0)
|
||||
return 0;
|
||||
|
||||
$dl = QRspec::rsDataCodes2($spec);
|
||||
$el = QRspec::rsEccCodes2($spec);
|
||||
$rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
|
||||
|
||||
if($rs == NULL) return -1;
|
||||
|
||||
for($i=0; $i<QRspec::rsBlockNum2($spec); $i++) {
|
||||
$ecc = array_slice($this->ecccode,$eccPos);
|
||||
$this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs);
|
||||
$this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc);
|
||||
|
||||
$dataPos += $dl;
|
||||
$eccPos += $el;
|
||||
$blockNo++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Gets ECC code
|
||||
@return Integer ECC byte for current object position
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$ret;
|
||||
|
||||
if($this->count < $this->dataLength) {
|
||||
$row = $this->count % $this->blocks;
|
||||
$col = $this->count / $this->blocks;
|
||||
if($col >= $this->rsblocks[0]->dataLength) {
|
||||
$row += $this->b1;
|
||||
}
|
||||
$ret = $this->rsblocks[$row]->data[$col];
|
||||
} else if($this->count < $this->dataLength + $this->eccLength) {
|
||||
$row = ($this->count - $this->dataLength) % $this->blocks;
|
||||
$col = ($this->count - $this->dataLength) / $this->blocks;
|
||||
$ret = $this->rsblocks[$row]->ecc[$col];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
$this->count++;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
//##########################################################################
|
||||
/**
|
||||
__Main class to create QR-code__.
|
||||
QR Code symbol is a 2D barcode that can be scanned by handy terminals such as a mobile phone with CCD.
|
||||
The capacity of QR Code is up to 7000 digits or 4000 characters, and has high robustness.
|
||||
This class supports QR Code model 2, described in JIS (Japanese Industrial Standards) X0510:2004 or ISO/IEC 18004.
|
||||
|
||||
Currently the following features are not supported: ECI and FNC1 mode, Micro QR Code, QR Code model 1, Structured mode.
|
||||
|
||||
@abstract Class for generating QR-code images, SVG and HTML5 Canvas
|
||||
@author Dominik Dzienia
|
||||
@copyright 2010-2013 Dominik Dzienia and others
|
||||
@link http://phpqrcode.sourceforge.net
|
||||
@license http://www.gnu.org/copyleft/lesser.html LGPL
|
||||
*/
|
||||
|
||||
class QRcode {
|
||||
|
||||
public $version; ///< __Integer__ QR code version. Size of QRcode is defined as version. Version is from 1 to 40. Version 1 is 21*21 matrix. And 4 modules increases whenever 1 version increases. So version 40 is 177*177 matrix.
|
||||
public $width; ///< __Integer__ Width of code table. Because code is square shaped - same as height.
|
||||
public $data; ///< __Array__ Ready, masked code data.
|
||||
|
||||
/** Canvas JS include flag.
|
||||
If canvas js support library was included, we remember it static in QRcode.
|
||||
(because file should be included only once)
|
||||
*/
|
||||
public static $jscanvasincluded = false;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
Encode mask
|
||||
Main function responsible for creating code.
|
||||
We get empty frame, then fill it with data from input, then select best mask and apply it.
|
||||
If $mask argument is greater than -1 we assume that user want's that specific mask number (ranging form 0-7) to be used.
|
||||
Otherwise (when $mask is -1) mask is detected using algorithm depending of global configuration,
|
||||
|
||||
@param QRinput $input data object
|
||||
@param Integer $mask sugested masking mode
|
||||
@return QRcode $this (current instance)
|
||||
*/
|
||||
public function encodeMask(QRinput $input, $mask)
|
||||
{
|
||||
if($input->getVersion() < 0 || $input->getVersion() > QRSPEC_VERSION_MAX) {
|
||||
throw new Exception('wrong version');
|
||||
}
|
||||
if($input->getErrorCorrectionLevel() > QR_ECLEVEL_H) {
|
||||
throw new Exception('wrong level');
|
||||
}
|
||||
|
||||
$raw = new QRrawcode($input);
|
||||
|
||||
QRtools::markTime('after_raw');
|
||||
|
||||
$version = $raw->version;
|
||||
$width = QRspec::getWidth($version);
|
||||
$frame = QRspec::newFrame($version);
|
||||
|
||||
$filler = new QRframeFiller($width, $frame);
|
||||
if(is_null($filler)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// inteleaved data and ecc codes
|
||||
for($i=0; $i<$raw->dataLength + $raw->eccLength; $i++) {
|
||||
$code = $raw->getCode();
|
||||
$bit = 0x80;
|
||||
for($j=0; $j<8; $j++) {
|
||||
$addr = $filler->next();
|
||||
$filler->setFrameAt($addr, 0x02 | (($bit & $code) != 0));
|
||||
$bit = $bit >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
QRtools::markTime('after_filler');
|
||||
|
||||
unset($raw);
|
||||
|
||||
// remainder bits
|
||||
$j = QRspec::getRemainder($version);
|
||||
for($i=0; $i<$j; $i++) {
|
||||
$addr = $filler->next();
|
||||
$filler->setFrameAt($addr, 0x02);
|
||||
}
|
||||
|
||||
$frame = $filler->frame;
|
||||
unset($filler);
|
||||
|
||||
|
||||
// masking
|
||||
$maskObj = new QRmask();
|
||||
if($mask < 0) {
|
||||
|
||||
if (QR_FIND_BEST_MASK) {
|
||||
$masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel());
|
||||
} else {
|
||||
$masked = $maskObj->makeMask($width, $frame, (intval(QR_DEFAULT_MASK) % 8), $input->getErrorCorrectionLevel());
|
||||
}
|
||||
} else {
|
||||
$masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel());
|
||||
}
|
||||
|
||||
if($masked == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QRtools::markTime('after_mask');
|
||||
|
||||
$this->version = $version;
|
||||
$this->width = $width;
|
||||
$this->data = $masked;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
Encode input with mask detection.
|
||||
Shorthand for encodeMask, without specifing particular, static mask number.
|
||||
|
||||
@param QRinput $input data object to be encoded
|
||||
@return
|
||||
*/
|
||||
public function encodeInput(QRinput $input)
|
||||
{
|
||||
return $this->encodeMask($input, -1);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
Encode string, forcing 8-bit encoding
|
||||
@param String $string input string
|
||||
@param Integer $version code version (size of code area)
|
||||
@param Integer $level ECC level (see: Global Constants -> Levels of Error Correction)
|
||||
@return QRcode $this (current instance)
|
||||
*/
|
||||
public function encodeString8bit($string, $version, $level)
|
||||
{
|
||||
if($string == NULL) {
|
||||
throw new Exception('empty string!');
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$input = new QRinput($version, $level);
|
||||
if($input == NULL) return NULL;
|
||||
|
||||
$ret = $input->append(QR_MODE_8, strlen($string), str_split($string));
|
||||
if($ret < 0) {
|
||||
unset($input);
|
||||
return NULL;
|
||||
}
|
||||
return $this->encodeInput($input);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
Encode string, using optimal encodings.
|
||||
Encode string dynamically adjusting encoding for subsections of string to
|
||||
minimize resulting code size. For complex string it will split string into
|
||||
subsections: Numerical, Alphanumerical or 8-bit.
|
||||
@param String $string input string
|
||||
@param Integer $version code version (size of code area)
|
||||
@param String $level ECC level (see: Global Constants -> Levels of Error Correction)
|
||||
@param Integer $hint __QR_MODE_8__ or __QR_MODE_KANJI__, Because Kanji encoding
|
||||
is kind of 8 bit encoding we need to hint encoder to use Kanji mode explicite.
|
||||
(otherwise it may try to encode it as plain 8 bit stream)
|
||||
@param Boolean $casesensitive hint if given string is case-sensitive, because
|
||||
if not - encoder may use optimal QR_MODE_AN instead of QR_MODE_8
|
||||
@return QRcode $this (current instance)
|
||||
*/
|
||||
public function encodeString($string, $version, $level, $hint, $casesensitive)
|
||||
{
|
||||
|
||||
if($hint != QR_MODE_8 && $hint != QR_MODE_KANJI) {
|
||||
throw new Exception('bad hint');
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$input = new QRinput($version, $level);
|
||||
if($input == NULL) return NULL;
|
||||
|
||||
$ret = QRsplit::splitStringToQRinput($string, $input, $hint, $casesensitive);
|
||||
if($ret < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return $this->encodeInput($input);
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
/**
|
||||
Creates PNG image containing QR-Code.
|
||||
Simple helper function to create QR-Code Png image with one static call.
|
||||
@param String $text text string to encode
|
||||
@param String $outfile (optional) output file name, if __false__ outputs to browser with required headers
|
||||
@param Integer $level (optional) error correction level __QR_ECLEVEL_L__, __QR_ECLEVEL_M__, __QR_ECLEVEL_Q__ or __QR_ECLEVEL_H__
|
||||
@param Integer $size (optional) pixel size, multiplier for each 'virtual' pixel
|
||||
@param Integer $margin (optional) code margin (silent zone) in 'virtual' pixels
|
||||
@param Boolean $saveandprint (optional) if __true__ code is outputed to browser and saved to file, otherwise only saved to file. It is effective only if $outfile is specified.
|
||||
*/
|
||||
|
||||
public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $saveandprint=false)
|
||||
{
|
||||
$enc = QRencode::factory($level, $size, $margin);
|
||||
return $enc->encodePNG($text, $outfile, $saveandprint=false);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
Creates text (1's & 0's) containing QR-Code.
|
||||
Simple helper function to create QR-Code text with one static call.
|
||||
@param String $text text string to encode
|
||||
@param String $outfile (optional) output file name, when __false__ file is not saved
|
||||
@param Integer $level (optional) error correction level __QR_ECLEVEL_L__, __QR_ECLEVEL_M__, __QR_ECLEVEL_Q__ or __QR_ECLEVEL_H__
|
||||
@param Integer $size (optional) pixel size, multiplier for each 'virtual' pixel
|
||||
@param Integer $margin (optional) code margin (silent zone) in 'virtual' pixels
|
||||
@return Array containing line of code with 1 and 0 for every code line
|
||||
*/
|
||||
|
||||
public static function text($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4)
|
||||
{
|
||||
$enc = QRencode::factory($level, $size, $margin);
|
||||
return $enc->encode($text, $outfile);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
Creates Raw Array containing QR-Code.
|
||||
Simple helper function to create QR-Code array with one static call.
|
||||
@param String $text text string to encode
|
||||
@param Boolean $outfile (optional) not used, shuold be __false__
|
||||
@param Integer $level (optional) error correction level __QR_ECLEVEL_L__, __QR_ECLEVEL_M__, __QR_ECLEVEL_Q__ or __QR_ECLEVEL_H__
|
||||
@param Integer $size (optional) pixel size, multiplier for each 'virtual' pixel
|
||||
@param Integer $margin (optional) code margin (silent zone) in 'virtual' pixels
|
||||
@return Array containing Raw QR code
|
||||
*/
|
||||
|
||||
public static function raw($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4)
|
||||
{
|
||||
$enc = QRencode::factory($level, $size, $margin);
|
||||
return $enc->encodeRAW($text, $outfile);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
Creates Html+JS code to draw QR-Code with HTML5 Canvas.
|
||||
Simple helper function to create QR-Code array with one static call.
|
||||
@param String $text text string to encode
|
||||
@param String $elemId (optional) target Canvas tag id attribute, if __false__ Canvas tag with auto id will be created
|
||||
@param Integer $level (optional) error correction level __QR_ECLEVEL_L__, __QR_ECLEVEL_M__, __QR_ECLEVEL_Q__ or __QR_ECLEVEL_H__
|
||||
@param Integer $width (optional) CANVAS element width (sam as height)
|
||||
@param Integer $size (optional) pixel size, multiplier for each 'virtual' pixel
|
||||
@param Integer $margin (optional) code margin (silent zone) in 'virtual' pixels
|
||||
@param Boolean $autoInclude (optional) if __true__, required qrcanvas.js lib will be included (only once)
|
||||
@return String containing JavaScript creating the code, Canvas element (when $elemId is __false__) and script tag with required lib (when $autoInclude is __true__ and not yet included)
|
||||
*/
|
||||
|
||||
public static function canvas($text, $elemId = false, $level = QR_ECLEVEL_L, $width = false, $size = false, $margin = 4, $autoInclude = false)
|
||||
{
|
||||
$html = '';
|
||||
$extra = '';
|
||||
|
||||
if ($autoInclude) {
|
||||
if (!self::$jscanvasincluded) {
|
||||
self::$jscanvasincluded = true;
|
||||
echo '<script type="text/javascript" src="qrcanvas.js"></script>';
|
||||
}
|
||||
}
|
||||
|
||||
$enc = QRencode::factory($level, 1, 0);
|
||||
$tab_src = $enc->encode($text, false);
|
||||
$area = new QRcanvasOutput($tab_src);
|
||||
$area->detectGroups();
|
||||
$area->detectAreas();
|
||||
|
||||
if ($elemId === false) {
|
||||
$elemId = 'qrcode-'.md5(mt_rand(1000,1000000).'.'.mt_rand(1000,1000000).'.'.mt_rand(1000,1000000).'.'.mt_rand(1000,1000000));
|
||||
|
||||
if ($width == false) {
|
||||
if (($size !== false) && ($size > 0)) {
|
||||
$width = ($area->getWidth()+(2*$margin)) * $size;
|
||||
} else {
|
||||
$width = ($area->getWidth()+(2*$margin)) * 4;
|
||||
}
|
||||
}
|
||||
|
||||
$html .= '<canvas id="'.$elemId.'" width="'.$width.'" height="'.$width.'">Your browser does not support CANVAS tag! Please upgrade to modern version of FireFox, Opera, Chrome or Safari/Webkit based browser</canvas>';
|
||||
}
|
||||
|
||||
if ($width !== false) {
|
||||
$extra .= ', '.$width.', '.$width;
|
||||
}
|
||||
|
||||
if ($margin !== false) {
|
||||
$extra .= ', '.$margin.', '.$margin;
|
||||
}
|
||||
|
||||
$html .= '<script>if(eval("typeof "+\'QRdrawCode\'+"==\'function\'")){QRdrawCode(QRdecompactOps(\''.$area->getCanvasOps().'\')'."\n".', \''.$elemId.'\', '.$area->getWidth().' '.$extra.');}else{alert(\'Please include qrcanvas.js!\');}</script>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
Creates SVG with QR-Code.
|
||||
Simple helper function to create QR-Code SVG with one static call.
|
||||
@param String $text text string to encode
|
||||
@param Boolean $elemId (optional) target SVG tag id attribute, if __false__ SVG tag with auto id will be created
|
||||
@param String $outfile (optional) output file name, when __false__ file is not saved
|
||||
@param Integer $level (optional) error correction level __QR_ECLEVEL_L__, __QR_ECLEVEL_M__, __QR_ECLEVEL_Q__ or __QR_ECLEVEL_H__
|
||||
@param Integer $width (optional) SVG element width (sam as height)
|
||||
@param Integer $size (optional) pixel size, multiplier for each 'virtual' pixel
|
||||
@param Integer $margin (optional) code margin (silent zone) in 'virtual' pixels
|
||||
@param Boolean $compress (optional) if __true__, compressed SVGZ (instead plaintext SVG) is saved to file
|
||||
@return String containing SVG tag
|
||||
*/
|
||||
|
||||
public static function svg($text, $elemId = false, $outFile = false, $level = QR_ECLEVEL_L, $width = false, $size = false, $margin = 4, $compress = false)
|
||||
{
|
||||
$enc = QRencode::factory($level, 1, 0);
|
||||
$tab_src = $enc->encode($text, false);
|
||||
$area = new QRsvgOutput($tab_src);
|
||||
$area->detectGroups();
|
||||
$area->detectAreas();
|
||||
|
||||
if ($elemId === false) {
|
||||
$elemId = 'qrcode-'.md5(mt_rand(1000,1000000).'.'.mt_rand(1000,1000000).'.'.mt_rand(1000,1000000).'.'.mt_rand(1000,1000000));
|
||||
|
||||
if ($width == false) {
|
||||
if (($size !== false) && ($size > 0)) {
|
||||
$width = ($area->getWidth()+(2*$margin)) * $size;
|
||||
} else {
|
||||
$width = ($area->getWidth()+(2*$margin)) * 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$svg = '<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
version="1.1"
|
||||
baseProfile="full"
|
||||
viewBox="'.(-$margin).' '.(-$margin).' '.($area->getWidth()+($margin*2)).' '.($area->getWidth()+($margin*2)).'"
|
||||
width="'.$width.'"
|
||||
height="'.$width.'"
|
||||
id="'.$elemId.'">'."\n";
|
||||
|
||||
$svg .= $area->getRawSvg().'</svg>';
|
||||
|
||||
if ($outFile !== false) {
|
||||
$xmlPreamble = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'."\n";
|
||||
$svgContent = $xmlPreamble.$svg;
|
||||
|
||||
if ($compress === true) {
|
||||
file_put_contents($outFile, gzencode($svgContent));
|
||||
} else {
|
||||
file_put_contents($outFile, $svgContent);
|
||||
}
|
||||
}
|
||||
|
||||
return $svg;
|
||||
}
|
||||
}
|
||||
|
||||
//##########################################################################
|
||||
/** Fills frame with data.
|
||||
Each empty frame consist of markers, timing symbols and format configuration.
|
||||
Remaining place is place for data, and should be filled according to QR Code spec.
|
||||
*/
|
||||
class QRframeFiller {
|
||||
|
||||
public $width; ///< __Integer__ Frame width
|
||||
public $frame; ///< __Array__ Frame itself
|
||||
public $x; ///< __Integer__ current X position
|
||||
public $y; ///< __Integer__ current Y position
|
||||
public $dir; ///< __Integer__ direction
|
||||
public $bit; ///< __Integer__ bit
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Frame filler Constructor.
|
||||
@param Integer $width frame size
|
||||
@param Array $frame Frame array
|
||||
*/
|
||||
public function __construct($width, &$frame)
|
||||
{
|
||||
$this->width = $width;
|
||||
$this->frame = $frame;
|
||||
$this->x = $width - 1;
|
||||
$this->y = $width - 1;
|
||||
$this->dir = -1;
|
||||
$this->bit = -1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Sets frame code at given position.
|
||||
@param Array $at position, map containing __x__ and __y__ coordinates
|
||||
@param Integer $val value to set
|
||||
*/
|
||||
public function setFrameAt($at, $val)
|
||||
{
|
||||
$this->frame[$at['y']][$at['x']] = chr($val);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Gets frame code from given position.
|
||||
@param Array $at position, map containing __x__ and __y__ coordinates
|
||||
@return Integer value at requested position
|
||||
*/
|
||||
public function getFrameAt($at)
|
||||
{
|
||||
return ord($this->frame[$at['y']][$at['x']]);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Proceed to next code point. */
|
||||
public function next()
|
||||
{
|
||||
do {
|
||||
|
||||
if($this->bit == -1) {
|
||||
$this->bit = 0;
|
||||
return array('x'=>$this->x, 'y'=>$this->y);
|
||||
}
|
||||
|
||||
$x = $this->x;
|
||||
$y = $this->y;
|
||||
$w = $this->width;
|
||||
|
||||
if($this->bit == 0) {
|
||||
$x--;
|
||||
$this->bit++;
|
||||
} else {
|
||||
$x++;
|
||||
$y += $this->dir;
|
||||
$this->bit--;
|
||||
}
|
||||
|
||||
if($this->dir < 0) {
|
||||
if($y < 0) {
|
||||
$y = 0;
|
||||
$x -= 2;
|
||||
$this->dir = 1;
|
||||
if($x == 6) {
|
||||
$x--;
|
||||
$y = 9;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if($y == $w) {
|
||||
$y = $w - 1;
|
||||
$x -= 2;
|
||||
$this->dir = -1;
|
||||
if($x == 6) {
|
||||
$x--;
|
||||
$y -= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
if($x < 0 || $y < 0) return null;
|
||||
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
|
||||
} while(ord($this->frame[$y][$x]) & 0x80);
|
||||
|
||||
return array('x'=>$x, 'y'=>$y);
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
//##########################################################################
|
||||
/** QR Code encoder.
|
||||
Encoder is used by QRCode to create simple static code generators. */
|
||||
class QRencode {
|
||||
|
||||
public $casesensitive = true; ///< __Boolean__ does input stream id case sensitive, if not encoder may use more optimal charsets
|
||||
public $eightbit = false; ///< __Boolean__ does input stream is 8 bit
|
||||
|
||||
public $version = 0; ///< __Integer__ code version (total size) if __0__ - will be auto-detected
|
||||
public $size = 3; ///< __Integer__ pixel zoom factor, multiplier to map virtual code pixels to image output pixels
|
||||
public $margin = 4; ///< __Integer__ margin (silent zone) size, in code pixels
|
||||
|
||||
public $structured = 0; ///< Structured QR codes. Not supported.
|
||||
|
||||
public $level = QR_ECLEVEL_L; ///< __Integer__ error correction level __QR_ECLEVEL_L__, __QR_ECLEVEL_M__, __QR_ECLEVEL_Q__ or __QR_ECLEVEL_H__
|
||||
public $hint = QR_MODE_8; ///< __Integer__ encoding hint, __QR_MODE_8__ or __QR_MODE_KANJI__, Because Kanji encoding is kind of 8 bit encoding we need to hint encoder to use Kanji mode explicite. (otherwise it may try to encode it as plain 8 bit stream)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Encoder instances factory.
|
||||
@param Integer $level error correction level __QR_ECLEVEL_L__, __QR_ECLEVEL_M__, __QR_ECLEVEL_Q__ or __QR_ECLEVEL_H__
|
||||
@param Integer $size pixel zoom factor, multiplier to map virtual code pixels to image output pixels
|
||||
@param Integer $margin margin (silent zone) size, in code pixels
|
||||
@return builded QRencode instance
|
||||
*/
|
||||
public static function factory($level = QR_ECLEVEL_L, $size = 3, $margin = 4)
|
||||
{
|
||||
$enc = new QRencode();
|
||||
$enc->size = $size;
|
||||
$enc->margin = $margin;
|
||||
|
||||
switch ($level.'') {
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
$enc->level = $level;
|
||||
break;
|
||||
case 'l':
|
||||
case 'L':
|
||||
$enc->level = QR_ECLEVEL_L;
|
||||
break;
|
||||
case 'm':
|
||||
case 'M':
|
||||
$enc->level = QR_ECLEVEL_M;
|
||||
break;
|
||||
case 'q':
|
||||
case 'Q':
|
||||
$enc->level = QR_ECLEVEL_Q;
|
||||
break;
|
||||
case 'h':
|
||||
case 'H':
|
||||
$enc->level = QR_ECLEVEL_H;
|
||||
break;
|
||||
}
|
||||
|
||||
return $enc;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Encodes input into Raw code table.
|
||||
@param String $intext input text
|
||||
@param Boolean $notused (optional, not used) placeholder for similar outfile parameter
|
||||
@return __Array__ Raw code frame
|
||||
*/
|
||||
public function encodeRAW($intext, $notused = false)
|
||||
{
|
||||
$code = new QRcode();
|
||||
|
||||
if($this->eightbit) {
|
||||
$code->encodeString8bit($intext, $this->version, $this->level);
|
||||
} else {
|
||||
$code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive);
|
||||
}
|
||||
|
||||
return $code->data;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Encodes input into binary code table.
|
||||
@param String $intext input text
|
||||
@param String $outfile (optional) output file to save code table, if __false__ file will be not saved
|
||||
@return __Array__ binary code frame
|
||||
*/
|
||||
public function encode($intext, $outfile = false)
|
||||
{
|
||||
$code = new QRcode();
|
||||
|
||||
if($this->eightbit) {
|
||||
$code->encodeString8bit($intext, $this->version, $this->level);
|
||||
} else {
|
||||
$code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive);
|
||||
}
|
||||
|
||||
QRtools::markTime('after_encode');
|
||||
|
||||
$binarized = QRtools::binarize($code->data);
|
||||
if ($outfile!== false) {
|
||||
file_put_contents($outfile, join("\n", $binarized));
|
||||
}
|
||||
|
||||
return $binarized;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Encodes input into PNG image.
|
||||
@param String $intext input text
|
||||
@param String $outfile (optional) output file name, if __false__ outputs to browser with required headers
|
||||
@param Boolean $saveandprint (optional) if __true__ code is outputed to browser and saved to file, otherwise only saved to file. It is effective only if $outfile is specified.
|
||||
*/
|
||||
public function encodePNG($intext, $outfile = false, $saveandprint=false)
|
||||
{
|
||||
try {
|
||||
|
||||
ob_start();
|
||||
$tab = $this->encode($intext);
|
||||
$err = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
if ($err != '')
|
||||
QRtools::log($outfile, $err);
|
||||
|
||||
$maxSize = (int)(QR_PNG_MAXIMUM_SIZE / (count($tab)+2*$this->margin));
|
||||
|
||||
QRimage::png($tab, $outfile, min(max(1, $this->size), $maxSize), $this->margin,$saveandprint);
|
||||
|
||||
} catch (Exception $e) {
|
||||
|
||||
QRtools::log($outfile, $e->getMessage());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @}*/
|
||||
131
public/phpqrcode/qrimage.php
Executable file
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
/*
|
||||
* PHP QR Code encoder
|
||||
*
|
||||
* Image output of code using GD2
|
||||
*
|
||||
* PHP QR Code is distributed under LGPL 3
|
||||
* Copyright (C) 2010-2013 Dominik Dzienia <deltalab at poczta dot fm>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
define('QR_IMAGE', true);
|
||||
|
||||
|
||||
/** @defgroup OutputGroup Standard API Output
|
||||
Provide simple Raster & Vector output */
|
||||
|
||||
/** @addtogroup OutputGroup */
|
||||
/** @{ */
|
||||
|
||||
/** Image rendering helper.
|
||||
Uses GD2 image to render QR Code into image file */
|
||||
class QRimage {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
Creates PNG image.
|
||||
@param Array $frame frame containing code
|
||||
@param String $filename (optional) output file name, if __false__ outputs to browser with required headers
|
||||
@param Integer $pixelPerPoint (optional) pixel size, multiplier for each 'virtual' pixel
|
||||
@param Integer $outerFrame (optional) code margin (silent zone) in 'virtual' pixels
|
||||
@param Boolean $saveandprint (optional) if __true__ code is outputed to browser and saved to file, otherwise only saved to file. It is effective only if $outfile is specified.
|
||||
*/
|
||||
|
||||
public static function png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4,$saveandprint=FALSE)
|
||||
{
|
||||
$image = self::image($frame, $pixelPerPoint, $outerFrame);
|
||||
|
||||
if ($filename === false) {
|
||||
Header("Content-type: image/png");
|
||||
ImagePng($image);
|
||||
} else {
|
||||
if($saveandprint===TRUE){
|
||||
ImagePng($image, $filename);
|
||||
header("Content-type: image/png");
|
||||
ImagePng($image);
|
||||
}else{
|
||||
ImagePng($image, $filename);
|
||||
}
|
||||
}
|
||||
|
||||
ImageDestroy($image);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
Creates JPEG image.
|
||||
@param Array $frame frame containing code
|
||||
@param String $filename (optional) output file name, if __false__ outputs to browser with required headers
|
||||
@param Integer $pixelPerPoint (optional) pixel size, multiplier for each 'virtual' pixel
|
||||
@param Integer $outerFrame (optional) code margin (silent zone) in 'virtual' pixels
|
||||
@param Integer $q (optional) JPEG compression level (__0__ .. __100__)
|
||||
*/
|
||||
|
||||
public static function jpg($frame, $filename = false, $pixelPerPoint = 8, $outerFrame = 4, $q = 85)
|
||||
{
|
||||
$image = self::image($frame, $pixelPerPoint, $outerFrame);
|
||||
|
||||
if ($filename === false) {
|
||||
Header("Content-type: image/jpeg");
|
||||
ImageJpeg($image, null, $q);
|
||||
} else {
|
||||
ImageJpeg($image, $filename, $q);
|
||||
}
|
||||
|
||||
ImageDestroy($image);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/**
|
||||
Creates generic GD2 image object
|
||||
@param Array $frame frame containing code
|
||||
@param Integer $pixelPerPoint (optional) pixel size, multiplier for each 'virtual' pixel
|
||||
@param Integer $outerFrame (optional) code margin (silent zone) in 'virtual' pixels
|
||||
@return __Resource__ GD2 image resource (remember to ImageDestroy it!)
|
||||
*/
|
||||
public static function image($frame, $pixelPerPoint = 4, $outerFrame = 4)
|
||||
{
|
||||
$h = count($frame);
|
||||
$w = strlen($frame[0]);
|
||||
|
||||
$imgW = $w + 2*$outerFrame;
|
||||
$imgH = $h + 2*$outerFrame;
|
||||
|
||||
$base_image =ImageCreate($imgW, $imgH);
|
||||
|
||||
$col[0] = ImageColorAllocate($base_image,255,255,255);
|
||||
$col[1] = ImageColorAllocate($base_image,0,0,0);
|
||||
|
||||
imagefill($base_image, 0, 0, $col[0]);
|
||||
|
||||
for($y=0; $y<$h; $y++) {
|
||||
for($x=0; $x<$w; $x++) {
|
||||
if ($frame[$y][$x] == '1') {
|
||||
ImageSetPixel($base_image,$x+$outerFrame,$y+$outerFrame,$col[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$target_image =ImageCreate($imgW * $pixelPerPoint, $imgH * $pixelPerPoint);
|
||||
ImageCopyResized($target_image, $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH);
|
||||
ImageDestroy($base_image);
|
||||
|
||||
return $target_image;
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
731
public/phpqrcode/qrinput.php
Executable file
@@ -0,0 +1,731 @@
|
||||
<?php
|
||||
/*
|
||||
* PHP QR Code encoder
|
||||
*
|
||||
* Input encoding class
|
||||
*
|
||||
* Based on libqrencode C library distributed under LGPL 2.1
|
||||
* Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* PHP QR Code is distributed under LGPL 3
|
||||
* Copyright (C) 2010-2013 Dominik Dzienia <deltalab at poczta dot fm>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
define('STRUCTURE_HEADER_BITS', 20);
|
||||
define('MAX_STRUCTURED_SYMBOLS', 16);
|
||||
|
||||
/** @addtogroup CoreGroup */
|
||||
/** @{ */
|
||||
|
||||
class QRinputItem {
|
||||
|
||||
public $mode;
|
||||
public $size;
|
||||
public $data;
|
||||
public $bstream;
|
||||
|
||||
public function __construct($mode, $size, $data, $bstream = null)
|
||||
{
|
||||
$setData = array_slice($data, 0, $size);
|
||||
|
||||
if (count($setData) < $size) {
|
||||
$setData = array_merge($setData, array_fill(0,$size-count($setData),0));
|
||||
}
|
||||
|
||||
if(!QRinput::check($mode, $size, $setData)) {
|
||||
throw new Exception('Error m:'.$mode.',s:'.$size.',d:'.join(',',$setData));
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->mode = $mode;
|
||||
$this->size = $size;
|
||||
$this->data = $setData;
|
||||
$this->bstream = $bstream;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function encodeModeNum($version)
|
||||
{
|
||||
try {
|
||||
|
||||
$words = (int)($this->size / 3);
|
||||
$bs = new QRbitstream();
|
||||
|
||||
$val = 0x1;
|
||||
$bs->appendNum(4, $val);
|
||||
$bs->appendNum(QRspec::lengthIndicator(QR_MODE_NUM, $version), $this->size);
|
||||
|
||||
for($i=0; $i<$words; $i++) {
|
||||
$val = (ord($this->data[$i*3 ]) - ord('0')) * 100;
|
||||
$val += (ord($this->data[$i*3+1]) - ord('0')) * 10;
|
||||
$val += (ord($this->data[$i*3+2]) - ord('0'));
|
||||
$bs->appendNum(10, $val);
|
||||
}
|
||||
|
||||
if($this->size - $words * 3 == 1) {
|
||||
$val = ord($this->data[$words*3]) - ord('0');
|
||||
$bs->appendNum(4, $val);
|
||||
} else if($this->size - $words * 3 == 2) {
|
||||
$val = (ord($this->data[$words*3 ]) - ord('0')) * 10;
|
||||
$val += (ord($this->data[$words*3+1]) - ord('0'));
|
||||
$bs->appendNum(7, $val);
|
||||
}
|
||||
|
||||
$this->bstream = $bs;
|
||||
return 0;
|
||||
|
||||
} catch (Exception $e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function encodeModeAn($version)
|
||||
{
|
||||
try {
|
||||
$words = (int)($this->size / 2);
|
||||
$bs = new QRbitstream();
|
||||
|
||||
$bs->appendNum(4, 0x02);
|
||||
$bs->appendNum(QRspec::lengthIndicator(QR_MODE_AN, $version), $this->size);
|
||||
|
||||
for($i=0; $i<$words; $i++) {
|
||||
$val = (int)QRinput::lookAnTable(ord($this->data[$i*2 ])) * 45;
|
||||
$val += (int)QRinput::lookAnTable(ord($this->data[$i*2+1]));
|
||||
|
||||
$bs->appendNum(11, $val);
|
||||
}
|
||||
|
||||
if($this->size & 1) {
|
||||
$val = QRinput::lookAnTable(ord($this->data[$words * 2]));
|
||||
$bs->appendNum(6, $val);
|
||||
}
|
||||
|
||||
$this->bstream = $bs;
|
||||
return 0;
|
||||
|
||||
} catch (Exception $e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function encodeMode8($version)
|
||||
{
|
||||
try {
|
||||
$bs = new QRbitstream();
|
||||
|
||||
$bs->appendNum(4, 0x4);
|
||||
$bs->appendNum(QRspec::lengthIndicator(QR_MODE_8, $version), $this->size);
|
||||
|
||||
for($i=0; $i<$this->size; $i++) {
|
||||
$bs->appendNum(8, ord($this->data[$i]));
|
||||
}
|
||||
|
||||
$this->bstream = $bs;
|
||||
return 0;
|
||||
|
||||
} catch (Exception $e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function encodeModeKanji($version)
|
||||
{
|
||||
try {
|
||||
|
||||
$bs = new QRbitrtream();
|
||||
|
||||
$bs->appendNum(4, 0x8);
|
||||
$bs->appendNum(QRspec::lengthIndicator(QR_MODE_KANJI, $version), (int)($this->size / 2));
|
||||
|
||||
for($i=0; $i<$this->size; $i+=2) {
|
||||
$val = (ord($this->data[$i]) << 8) | ord($this->data[$i+1]);
|
||||
if($val <= 0x9ffc) {
|
||||
$val -= 0x8140;
|
||||
} else {
|
||||
$val -= 0xc140;
|
||||
}
|
||||
|
||||
$h = ($val >> 8) * 0xc0;
|
||||
$val = ($val & 0xff) + $h;
|
||||
|
||||
$bs->appendNum(13, $val);
|
||||
}
|
||||
|
||||
$this->bstream = $bs;
|
||||
return 0;
|
||||
|
||||
} catch (Exception $e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function encodeModeStructure()
|
||||
{
|
||||
try {
|
||||
$bs = new QRbitstream();
|
||||
|
||||
$bs->appendNum(4, 0x03);
|
||||
$bs->appendNum(4, ord($this->data[1]) - 1);
|
||||
$bs->appendNum(4, ord($this->data[0]) - 1);
|
||||
$bs->appendNum(8, ord($this->data[2]));
|
||||
|
||||
$this->bstream = $bs;
|
||||
return 0;
|
||||
|
||||
} catch (Exception $e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function estimateBitStreamSizeOfEntry($version)
|
||||
{
|
||||
$bits = 0;
|
||||
|
||||
if($version == 0)
|
||||
$version = 1;
|
||||
|
||||
switch($this->mode) {
|
||||
case QR_MODE_NUM: $bits = QRinput::estimateBitsModeNum($this->size); break;
|
||||
case QR_MODE_AN: $bits = QRinput::estimateBitsModeAn($this->size); break;
|
||||
case QR_MODE_8: $bits = QRinput::estimateBitsMode8($this->size); break;
|
||||
case QR_MODE_KANJI: $bits = QRinput::estimateBitsModeKanji($this->size);break;
|
||||
case QR_MODE_STRUCTURE: return STRUCTURE_HEADER_BITS;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
$l = QRspec::lengthIndicator($this->mode, $version);
|
||||
$m = 1 << $l;
|
||||
$num = (int)(($this->size + $m - 1) / $m);
|
||||
|
||||
$bits += $num * (4 + $l);
|
||||
|
||||
return $bits;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function encodeBitStream($version)
|
||||
{
|
||||
try {
|
||||
|
||||
unset($this->bstream);
|
||||
$words = QRspec::maximumWords($this->mode, $version);
|
||||
|
||||
if($this->size > $words) {
|
||||
|
||||
$st1 = new QRinputItem($this->mode, $words, $this->data);
|
||||
$st2 = new QRinputItem($this->mode, $this->size - $words, array_slice($this->data, $words));
|
||||
|
||||
$st1->encodeBitStream($version);
|
||||
$st2->encodeBitStream($version);
|
||||
|
||||
$this->bstream = new QRbitstream();
|
||||
$this->bstream->append($st1->bstream);
|
||||
$this->bstream->append($st2->bstream);
|
||||
|
||||
unset($st1);
|
||||
unset($st2);
|
||||
|
||||
} else {
|
||||
|
||||
$ret = 0;
|
||||
|
||||
switch($this->mode) {
|
||||
case QR_MODE_NUM: $ret = $this->encodeModeNum($version); break;
|
||||
case QR_MODE_AN: $ret = $this->encodeModeAn($version); break;
|
||||
case QR_MODE_8: $ret = $this->encodeMode8($version); break;
|
||||
case QR_MODE_KANJI: $ret = $this->encodeModeKanji($version);break;
|
||||
case QR_MODE_STRUCTURE: $ret = $this->encodeModeStructure(); break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if($ret < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return $this->bstream->size();
|
||||
|
||||
} catch (Exception $e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//##########################################################################
|
||||
|
||||
class QRinput {
|
||||
|
||||
public $items;
|
||||
|
||||
private $version;
|
||||
private $level;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function __construct($version = 0, $level = QR_ECLEVEL_L)
|
||||
{
|
||||
if ($version < 0 || $version > QRSPEC_VERSION_MAX || $level > QR_ECLEVEL_H) {
|
||||
throw new Exception('Invalid version no');
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$this->version = $version;
|
||||
$this->level = $level;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function getVersion()
|
||||
{
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function setVersion($version)
|
||||
{
|
||||
if($version < 0 || $version > QRSPEC_VERSION_MAX) {
|
||||
throw new Exception('Invalid version no');
|
||||
return -1;
|
||||
}
|
||||
|
||||
$this->version = $version;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function getErrorCorrectionLevel()
|
||||
{
|
||||
return $this->level;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function setErrorCorrectionLevel($level)
|
||||
{
|
||||
if($level > QR_ECLEVEL_H) {
|
||||
throw new Exception('Invalid ECLEVEL');
|
||||
return -1;
|
||||
}
|
||||
|
||||
$this->level = $level;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function appendEntry(QRinputItem $entry)
|
||||
{
|
||||
$this->items[] = $entry;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function append($mode, $size, $data)
|
||||
{
|
||||
try {
|
||||
$entry = new QRinputItem($mode, $size, $data);
|
||||
$this->items[] = $entry;
|
||||
return 0;
|
||||
} catch (Exception $e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
public function insertStructuredAppendHeader($size, $index, $parity)
|
||||
{
|
||||
if( $size > MAX_STRUCTURED_SYMBOLS ) {
|
||||
throw new Exception('insertStructuredAppendHeader wrong size');
|
||||
}
|
||||
|
||||
if( $index <= 0 || $index > MAX_STRUCTURED_SYMBOLS ) {
|
||||
throw new Exception('insertStructuredAppendHeader wrong index');
|
||||
}
|
||||
|
||||
$buf = array($size, $index, $parity);
|
||||
|
||||
try {
|
||||
$entry = new QRinputItem(QR_MODE_STRUCTURE, 3, buf);
|
||||
array_unshift($this->items, $entry);
|
||||
return 0;
|
||||
} catch (Exception $e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function calcParity()
|
||||
{
|
||||
$parity = 0;
|
||||
|
||||
foreach($this->items as $item) {
|
||||
if($item->mode != QR_MODE_STRUCTURE) {
|
||||
for($i=$item->size-1; $i>=0; $i--) {
|
||||
$parity ^= $item->data[$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $parity;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function checkModeNum($size, $data)
|
||||
{
|
||||
for($i=0; $i<$size; $i++) {
|
||||
if((ord($data[$i]) < ord('0')) || (ord($data[$i]) > ord('9'))){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function estimateBitsModeNum($size)
|
||||
{
|
||||
$w = (int)$size / 3;
|
||||
$bits = $w * 10;
|
||||
|
||||
switch($size - $w * 3) {
|
||||
case 1:
|
||||
$bits += 4;
|
||||
break;
|
||||
case 2:
|
||||
$bits += 7;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return $bits;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static $anTable = array(
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1,
|
||||
-1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||
);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function lookAnTable($c)
|
||||
{
|
||||
return (($c > 127)?-1:self::$anTable[$c]);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function checkModeAn($size, $data)
|
||||
{
|
||||
for($i=0; $i<$size; $i++) {
|
||||
if (self::lookAnTable(ord($data[$i])) == -1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function estimateBitsModeAn($size)
|
||||
{
|
||||
$w = (int)($size / 2);
|
||||
$bits = $w * 11;
|
||||
|
||||
if($size & 1) {
|
||||
$bits += 6;
|
||||
}
|
||||
|
||||
return $bits;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function estimateBitsMode8($size)
|
||||
{
|
||||
return $size * 8;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function estimateBitsModeKanji($size)
|
||||
{
|
||||
return (int)(($size / 2) * 13);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function checkModeKanji($size, $data)
|
||||
{
|
||||
if($size & 1)
|
||||
return false;
|
||||
|
||||
for($i=0; $i<$size; $i+=2) {
|
||||
$val = (ord($data[$i]) << 8) | ord($data[$i+1]);
|
||||
if( $val < 0x8140
|
||||
|| ($val > 0x9ffc && $val < 0xe040)
|
||||
|| $val > 0xebbf) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Validation
|
||||
**********************************************************************/
|
||||
|
||||
public static function check($mode, $size, $data)
|
||||
{
|
||||
if($size <= 0)
|
||||
return false;
|
||||
|
||||
switch($mode) {
|
||||
case QR_MODE_NUM: return self::checkModeNum($size, $data); break;
|
||||
case QR_MODE_AN: return self::checkModeAn($size, $data); break;
|
||||
case QR_MODE_KANJI: return self::checkModeKanji($size, $data); break;
|
||||
case QR_MODE_8: return true; break;
|
||||
case QR_MODE_STRUCTURE: return true; break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function estimateBitStreamSize($version)
|
||||
{
|
||||
$bits = 0;
|
||||
|
||||
foreach($this->items as $item) {
|
||||
$bits += $item->estimateBitStreamSizeOfEntry($version);
|
||||
}
|
||||
|
||||
return $bits;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function estimateVersion()
|
||||
{
|
||||
$version = 0;
|
||||
$prev = 0;
|
||||
do {
|
||||
$prev = $version;
|
||||
$bits = $this->estimateBitStreamSize($prev);
|
||||
$version = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level);
|
||||
if ($version < 0) {
|
||||
return -1;
|
||||
}
|
||||
} while ($version > $prev);
|
||||
|
||||
return $version;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function lengthOfCode($mode, $version, $bits)
|
||||
{
|
||||
$payload = $bits - 4 - QRspec::lengthIndicator($mode, $version);
|
||||
switch($mode) {
|
||||
case QR_MODE_NUM:
|
||||
$chunks = (int)($payload / 10);
|
||||
$remain = $payload - $chunks * 10;
|
||||
$size = $chunks * 3;
|
||||
if($remain >= 7) {
|
||||
$size += 2;
|
||||
} else if($remain >= 4) {
|
||||
$size += 1;
|
||||
}
|
||||
break;
|
||||
case QR_MODE_AN:
|
||||
$chunks = (int)($payload / 11);
|
||||
$remain = $payload - $chunks * 11;
|
||||
$size = $chunks * 2;
|
||||
if($remain >= 6)
|
||||
$size++;
|
||||
break;
|
||||
case QR_MODE_8:
|
||||
$size = (int)($payload / 8);
|
||||
break;
|
||||
case QR_MODE_KANJI:
|
||||
$size = (int)(($payload / 13) * 2);
|
||||
break;
|
||||
case QR_MODE_STRUCTURE:
|
||||
$size = (int)($payload / 8);
|
||||
break;
|
||||
default:
|
||||
$size = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
$maxsize = QRspec::maximumWords($mode, $version);
|
||||
if($size < 0) $size = 0;
|
||||
if($size > $maxsize) $size = $maxsize;
|
||||
|
||||
return $size;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function createBitStream()
|
||||
{
|
||||
$total = 0;
|
||||
|
||||
foreach($this->items as $item) {
|
||||
$bits = $item->encodeBitStream($this->version);
|
||||
|
||||
if($bits < 0)
|
||||
return -1;
|
||||
|
||||
$total += $bits;
|
||||
}
|
||||
|
||||
return $total;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function convertData()
|
||||
{
|
||||
$ver = $this->estimateVersion();
|
||||
if($ver > $this->getVersion()) {
|
||||
$this->setVersion($ver);
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
$bits = $this->createBitStream();
|
||||
|
||||
if($bits < 0)
|
||||
return -1;
|
||||
|
||||
$ver = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level);
|
||||
if($ver < 0) {
|
||||
throw new Exception('WRONG VERSION');
|
||||
return -1;
|
||||
} else if($ver > $this->getVersion()) {
|
||||
$this->setVersion($ver);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function appendPaddingBit(&$bstream)
|
||||
{
|
||||
$bits = $bstream->size();
|
||||
$maxwords = QRspec::getDataLength($this->version, $this->level);
|
||||
$maxbits = $maxwords * 8;
|
||||
|
||||
if ($maxbits == $bits) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($maxbits - $bits < 5) {
|
||||
return $bstream->appendNum($maxbits - $bits, 0);
|
||||
}
|
||||
|
||||
$bits += 4;
|
||||
$words = (int)(($bits + 7) / 8);
|
||||
|
||||
$padding = new QRbitstream();
|
||||
$ret = $padding->appendNum($words * 8 - $bits + 4, 0);
|
||||
|
||||
if($ret < 0)
|
||||
return $ret;
|
||||
|
||||
$padlen = $maxwords - $words;
|
||||
|
||||
if($padlen > 0) {
|
||||
|
||||
$padbuf = array();
|
||||
for($i=0; $i<$padlen; $i++) {
|
||||
$padbuf[$i] = ($i&1)?0x11:0xec;
|
||||
}
|
||||
|
||||
$ret = $padding->appendBytes($padlen, $padbuf);
|
||||
|
||||
if($ret < 0)
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
$ret = $bstream->append($padding);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function mergeBitStream()
|
||||
{
|
||||
if($this->convertData() < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$bstream = new QRbitstream();
|
||||
|
||||
foreach($this->items as $item) {
|
||||
$ret = $bstream->append($item->bstream);
|
||||
if($ret < 0) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return $bstream;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function getBitStream()
|
||||
{
|
||||
|
||||
$bstream = $this->mergeBitStream();
|
||||
|
||||
if($bstream == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$ret = $this->appendPaddingBit($bstream);
|
||||
if($ret < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $bstream;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function getByteStream()
|
||||
{
|
||||
$bstream = $this->getBitStream();
|
||||
if($bstream == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $bstream->toByte();
|
||||
}
|
||||
}
|
||||
|
||||
/** @}*/
|
||||
49
public/phpqrcode/qrlib.php
Executable file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/*
|
||||
* PHP QR Code encoder
|
||||
*
|
||||
* Root library file, prepares environment and includes dependencies
|
||||
*
|
||||
* Based on libqrencode C library distributed under LGPL 2.1
|
||||
* Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* PHP QR Code is distributed under LGPL 3
|
||||
* Copyright (C) 2010-2013 Dominik Dzienia <deltalab at poczta dot fm>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
$QR_BASEDIR = dirname(__FILE__).DIRECTORY_SEPARATOR;
|
||||
|
||||
// Required libs
|
||||
|
||||
include $QR_BASEDIR."qrconst.php";
|
||||
include $QR_BASEDIR."qrconfig.php";
|
||||
include $QR_BASEDIR."qrtools.php";
|
||||
include $QR_BASEDIR."qrspec.php";
|
||||
include $QR_BASEDIR."qrimage.php";
|
||||
include $QR_BASEDIR."qrinput.php";
|
||||
include $QR_BASEDIR."qrbitstream.php";
|
||||
include $QR_BASEDIR."qrsplit.php";
|
||||
include $QR_BASEDIR."qrrscode.php";
|
||||
include $QR_BASEDIR."qrmask.php";
|
||||
include $QR_BASEDIR."qrencode.php";
|
||||
|
||||
include $QR_BASEDIR."qrarea.php";
|
||||
include $QR_BASEDIR."qrcanvas.php";
|
||||
include $QR_BASEDIR."qrsvg.php";
|
||||
//
|
||||
|
||||
|
||||
335
public/phpqrcode/qrmask.php
Executable file
@@ -0,0 +1,335 @@
|
||||
<?php
|
||||
/*
|
||||
* PHP QR Code encoder
|
||||
*
|
||||
* Masking
|
||||
*
|
||||
* Based on libqrencode C library distributed under LGPL 2.1
|
||||
* Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* PHP QR Code is distributed under LGPL 3
|
||||
* Copyright (C) 2010-2013 Dominik Dzienia <deltalab at poczta dot fm>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
|
||||
define('N1', 3);
|
||||
define('N2', 3);
|
||||
define('N3', 40);
|
||||
define('N4', 10);
|
||||
|
||||
/** @addtogroup CoreGroup */
|
||||
/** @{ */
|
||||
|
||||
class QRmask {
|
||||
|
||||
public $runLength = array();
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function __construct()
|
||||
{
|
||||
$this->runLength = array_fill(0, QRSPEC_WIDTH_MAX + 1, 0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function writeFormatInformation($width, &$frame, $mask, $level)
|
||||
{
|
||||
$blacks = 0;
|
||||
$format = QRspec::getFormatInfo($mask, $level);
|
||||
|
||||
for($i=0; $i<8; $i++) {
|
||||
if($format & 1) {
|
||||
$blacks += 2;
|
||||
$v = 0x85;
|
||||
} else {
|
||||
$v = 0x84;
|
||||
}
|
||||
|
||||
$frame[8][$width - 1 - $i] = chr($v);
|
||||
if($i < 6) {
|
||||
$frame[$i][8] = chr($v);
|
||||
} else {
|
||||
$frame[$i + 1][8] = chr($v);
|
||||
}
|
||||
$format = $format >> 1;
|
||||
}
|
||||
|
||||
for($i=0; $i<7; $i++) {
|
||||
if($format & 1) {
|
||||
$blacks += 2;
|
||||
$v = 0x85;
|
||||
} else {
|
||||
$v = 0x84;
|
||||
}
|
||||
|
||||
$frame[$width - 7 + $i][8] = chr($v);
|
||||
if($i == 0) {
|
||||
$frame[8][7] = chr($v);
|
||||
} else {
|
||||
$frame[8][6 - $i] = chr($v);
|
||||
}
|
||||
|
||||
$format = $format >> 1;
|
||||
}
|
||||
|
||||
return $blacks;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function mask0($x, $y) { return ($x+$y)&1; }
|
||||
public function mask1($x, $y) { return ($y&1); }
|
||||
public function mask2($x, $y) { return ($x%3); }
|
||||
public function mask3($x, $y) { return ($x+$y)%3; }
|
||||
public function mask4($x, $y) { return (((int)($y/2))+((int)($x/3)))&1; }
|
||||
public function mask5($x, $y) { return (($x*$y)&1)+($x*$y)%3; }
|
||||
public function mask6($x, $y) { return ((($x*$y)&1)+($x*$y)%3)&1; }
|
||||
public function mask7($x, $y) { return ((($x*$y)%3)+(($x+$y)&1))&1; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
private function generateMaskNo($maskNo, $width, $frame)
|
||||
{
|
||||
$bitMask = array_fill(0, $width, array_fill(0, $width, 0));
|
||||
|
||||
for($y=0; $y<$width; $y++) {
|
||||
for($x=0; $x<$width; $x++) {
|
||||
if(ord($frame[$y][$x]) & 0x80) {
|
||||
$bitMask[$y][$x] = 0;
|
||||
} else {
|
||||
$maskFunc = call_user_func(array($this, 'mask'.$maskNo), $x, $y);
|
||||
$bitMask[$y][$x] = ($maskFunc == 0)?1:0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $bitMask;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function serial($bitFrame)
|
||||
{
|
||||
$codeArr = array();
|
||||
|
||||
foreach ($bitFrame as $line)
|
||||
$codeArr[] = join('', $line);
|
||||
|
||||
return gzcompress(join("\n", $codeArr), 9);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function unserial($code)
|
||||
{
|
||||
$codeArr = array();
|
||||
|
||||
$codeLines = explode("\n", gzuncompress($code));
|
||||
foreach ($codeLines as $line)
|
||||
$codeArr[] = str_split($line);
|
||||
|
||||
return $codeArr;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly = false)
|
||||
{
|
||||
$b = 0;
|
||||
$bitMask = array();
|
||||
|
||||
$fileName = QR_CACHE_DIR.'mask_'.$maskNo.DIRECTORY_SEPARATOR.'mask_'.$width.'_'.$maskNo.'.dat';
|
||||
|
||||
if (QR_CACHEABLE) {
|
||||
if (file_exists($fileName)) {
|
||||
$bitMask = self::unserial(file_get_contents($fileName));
|
||||
} else {
|
||||
$bitMask = $this->generateMaskNo($maskNo, $width, $s, $d);
|
||||
if (!file_exists(QR_CACHE_DIR.'mask_'.$maskNo))
|
||||
mkdir(QR_CACHE_DIR.'mask_'.$maskNo);
|
||||
file_put_contents($fileName, self::serial($bitMask));
|
||||
}
|
||||
} else {
|
||||
$bitMask = $this->generateMaskNo($maskNo, $width, $s, $d);
|
||||
}
|
||||
|
||||
if ($maskGenOnly)
|
||||
return;
|
||||
|
||||
$d = $s;
|
||||
|
||||
for($y=0; $y<$width; $y++) {
|
||||
for($x=0; $x<$width; $x++) {
|
||||
if($bitMask[$y][$x] == 1) {
|
||||
$d[$y][$x] = chr(ord($s[$y][$x]) ^ (int)$bitMask[$y][$x]);
|
||||
}
|
||||
$b += (int)(ord($d[$y][$x]) & 1);
|
||||
}
|
||||
}
|
||||
|
||||
return $b;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function makeMask($width, $frame, $maskNo, $level)
|
||||
{
|
||||
$masked = array_fill(0, $width, str_repeat("\0", $width));
|
||||
$this->makeMaskNo($maskNo, $width, $frame, $masked);
|
||||
$this->writeFormatInformation($width, $masked, $maskNo, $level);
|
||||
|
||||
return $masked;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function calcN1N3($length)
|
||||
{
|
||||
$demerit = 0;
|
||||
|
||||
for($i=0; $i<$length; $i++) {
|
||||
|
||||
if($this->runLength[$i] >= 5) {
|
||||
$demerit += (N1 + ($this->runLength[$i] - 5));
|
||||
}
|
||||
if($i & 1) {
|
||||
if(($i >= 3) && ($i < ($length-2)) && ($this->runLength[$i] % 3 == 0)) {
|
||||
$fact = (int)($this->runLength[$i] / 3);
|
||||
if(($this->runLength[$i-2] == $fact) &&
|
||||
($this->runLength[$i-1] == $fact) &&
|
||||
($this->runLength[$i+1] == $fact) &&
|
||||
($this->runLength[$i+2] == $fact)) {
|
||||
if(($this->runLength[$i-3] < 0) || ($this->runLength[$i-3] >= (4 * $fact))) {
|
||||
$demerit += N3;
|
||||
} else if((($i+3) >= $length) || ($this->runLength[$i+3] >= (4 * $fact))) {
|
||||
$demerit += N3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $demerit;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function evaluateSymbol($width, $frame)
|
||||
{
|
||||
$head = 0;
|
||||
$demerit = 0;
|
||||
|
||||
for($y=0; $y<$width; $y++) {
|
||||
$head = 0;
|
||||
$this->runLength[0] = 1;
|
||||
|
||||
$frameY = $frame[$y];
|
||||
|
||||
if ($y>0)
|
||||
$frameYM = $frame[$y-1];
|
||||
|
||||
for($x=0; $x<$width; $x++) {
|
||||
if(($x > 0) && ($y > 0)) {
|
||||
$b22 = ord($frameY[$x]) & ord($frameY[$x-1]) & ord($frameYM[$x]) & ord($frameYM[$x-1]);
|
||||
$w22 = ord($frameY[$x]) | ord($frameY[$x-1]) | ord($frameYM[$x]) | ord($frameYM[$x-1]);
|
||||
|
||||
if(($b22 | ($w22 ^ 1))&1) {
|
||||
$demerit += N2;
|
||||
}
|
||||
}
|
||||
if(($x == 0) && (ord($frameY[$x]) & 1)) {
|
||||
$this->runLength[0] = -1;
|
||||
$head = 1;
|
||||
$this->runLength[$head] = 1;
|
||||
} else if($x > 0) {
|
||||
if((ord($frameY[$x]) ^ ord($frameY[$x-1])) & 1) {
|
||||
$head++;
|
||||
$this->runLength[$head] = 1;
|
||||
} else {
|
||||
$this->runLength[$head]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$demerit += $this->calcN1N3($head+1);
|
||||
}
|
||||
|
||||
for($x=0; $x<$width; $x++) {
|
||||
$head = 0;
|
||||
$this->runLength[0] = 1;
|
||||
|
||||
for($y=0; $y<$width; $y++) {
|
||||
if($y == 0 && (ord($frame[$y][$x]) & 1)) {
|
||||
$this->runLength[0] = -1;
|
||||
$head = 1;
|
||||
$this->runLength[$head] = 1;
|
||||
} else if($y > 0) {
|
||||
if((ord($frame[$y][$x]) ^ ord($frame[$y-1][$x])) & 1) {
|
||||
$head++;
|
||||
$this->runLength[$head] = 1;
|
||||
} else {
|
||||
$this->runLength[$head]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$demerit += $this->calcN1N3($head+1);
|
||||
}
|
||||
|
||||
return $demerit;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function mask($width, $frame, $level)
|
||||
{
|
||||
$minDemerit = PHP_INT_MAX;
|
||||
$bestMaskNum = 0;
|
||||
$bestMask = array();
|
||||
|
||||
$checked_masks = array(0,1,2,3,4,5,6,7);
|
||||
|
||||
if (QR_FIND_FROM_RANDOM !== false) {
|
||||
|
||||
$howManuOut = 8-(QR_FIND_FROM_RANDOM % 9);
|
||||
for ($i = 0; $i < $howManuOut; $i++) {
|
||||
$remPos = rand (0, count($checked_masks)-1);
|
||||
unset($checked_masks[$remPos]);
|
||||
$checked_masks = array_values($checked_masks);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$bestMask = $frame;
|
||||
|
||||
foreach($checked_masks as $i) {
|
||||
$mask = array_fill(0, $width, str_repeat("\0", $width));
|
||||
|
||||
$demerit = 0;
|
||||
$blacks = 0;
|
||||
$blacks = $this->makeMaskNo($i, $width, $frame, $mask);
|
||||
$blacks += $this->writeFormatInformation($width, $mask, $i, $level);
|
||||
$blacks = (int)(100 * $blacks / ($width * $width));
|
||||
$demerit = (int)((int)(abs($blacks - 50) / 5) * N4);
|
||||
$demerit += $this->evaluateSymbol($width, $mask);
|
||||
|
||||
if($demerit < $minDemerit) {
|
||||
$minDemerit = $demerit;
|
||||
$bestMask = $mask;
|
||||
$bestMaskNum = $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $bestMask;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
}
|
||||
|
||||
/** @}*/
|
||||
251
public/phpqrcode/qrrscode.php
Executable file
@@ -0,0 +1,251 @@
|
||||
<?php
|
||||
/*
|
||||
* PHP QR Code encoder
|
||||
*
|
||||
* Reed-Solomon error correction support
|
||||
*
|
||||
* Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
|
||||
* (libfec is released under the GNU Lesser General Public License.)
|
||||
*
|
||||
* Based on libqrencode C library distributed under LGPL 2.1
|
||||
* Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* PHP QR Code is distributed under LGPL 3
|
||||
* Copyright (C) 2010-2013 Dominik Dzienia <deltalab at poczta dot fm>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @addtogroup CoreGroup */
|
||||
/** @{ */
|
||||
|
||||
/** Reed-Solomon encoder item */
|
||||
class QRrsItem {
|
||||
|
||||
/** Bits per symbol */
|
||||
public $mm;
|
||||
/** Symbols per block (= (1<<mm)-1) */
|
||||
public $nn;
|
||||
/** Log lookup table */
|
||||
public $alpha_to = array();
|
||||
/** Antilog lookup table */
|
||||
public $index_of = array();
|
||||
/** Generator polynomial */
|
||||
public $genpoly = array();
|
||||
/** Number of generator roots = number of parity symbols */
|
||||
public $nroots;
|
||||
/** First consecutive root, index form */
|
||||
public $fcr;
|
||||
/** Primitive element, index form */
|
||||
public $prim;
|
||||
/** Prim-th root of 1, index form */
|
||||
public $iprim;
|
||||
/** Padding bytes in shortened block */
|
||||
public $pad;
|
||||
/** Galois Field Polynomial */
|
||||
public $gfpoly;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Modulo function in defined Field
|
||||
@param Integer $x number to be modulo-mapped
|
||||
*/
|
||||
public function modnn($x)
|
||||
{
|
||||
while ($x >= $this->nn) {
|
||||
$x -= $this->nn;
|
||||
$x = ($x >> $this->mm) + ($x & $this->nn);
|
||||
}
|
||||
|
||||
return $x;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Encoder initialisation
|
||||
@param Integer $symsize symbol size, bit count (1..8)
|
||||
@param Integer $gfpoly Galois Field Polynomial
|
||||
@param Integer $fcr First consecutive root
|
||||
@param Integer $prim Primitive element
|
||||
@param Integer $nroots Number of generator roots = number of parity symbols
|
||||
@param Integer $pad Padding bytes in shortened block
|
||||
*/
|
||||
public static function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
|
||||
{
|
||||
// Common code for intializing a Reed-Solomon control block (char or int symbols)
|
||||
// Copyright 2004 Phil Karn, KA9Q
|
||||
// May be used under the terms of the GNU Lesser General Public License (LGPL)
|
||||
|
||||
$rs = null;
|
||||
|
||||
// Check parameter ranges
|
||||
if($symsize < 0 || $symsize > 8) return $rs;
|
||||
if($fcr < 0 || $fcr >= (1<<$symsize)) return $rs;
|
||||
if($prim <= 0 || $prim >= (1<<$symsize)) return $rs;
|
||||
if($nroots < 0 || $nroots >= (1<<$symsize)) return $rs; // Can't have more roots than symbol values!
|
||||
if($pad < 0 || $pad >= ((1<<$symsize) -1 - $nroots)) return $rs; // Too much padding
|
||||
|
||||
$rs = new QRrsItem();
|
||||
$rs->mm = $symsize;
|
||||
$rs->nn = (1<<$symsize)-1;
|
||||
$rs->pad = $pad;
|
||||
|
||||
$rs->alpha_to = array_fill(0, $rs->nn+1, 0);
|
||||
$rs->index_of = array_fill(0, $rs->nn+1, 0);
|
||||
|
||||
// PHP style macro replacement ;)
|
||||
$NN =& $rs->nn;
|
||||
$A0 =& $NN;
|
||||
|
||||
// Generate Galois field lookup tables
|
||||
$rs->index_of[0] = $A0; // log(zero) = -inf
|
||||
$rs->alpha_to[$A0] = 0; // alpha**-inf = 0
|
||||
$sr = 1;
|
||||
|
||||
for($i=0; $i<$rs->nn; $i++) {
|
||||
$rs->index_of[$sr] = $i;
|
||||
$rs->alpha_to[$i] = $sr;
|
||||
$sr <<= 1;
|
||||
if($sr & (1<<$symsize)) {
|
||||
$sr ^= $gfpoly;
|
||||
}
|
||||
$sr &= $rs->nn;
|
||||
}
|
||||
|
||||
if($sr != 1){
|
||||
// field generator polynomial is not primitive!
|
||||
$rs = NULL;
|
||||
return $rs;
|
||||
}
|
||||
|
||||
/* Form RS code generator polynomial from its roots */
|
||||
$rs->genpoly = array_fill(0, $nroots+1, 0);
|
||||
|
||||
$rs->fcr = $fcr;
|
||||
$rs->prim = $prim;
|
||||
$rs->nroots = $nroots;
|
||||
$rs->gfpoly = $gfpoly;
|
||||
|
||||
/* Find prim-th root of 1, used in decoding */
|
||||
for($iprim=1;($iprim % $prim) != 0;$iprim += $rs->nn)
|
||||
; // intentional empty-body loop!
|
||||
|
||||
$rs->iprim = (int)($iprim / $prim);
|
||||
$rs->genpoly[0] = 1;
|
||||
|
||||
for ($i = 0,$root=$fcr*$prim; $i < $nroots; $i++, $root += $prim) {
|
||||
$rs->genpoly[$i+1] = 1;
|
||||
|
||||
// Multiply rs->genpoly[] by @**(root + x)
|
||||
for ($j = $i; $j > 0; $j--) {
|
||||
if ($rs->genpoly[$j] != 0) {
|
||||
$rs->genpoly[$j] = $rs->genpoly[$j-1] ^ $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[$j]] + $root)];
|
||||
} else {
|
||||
$rs->genpoly[$j] = $rs->genpoly[$j-1];
|
||||
}
|
||||
}
|
||||
// rs->genpoly[0] can never be zero
|
||||
$rs->genpoly[0] = $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[0]] + $root)];
|
||||
}
|
||||
|
||||
// convert rs->genpoly[] to index form for quicker encoding
|
||||
for ($i = 0; $i <= $nroots; $i++)
|
||||
$rs->genpoly[$i] = $rs->index_of[$rs->genpoly[$i]];
|
||||
|
||||
return $rs;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Appends char into encoder
|
||||
@param String input
|
||||
@param Array parity table
|
||||
*/
|
||||
public function encode_rs_char($data, &$parity)
|
||||
{
|
||||
$MM =& $this->mm;
|
||||
$NN =& $this->nn;
|
||||
$ALPHA_TO =& $this->alpha_to;
|
||||
$INDEX_OF =& $this->index_of;
|
||||
$GENPOLY =& $this->genpoly;
|
||||
$NROOTS =& $this->nroots;
|
||||
$FCR =& $this->fcr;
|
||||
$PRIM =& $this->prim;
|
||||
$IPRIM =& $this->iprim;
|
||||
$PAD =& $this->pad;
|
||||
$A0 =& $NN;
|
||||
|
||||
$parity = array_fill(0, $NROOTS, 0);
|
||||
|
||||
for($i=0; $i< ($NN-$NROOTS-$PAD); $i++) {
|
||||
|
||||
$feedback = $INDEX_OF[$data[$i] ^ $parity[0]];
|
||||
if($feedback != $A0) {
|
||||
// feedback term is non-zero
|
||||
|
||||
// This line is unnecessary when GENPOLY[NROOTS] is unity, as it must
|
||||
// always be for the polynomials constructed by init_rs()
|
||||
$feedback = $this->modnn($NN - $GENPOLY[$NROOTS] + $feedback);
|
||||
|
||||
for($j=1;$j<$NROOTS;$j++) {
|
||||
$parity[$j] ^= $ALPHA_TO[$this->modnn($feedback + $GENPOLY[$NROOTS-$j])];
|
||||
}
|
||||
}
|
||||
|
||||
// Shift
|
||||
array_shift($parity);
|
||||
if($feedback != $A0) {
|
||||
array_push($parity, $ALPHA_TO[$this->modnn($feedback + $GENPOLY[0])]);
|
||||
} else {
|
||||
array_push($parity, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//##########################################################################
|
||||
/** Reed-Solomon encoder */
|
||||
class QRrs {
|
||||
|
||||
/** Encoder items array */
|
||||
public static $items = array();
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Encoder initialisation
|
||||
@param Integer $symsize symbol size, bit count (1..8)
|
||||
@param Integer $gfpoly Galois Field Polynomial
|
||||
@param Integer $fcr First consecutive root
|
||||
@param Integer $prim Primitive element
|
||||
@param Integer $nroots Number of generator roots = number of parity symbols
|
||||
@param Integer $pad Padding bytes in shortened block
|
||||
*/
|
||||
public static function init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
|
||||
{
|
||||
foreach(self::$items as $rs) {
|
||||
if($rs->pad != $pad) continue;
|
||||
if($rs->nroots != $nroots) continue;
|
||||
if($rs->mm != $symsize) continue;
|
||||
if($rs->gfpoly != $gfpoly) continue;
|
||||
if($rs->fcr != $fcr) continue;
|
||||
if($rs->prim != $prim) continue;
|
||||
|
||||
return $rs;
|
||||
}
|
||||
|
||||
$rs = QRrsItem::init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad);
|
||||
array_unshift(self::$items, $rs);
|
||||
|
||||
return $rs;
|
||||
}
|
||||
}
|
||||
|
||||
/** @}*/
|
||||
690
public/phpqrcode/qrspec.php
Executable file
@@ -0,0 +1,690 @@
|
||||
<?php
|
||||
/*
|
||||
* PHP QR Code encoder
|
||||
*
|
||||
* QR Code specifications
|
||||
*
|
||||
* Based on libqrencode C library distributed under LGPL 2.1
|
||||
* Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* PHP QR Code is distributed under LGPL 3
|
||||
* Copyright (C) 2010-2013 Dominik Dzienia <deltalab at poczta dot fm>
|
||||
*
|
||||
* The following data / specifications are taken from
|
||||
* "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
|
||||
* or
|
||||
* "Automatic identification and data capture techniques --
|
||||
* QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** Maximal Version no allowed by QR-Code spec */
|
||||
define('QRSPEC_VERSION_MAX', 40);
|
||||
/** Maximal Code size in pixels allowed by QR-Code spec */
|
||||
define('QRSPEC_WIDTH_MAX', 177);
|
||||
|
||||
define('QRCAP_WIDTH', 0);
|
||||
define('QRCAP_WORDS', 1);
|
||||
define('QRCAP_REMINDER', 2);
|
||||
define('QRCAP_EC', 3);
|
||||
|
||||
/** @addtogroup CoreGroup */
|
||||
/** @{ */
|
||||
|
||||
/** QR-Code specification and Code Frame handling.
|
||||
Contains code specifications, calculates base frame, code structure
|
||||
and base properties
|
||||
*/
|
||||
class QRspec {
|
||||
|
||||
/** Array specifying properties of QR-Code "versions".
|
||||
Each so-called version has specified code area size and capacity.
|
||||
There are 40 versions, this table specifies for each of them four parameters:
|
||||
|
||||
- Integer __QRCAP_WIDTH__ - size of code in pixels
|
||||
- Integer __QRCAP_WORDS__ - code capacity, in words
|
||||
- Integer __QRCAP_REMINDER__ - remainder words
|
||||
- Array of Integers __QRCAP_EC__ - RS correction code count for each of four ECC levels
|
||||
\hideinitializer
|
||||
*/
|
||||
public static $capacity = array(
|
||||
array( 0, 0, 0, array( 0, 0, 0, 0)),
|
||||
array( 21, 26, 0, array( 7, 10, 13, 17)), // 1
|
||||
array( 25, 44, 7, array( 10, 16, 22, 28)),
|
||||
array( 29, 70, 7, array( 15, 26, 36, 44)),
|
||||
array( 33, 100, 7, array( 20, 36, 52, 64)),
|
||||
array( 37, 134, 7, array( 26, 48, 72, 88)), // 5
|
||||
array( 41, 172, 7, array( 36, 64, 96, 112)),
|
||||
array( 45, 196, 0, array( 40, 72, 108, 130)),
|
||||
array( 49, 242, 0, array( 48, 88, 132, 156)),
|
||||
array( 53, 292, 0, array( 60, 110, 160, 192)),
|
||||
array( 57, 346, 0, array( 72, 130, 192, 224)), //10
|
||||
array( 61, 404, 0, array( 80, 150, 224, 264)),
|
||||
array( 65, 466, 0, array( 96, 176, 260, 308)),
|
||||
array( 69, 532, 0, array( 104, 198, 288, 352)),
|
||||
array( 73, 581, 3, array( 120, 216, 320, 384)),
|
||||
array( 77, 655, 3, array( 132, 240, 360, 432)), //15
|
||||
array( 81, 733, 3, array( 144, 280, 408, 480)),
|
||||
array( 85, 815, 3, array( 168, 308, 448, 532)),
|
||||
array( 89, 901, 3, array( 180, 338, 504, 588)),
|
||||
array( 93, 991, 3, array( 196, 364, 546, 650)),
|
||||
array( 97, 1085, 3, array( 224, 416, 600, 700)), //20
|
||||
array(101, 1156, 4, array( 224, 442, 644, 750)),
|
||||
array(105, 1258, 4, array( 252, 476, 690, 816)),
|
||||
array(109, 1364, 4, array( 270, 504, 750, 900)),
|
||||
array(113, 1474, 4, array( 300, 560, 810, 960)),
|
||||
array(117, 1588, 4, array( 312, 588, 870, 1050)), //25
|
||||
array(121, 1706, 4, array( 336, 644, 952, 1110)),
|
||||
array(125, 1828, 4, array( 360, 700, 1020, 1200)),
|
||||
array(129, 1921, 3, array( 390, 728, 1050, 1260)),
|
||||
array(133, 2051, 3, array( 420, 784, 1140, 1350)),
|
||||
array(137, 2185, 3, array( 450, 812, 1200, 1440)), //30
|
||||
array(141, 2323, 3, array( 480, 868, 1290, 1530)),
|
||||
array(145, 2465, 3, array( 510, 924, 1350, 1620)),
|
||||
array(149, 2611, 3, array( 540, 980, 1440, 1710)),
|
||||
array(153, 2761, 3, array( 570, 1036, 1530, 1800)),
|
||||
array(157, 2876, 0, array( 570, 1064, 1590, 1890)), //35
|
||||
array(161, 3034, 0, array( 600, 1120, 1680, 1980)),
|
||||
array(165, 3196, 0, array( 630, 1204, 1770, 2100)),
|
||||
array(169, 3362, 0, array( 660, 1260, 1860, 2220)),
|
||||
array(173, 3532, 0, array( 720, 1316, 1950, 2310)),
|
||||
array(177, 3706, 0, array( 750, 1372, 2040, 2430)) //40
|
||||
);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Calculates data length for specified code configuration.
|
||||
@param Integer $version Code version
|
||||
@param Integer $level ECC level
|
||||
@returns Code data capacity
|
||||
*/
|
||||
public static function getDataLength($version, $level)
|
||||
{
|
||||
return self::$capacity[$version][QRCAP_WORDS] - self::$capacity[$version][QRCAP_EC][$level];
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Calculates count of Error Correction Codes for specified code configuration.
|
||||
@param Integer $version Code version
|
||||
@param Integer $level ECC level
|
||||
@returns ECC code count
|
||||
*/
|
||||
public static function getECCLength($version, $level)
|
||||
{
|
||||
return self::$capacity[$version][QRCAP_EC][$level];
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Gets pixel width of code.
|
||||
@param Integer $version Code version
|
||||
@returns Code width, in pixels
|
||||
*/
|
||||
public static function getWidth($version)
|
||||
{
|
||||
return self::$capacity[$version][QRCAP_WIDTH];
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Gets reminder chars length.
|
||||
@param Integer $version Code version
|
||||
@returns Reminder length
|
||||
*/
|
||||
public static function getRemainder($version)
|
||||
{
|
||||
return self::$capacity[$version][QRCAP_REMINDER];
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Finds minimal code version capable of hosting specified data length.
|
||||
@param Integer $size amount of raw data
|
||||
@param Integer $level ECC level
|
||||
@returns code version capable of hosting specified amount of data at specified ECC level
|
||||
*/
|
||||
public static function getMinimumVersion($size, $level)
|
||||
{
|
||||
|
||||
for($i=1; $i<= QRSPEC_VERSION_MAX; $i++) {
|
||||
$words = self::$capacity[$i][QRCAP_WORDS] - self::$capacity[$i][QRCAP_EC][$level];
|
||||
if($words >= $size)
|
||||
return $i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
|
||||
/** Length bits Table.
|
||||
\hideinitializer
|
||||
*/
|
||||
public static $lengthTableBits = array(
|
||||
array(10, 12, 14),
|
||||
array( 9, 11, 13),
|
||||
array( 8, 16, 16),
|
||||
array( 8, 10, 12)
|
||||
);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function lengthIndicator($mode, $version)
|
||||
{
|
||||
if ($mode == QR_MODE_STRUCTURE)
|
||||
return 0;
|
||||
|
||||
if ($version <= 9) {
|
||||
$l = 0;
|
||||
} else if ($version <= 26) {
|
||||
$l = 1;
|
||||
} else {
|
||||
$l = 2;
|
||||
}
|
||||
|
||||
return self::$lengthTableBits[$mode][$l];
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function maximumWords($mode, $version)
|
||||
{
|
||||
if($mode == QR_MODE_STRUCTURE)
|
||||
return 3;
|
||||
|
||||
if($version <= 9) {
|
||||
$l = 0;
|
||||
} else if($version <= 26) {
|
||||
$l = 1;
|
||||
} else {
|
||||
$l = 2;
|
||||
}
|
||||
|
||||
$bits = self::$lengthTableBits[$mode][$l];
|
||||
$words = (1 << $bits) - 1;
|
||||
|
||||
if($mode == QR_MODE_KANJI) {
|
||||
$words *= 2; // the number of bytes is required
|
||||
}
|
||||
|
||||
return $words;
|
||||
}
|
||||
|
||||
// Error correction code -----------------------------------------------
|
||||
/** Table of the error correction code (Reed-Solomon block).
|
||||
@see Table 12-16 (pp.30-36), JIS X0510:2004.
|
||||
\hideinitializer
|
||||
*/
|
||||
|
||||
public static $eccTable = array(
|
||||
array(array( 0, 0), array( 0, 0), array( 0, 0), array( 0, 0)),
|
||||
array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), // 1
|
||||
array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)),
|
||||
array(array( 1, 0), array( 1, 0), array( 2, 0), array( 2, 0)),
|
||||
array(array( 1, 0), array( 2, 0), array( 2, 0), array( 4, 0)),
|
||||
array(array( 1, 0), array( 2, 0), array( 2, 2), array( 2, 2)), // 5
|
||||
array(array( 2, 0), array( 4, 0), array( 4, 0), array( 4, 0)),
|
||||
array(array( 2, 0), array( 4, 0), array( 2, 4), array( 4, 1)),
|
||||
array(array( 2, 0), array( 2, 2), array( 4, 2), array( 4, 2)),
|
||||
array(array( 2, 0), array( 3, 2), array( 4, 4), array( 4, 4)),
|
||||
array(array( 2, 2), array( 4, 1), array( 6, 2), array( 6, 2)), //10
|
||||
array(array( 4, 0), array( 1, 4), array( 4, 4), array( 3, 8)),
|
||||
array(array( 2, 2), array( 6, 2), array( 4, 6), array( 7, 4)),
|
||||
array(array( 4, 0), array( 8, 1), array( 8, 4), array(12, 4)),
|
||||
array(array( 3, 1), array( 4, 5), array(11, 5), array(11, 5)),
|
||||
array(array( 5, 1), array( 5, 5), array( 5, 7), array(11, 7)), //15
|
||||
array(array( 5, 1), array( 7, 3), array(15, 2), array( 3, 13)),
|
||||
array(array( 1, 5), array(10, 1), array( 1, 15), array( 2, 17)),
|
||||
array(array( 5, 1), array( 9, 4), array(17, 1), array( 2, 19)),
|
||||
array(array( 3, 4), array( 3, 11), array(17, 4), array( 9, 16)),
|
||||
array(array( 3, 5), array( 3, 13), array(15, 5), array(15, 10)), //20
|
||||
array(array( 4, 4), array(17, 0), array(17, 6), array(19, 6)),
|
||||
array(array( 2, 7), array(17, 0), array( 7, 16), array(34, 0)),
|
||||
array(array( 4, 5), array( 4, 14), array(11, 14), array(16, 14)),
|
||||
array(array( 6, 4), array( 6, 14), array(11, 16), array(30, 2)),
|
||||
array(array( 8, 4), array( 8, 13), array( 7, 22), array(22, 13)), //25
|
||||
array(array(10, 2), array(19, 4), array(28, 6), array(33, 4)),
|
||||
array(array( 8, 4), array(22, 3), array( 8, 26), array(12, 28)),
|
||||
array(array( 3, 10), array( 3, 23), array( 4, 31), array(11, 31)),
|
||||
array(array( 7, 7), array(21, 7), array( 1, 37), array(19, 26)),
|
||||
array(array( 5, 10), array(19, 10), array(15, 25), array(23, 25)), //30
|
||||
array(array(13, 3), array( 2, 29), array(42, 1), array(23, 28)),
|
||||
array(array(17, 0), array(10, 23), array(10, 35), array(19, 35)),
|
||||
array(array(17, 1), array(14, 21), array(29, 19), array(11, 46)),
|
||||
array(array(13, 6), array(14, 23), array(44, 7), array(59, 1)),
|
||||
array(array(12, 7), array(12, 26), array(39, 14), array(22, 41)), //35
|
||||
array(array( 6, 14), array( 6, 34), array(46, 10), array( 2, 64)),
|
||||
array(array(17, 4), array(29, 14), array(49, 10), array(24, 46)),
|
||||
array(array( 4, 18), array(13, 32), array(48, 14), array(42, 32)),
|
||||
array(array(20, 4), array(40, 7), array(43, 22), array(10, 67)),
|
||||
array(array(19, 6), array(18, 31), array(34, 34), array(20, 61)),//40
|
||||
);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// CACHEABLE!!!
|
||||
|
||||
public static function getEccSpec($version, $level, array &$spec)
|
||||
{
|
||||
if (count($spec) < 5) {
|
||||
$spec = array(0,0,0,0,0);
|
||||
}
|
||||
|
||||
$b1 = self::$eccTable[$version][$level][0];
|
||||
$b2 = self::$eccTable[$version][$level][1];
|
||||
$data = self::getDataLength($version, $level);
|
||||
$ecc = self::getECCLength($version, $level);
|
||||
|
||||
if($b2 == 0) {
|
||||
$spec[0] = $b1;
|
||||
$spec[1] = (int)($data / $b1);
|
||||
$spec[2] = (int)($ecc / $b1);
|
||||
$spec[3] = 0;
|
||||
$spec[4] = 0;
|
||||
} else {
|
||||
$spec[0] = $b1;
|
||||
$spec[1] = (int)($data / ($b1 + $b2));
|
||||
$spec[2] = (int)($ecc / ($b1 + $b2));
|
||||
$spec[3] = $b2;
|
||||
$spec[4] = $spec[1] + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Alignment pattern ---------------------------------------------------
|
||||
|
||||
/** Positions of alignment patterns.
|
||||
This array includes only the second and the third position of the
|
||||
lignment patterns. Rest of them can be calculated from the distance
|
||||
between them.
|
||||
|
||||
@see Table 1 in Appendix E (pp.71) of JIS X0510:2004.
|
||||
\hideinitializer
|
||||
*/
|
||||
|
||||
public static $alignmentPattern = array(
|
||||
array( 0, 0),
|
||||
array( 0, 0), array(18, 0), array(22, 0), array(26, 0), array(30, 0), // 1- 5
|
||||
array(34, 0), array(22, 38), array(24, 42), array(26, 46), array(28, 50), // 6-10
|
||||
array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48), //11-15
|
||||
array(26, 50), array(30, 54), array(30, 56), array(30, 58), array(34, 62), //16-20
|
||||
array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58), //21-25
|
||||
array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), //26-30
|
||||
array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), //31-35
|
||||
array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58), //35-40
|
||||
);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Puts an alignment marker.
|
||||
@param frame
|
||||
@param width
|
||||
@param ox,oy center coordinate of the pattern
|
||||
*/
|
||||
public static function putAlignmentMarker(array &$frame, $ox, $oy)
|
||||
{
|
||||
$finder = array(
|
||||
"\xa1\xa1\xa1\xa1\xa1",
|
||||
"\xa1\xa0\xa0\xa0\xa1",
|
||||
"\xa1\xa0\xa1\xa0\xa1",
|
||||
"\xa1\xa0\xa0\xa0\xa1",
|
||||
"\xa1\xa1\xa1\xa1\xa1"
|
||||
);
|
||||
|
||||
$yStart = $oy-2;
|
||||
$xStart = $ox-2;
|
||||
|
||||
for($y=0; $y<5; $y++) {
|
||||
self::set($frame, $xStart, $yStart+$y, $finder[$y]);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function putAlignmentPattern($version, &$frame, $width)
|
||||
{
|
||||
if($version < 2)
|
||||
return;
|
||||
|
||||
$d = self::$alignmentPattern[$version][1] - self::$alignmentPattern[$version][0];
|
||||
if($d < 0) {
|
||||
$w = 2;
|
||||
} else {
|
||||
$w = (int)(($width - self::$alignmentPattern[$version][0]) / $d + 2);
|
||||
}
|
||||
|
||||
if($w * $w - 3 == 1) {
|
||||
$x = self::$alignmentPattern[$version][0];
|
||||
$y = self::$alignmentPattern[$version][0];
|
||||
self::putAlignmentMarker($frame, $x, $y);
|
||||
return;
|
||||
}
|
||||
|
||||
$cx = self::$alignmentPattern[$version][0];
|
||||
for($x=1; $x<$w - 1; $x++) {
|
||||
self::putAlignmentMarker($frame, 6, $cx);
|
||||
self::putAlignmentMarker($frame, $cx, 6);
|
||||
$cx += $d;
|
||||
}
|
||||
|
||||
$cy = self::$alignmentPattern[$version][0];
|
||||
for($y=0; $y<$w-1; $y++) {
|
||||
$cx = self::$alignmentPattern[$version][0];
|
||||
for($x=0; $x<$w-1; $x++) {
|
||||
self::putAlignmentMarker($frame, $cx, $cy);
|
||||
$cx += $d;
|
||||
}
|
||||
$cy += $d;
|
||||
}
|
||||
}
|
||||
|
||||
// Version information pattern -----------------------------------------
|
||||
/** Version information pattern (BCH coded).
|
||||
size: [QRSPEC_VERSION_MAX - 6]
|
||||
@see Table 1 in Appendix D (pp.68) of JIS X0510:2004.
|
||||
\hideinitializer
|
||||
*/
|
||||
|
||||
public static $versionPattern = array(
|
||||
0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
|
||||
0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
|
||||
0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
|
||||
0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,
|
||||
0x27541, 0x28c69
|
||||
);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function getVersionPattern($version)
|
||||
{
|
||||
if($version < 7 || $version > QRSPEC_VERSION_MAX)
|
||||
return 0;
|
||||
|
||||
return self::$versionPattern[$version -7];
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Format information.
|
||||
@see calcFormatInfo in tests/test_qrspec.c (orginal qrencode c lib)
|
||||
\hideinitializer
|
||||
*/
|
||||
|
||||
public static $formatInfo = array(
|
||||
array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976),
|
||||
array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0),
|
||||
array(0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed),
|
||||
array(0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b)
|
||||
);
|
||||
|
||||
public static function getFormatInfo($mask, $level)
|
||||
{
|
||||
if($mask < 0 || $mask > 7)
|
||||
return 0;
|
||||
|
||||
if($level < 0 || $level > 3)
|
||||
return 0;
|
||||
|
||||
return self::$formatInfo[$level][$mask];
|
||||
}
|
||||
|
||||
// Frame ---------------------------------------------------------------
|
||||
|
||||
/** Cache of initial frames. */
|
||||
public static $frames = array();
|
||||
|
||||
/** Put a finder pattern.
|
||||
@param frame
|
||||
@param width
|
||||
@param ox,oy upper-left coordinate of the pattern
|
||||
\hideinitializer
|
||||
*/
|
||||
public static function putFinderPattern(&$frame, $ox, $oy)
|
||||
{
|
||||
$finder = array(
|
||||
"\xc1\xc1\xc1\xc1\xc1\xc1\xc1",
|
||||
"\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
|
||||
"\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
|
||||
"\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
|
||||
"\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
|
||||
"\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
|
||||
"\xc1\xc1\xc1\xc1\xc1\xc1\xc1"
|
||||
);
|
||||
|
||||
for($y=0; $y<7; $y++) {
|
||||
self::set($frame, $ox, $oy+$y, $finder[$y]);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function createFrame($version)
|
||||
{
|
||||
$width = self::$capacity[$version][QRCAP_WIDTH];
|
||||
$frameLine = str_repeat ("\0", $width);
|
||||
$frame = array_fill(0, $width, $frameLine);
|
||||
|
||||
// Finder pattern
|
||||
self::putFinderPattern($frame, 0, 0);
|
||||
self::putFinderPattern($frame, $width - 7, 0);
|
||||
self::putFinderPattern($frame, 0, $width - 7);
|
||||
|
||||
// Separator
|
||||
$yOffset = $width - 7;
|
||||
|
||||
for($y=0; $y<7; $y++) {
|
||||
$frame[$y][7] = "\xc0";
|
||||
$frame[$y][$width - 8] = "\xc0";
|
||||
$frame[$yOffset][7] = "\xc0";
|
||||
$yOffset++;
|
||||
}
|
||||
|
||||
$setPattern = str_repeat("\xc0", 8);
|
||||
|
||||
self::set($frame, 0, 7, $setPattern);
|
||||
self::set($frame, $width-8, 7, $setPattern);
|
||||
self::set($frame, 0, $width - 8, $setPattern);
|
||||
|
||||
// Format info
|
||||
$setPattern = str_repeat("\x84", 9);
|
||||
self::set($frame, 0, 8, $setPattern);
|
||||
self::set($frame, $width - 8, 8, $setPattern, 8);
|
||||
|
||||
$yOffset = $width - 8;
|
||||
|
||||
for($y=0; $y<8; $y++,$yOffset++) {
|
||||
$frame[$y][8] = "\x84";
|
||||
$frame[$yOffset][8] = "\x84";
|
||||
}
|
||||
|
||||
// Timing pattern
|
||||
|
||||
for($i=1; $i<$width-15; $i++) {
|
||||
$frame[6][7+$i] = chr(0x90 | ($i & 1));
|
||||
$frame[7+$i][6] = chr(0x90 | ($i & 1));
|
||||
}
|
||||
|
||||
// Alignment pattern
|
||||
self::putAlignmentPattern($version, $frame, $width);
|
||||
|
||||
// Version information
|
||||
if($version >= 7) {
|
||||
$vinf = self::getVersionPattern($version);
|
||||
|
||||
$v = $vinf;
|
||||
|
||||
for($x=0; $x<6; $x++) {
|
||||
for($y=0; $y<3; $y++) {
|
||||
$frame[($width - 11)+$y][$x] = chr(0x88 | ($v & 1));
|
||||
$v = $v >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
$v = $vinf;
|
||||
for($y=0; $y<6; $y++) {
|
||||
for($x=0; $x<3; $x++) {
|
||||
$frame[$y][$x+($width - 11)] = chr(0x88 | ($v & 1));
|
||||
$v = $v >> 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// and a little bit...
|
||||
$frame[$width - 8][8] = "\x81";
|
||||
|
||||
return $frame;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Dumps debug HTML of frame.
|
||||
@param Array $frame code frame
|
||||
@param Boolean $binary_mode in binary mode only contents is dumped, without styling
|
||||
*/
|
||||
public static function debug($frame, $binary_mode = false)
|
||||
{
|
||||
if ($binary_mode) {
|
||||
|
||||
foreach ($frame as &$frameLine) {
|
||||
$frameLine = join('<span class="m"> </span>', explode('0', $frameLine));
|
||||
$frameLine = join('██', explode('1', $frameLine));
|
||||
}
|
||||
|
||||
echo '<style> .m { background-color: white; } </style> ';
|
||||
echo '<pre><tt><br/ ><br/ ><br/ > ';
|
||||
echo join("<br/ > ", $frame);
|
||||
echo '</tt></pre><br/ ><br/ ><br/ ><br/ ><br/ ><br/ >';
|
||||
|
||||
} else {
|
||||
|
||||
foreach ($frame as &$frameLine) {
|
||||
|
||||
$frameLine = strtr($frameLine, array(
|
||||
"\xc0" => '<span class="m"> </span>', //marker 0
|
||||
"\xc1" => '<span class="m">▒</span>', //marker 1
|
||||
"\xa0" => '<span class="p"> </span>', //submarker 0
|
||||
"\xa1" => '<span class="p">▒</span>', //submarker 1
|
||||
"\x84" => '<span class="s">F</span>', //format 0
|
||||
"\x85" => '<span class="s">f</span>', //format 1
|
||||
"\x81" => '<span class="x">S</span>', //special bit
|
||||
"\x90" => '<span class="c">C</span>', //clock 0
|
||||
"\x91" => '<span class="c">c</span>', //clock 1
|
||||
"\x88" => '<span class="f"> </span>', //version 0
|
||||
"\x89" => '<span class="f">▒</span>', //version 1
|
||||
"\x03" => '1', // 1
|
||||
"\x02" => '0', // 0
|
||||
));
|
||||
}
|
||||
|
||||
echo '<style>';
|
||||
echo ' .p { background-color: yellow; }';
|
||||
echo ' .m { background-color: #00FF00; }';
|
||||
echo ' .s { background-color: #FF0000; }';
|
||||
echo ' .c { background-color: aqua; }';
|
||||
echo ' .x { background-color: pink; }';
|
||||
echo ' .f { background-color: gold; }';
|
||||
echo '</style>';
|
||||
|
||||
echo "<tt>";
|
||||
echo join("<br/ >", $frame);
|
||||
echo "<br/>Legend:<br/>";
|
||||
echo '1 - data 1<br/>';
|
||||
echo '0 - data 0<br/>';
|
||||
echo '<span class="m"> </span> - marker bit 0<br/>';
|
||||
echo '<span class="m">▒</span> - marker bit 1<br/>';
|
||||
echo '<span class="p"> </span> - secondary marker bit 0<br/>';
|
||||
echo '<span class="p">▒</span> - secondary marker bit 1<br/>';
|
||||
echo '<span class="s">F</span> - format bit 0<br/>';
|
||||
echo '<span class="s">f</span> - format bit 1<br/>';
|
||||
echo '<span class="x">S</span> - special bit<br/>';
|
||||
echo '<span class="c">C</span> - clock bit 0<br/>';
|
||||
echo '<span class="c">c</span> - clock bit 1<br/>';
|
||||
echo '<span class="f"> </span> - version bit 0<br/>';
|
||||
echo '<span class="f">▒</span> - version bit 1<br/>';
|
||||
echo "</tt>";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Serializes frame.
|
||||
Create compressed, serialized version of frame.
|
||||
@param Array $frame Code Frame
|
||||
@return String binary compresed Code Frame
|
||||
*/
|
||||
public static function serial($frame)
|
||||
{
|
||||
return gzcompress(join("\n", $frame), 9);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Deserializes frame.
|
||||
Loads frame from serialized compressed binary
|
||||
@param String $code binary, GZipped, serialized frame
|
||||
@return Array Code Frame array
|
||||
*/
|
||||
public static function unserial($code)
|
||||
{
|
||||
return explode("\n", gzuncompress($code));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function newFrame($version)
|
||||
{
|
||||
if($version < 1 || $version > QRSPEC_VERSION_MAX)
|
||||
return null;
|
||||
|
||||
if(!isset(self::$frames[$version])) {
|
||||
|
||||
$fileName = QR_CACHE_DIR.'frame_'.$version.'.dat';
|
||||
|
||||
if (QR_CACHEABLE) {
|
||||
if (file_exists($fileName)) {
|
||||
self::$frames[$version] = self::unserial(file_get_contents($fileName));
|
||||
} else {
|
||||
self::$frames[$version] = self::createFrame($version);
|
||||
file_put_contents($fileName, self::serial(self::$frames[$version]));
|
||||
}
|
||||
} else {
|
||||
self::$frames[$version] = self::createFrame($version);
|
||||
}
|
||||
}
|
||||
|
||||
if(is_null(self::$frames[$version]))
|
||||
return null;
|
||||
|
||||
return self::$frames[$version];
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/** Sets code frame with speciffied code.
|
||||
@param Array $frame target frame (modified by reference)
|
||||
@param Integer $x X-axis position of replacement
|
||||
@param Integer $y Y-axis position of replacement
|
||||
@param Byte $repl replacement string
|
||||
@param Integer $replLen (optional) replacement string length, when __Integer__ > 1 subset of given $repl is used, when __false__ whole $repl is used
|
||||
*/
|
||||
public static function set(&$frame, $x, $y, $repl, $replLen = false) {
|
||||
$frame[$y] = substr_replace($frame[$y], ($replLen !== false)?substr($repl,0,$replLen):$repl, $x, ($replLen !== false)?$replLen:strlen($repl));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/** @name Reed-Solomon related shorthand getters.
|
||||
Syntax-sugar to access code speciffication by getter name, not by spec array field.
|
||||
*/
|
||||
/** @{*/
|
||||
public static function rsBlockNum($spec) { return $spec[0] + $spec[3]; }
|
||||
public static function rsBlockNum1($spec) { return $spec[0]; }
|
||||
public static function rsDataCodes1($spec) { return $spec[1]; }
|
||||
public static function rsEccCodes1($spec) { return $spec[2]; }
|
||||
public static function rsBlockNum2($spec) { return $spec[3]; }
|
||||
public static function rsDataCodes2($spec) { return $spec[4]; }
|
||||
public static function rsEccCodes2($spec) { return $spec[2]; }
|
||||
public static function rsDataLength($spec) { return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]); }
|
||||
public static function rsEccLength($spec) { return ($spec[0] + $spec[3]) * $spec[2]; }
|
||||
/** @}*/
|
||||
}
|
||||
|
||||
/** @}*/
|
||||
|
||||
?>
|
||||
318
public/phpqrcode/qrsplit.php
Executable file
@@ -0,0 +1,318 @@
|
||||
<?php
|
||||
/*
|
||||
* PHP QR Code encoder
|
||||
*
|
||||
* Input splitting classes
|
||||
*
|
||||
* Based on libqrencode C library distributed under LGPL 2.1
|
||||
* Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* PHP QR Code is distributed under LGPL 3
|
||||
* Copyright (C) 2010-2013 Dominik Dzienia <deltalab at poczta dot fm>
|
||||
*
|
||||
* The following data / specifications are taken from
|
||||
* "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
|
||||
* or
|
||||
* "Automatic identification and data capture techniques --
|
||||
* QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @addtogroup CoreGroup */
|
||||
/** @{ */
|
||||
|
||||
/** Input stream splitter. */
|
||||
class QRsplit {
|
||||
|
||||
public $dataStr = '';
|
||||
public $input;
|
||||
public $modeHint;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function __construct($dataStr, $input, $modeHint)
|
||||
{
|
||||
$this->dataStr = $dataStr;
|
||||
$this->input = $input;
|
||||
$this->modeHint = $modeHint;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function isdigitat($str, $pos)
|
||||
{
|
||||
if ($pos >= strlen($str))
|
||||
return false;
|
||||
|
||||
return ((ord($str[$pos]) >= ord('0'))&&(ord($str[$pos]) <= ord('9')));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function isalnumat($str, $pos)
|
||||
{
|
||||
if ($pos >= strlen($str))
|
||||
return false;
|
||||
|
||||
return (QRinput::lookAnTable(ord($str[$pos])) >= 0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function identifyMode($pos)
|
||||
{
|
||||
if ($pos >= strlen($this->dataStr))
|
||||
return QR_MODE_NUL;
|
||||
|
||||
$c = $this->dataStr[$pos];
|
||||
|
||||
if(self::isdigitat($this->dataStr, $pos)) {
|
||||
return QR_MODE_NUM;
|
||||
} else if(self::isalnumat($this->dataStr, $pos)) {
|
||||
return QR_MODE_AN;
|
||||
} else if($this->modeHint == QR_MODE_KANJI) {
|
||||
|
||||
if ($pos+1 < strlen($this->dataStr))
|
||||
{
|
||||
$d = $this->dataStr[$pos+1];
|
||||
$word = (ord($c) << 8) | ord($d);
|
||||
if(($word >= 0x8140 && $word <= 0x9ffc) || ($word >= 0xe040 && $word <= 0xebbf)) {
|
||||
return QR_MODE_KANJI;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QR_MODE_8;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function eatNum()
|
||||
{
|
||||
$ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
|
||||
|
||||
$p = 0;
|
||||
while(self::isdigitat($this->dataStr, $p)) {
|
||||
$p++;
|
||||
}
|
||||
|
||||
$run = $p;
|
||||
$mode = $this->identifyMode($p);
|
||||
|
||||
if($mode == QR_MODE_8) {
|
||||
$dif = QRinput::estimateBitsModeNum($run) + 4 + $ln
|
||||
+ QRinput::estimateBitsMode8(1) // + 4 + l8
|
||||
- QRinput::estimateBitsMode8($run + 1); // - 4 - l8
|
||||
if($dif > 0) {
|
||||
return $this->eat8();
|
||||
}
|
||||
}
|
||||
if($mode == QR_MODE_AN) {
|
||||
$dif = QRinput::estimateBitsModeNum($run) + 4 + $ln
|
||||
+ QRinput::estimateBitsModeAn(1) // + 4 + la
|
||||
- QRinput::estimateBitsModeAn($run + 1);// - 4 - la
|
||||
if($dif > 0) {
|
||||
return $this->eatAn();
|
||||
}
|
||||
}
|
||||
|
||||
$ret = $this->input->append(QR_MODE_NUM, $run, str_split($this->dataStr));
|
||||
if($ret < 0)
|
||||
return -1;
|
||||
|
||||
return $run;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function eatAn()
|
||||
{
|
||||
$la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion());
|
||||
$ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
|
||||
|
||||
$p = 0;
|
||||
|
||||
while(self::isalnumat($this->dataStr, $p)) {
|
||||
if(self::isdigitat($this->dataStr, $p)) {
|
||||
$q = $p;
|
||||
while(self::isdigitat($this->dataStr, $q)) {
|
||||
$q++;
|
||||
}
|
||||
|
||||
$dif = QRinput::estimateBitsModeAn($p) // + 4 + la
|
||||
+ QRinput::estimateBitsModeNum($q - $p) + 4 + $ln
|
||||
- QRinput::estimateBitsModeAn($q); // - 4 - la
|
||||
|
||||
if($dif < 0) {
|
||||
break;
|
||||
} else {
|
||||
$p = $q;
|
||||
}
|
||||
} else {
|
||||
$p++;
|
||||
}
|
||||
}
|
||||
|
||||
$run = $p;
|
||||
|
||||
if(!self::isalnumat($this->dataStr, $p)) {
|
||||
$dif = QRinput::estimateBitsModeAn($run) + 4 + $la
|
||||
+ QRinput::estimateBitsMode8(1) // + 4 + l8
|
||||
- QRinput::estimateBitsMode8($run + 1); // - 4 - l8
|
||||
if($dif > 0) {
|
||||
return $this->eat8();
|
||||
}
|
||||
}
|
||||
|
||||
$ret = $this->input->append(QR_MODE_AN, $run, str_split($this->dataStr));
|
||||
if($ret < 0)
|
||||
return -1;
|
||||
|
||||
return $run;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function eatKanji()
|
||||
{
|
||||
$p = 0;
|
||||
|
||||
while($this->identifyMode($p) == QR_MODE_KANJI) {
|
||||
$p += 2;
|
||||
}
|
||||
|
||||
$ret = $this->input->append(QR_MODE_KANJI, $p, str_split($this->dataStr));
|
||||
if($ret < 0)
|
||||
return -1;
|
||||
|
||||
return $run;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function eat8()
|
||||
{
|
||||
$la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion());
|
||||
$ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
|
||||
|
||||
$p = 1;
|
||||
$dataStrLen = strlen($this->dataStr);
|
||||
|
||||
while($p < $dataStrLen) {
|
||||
|
||||
$mode = $this->identifyMode($p);
|
||||
if($mode == QR_MODE_KANJI) {
|
||||
break;
|
||||
}
|
||||
if($mode == QR_MODE_NUM) {
|
||||
$q = $p;
|
||||
while(self::isdigitat($this->dataStr, $q)) {
|
||||
$q++;
|
||||
}
|
||||
$dif = QRinput::estimateBitsMode8($p) // + 4 + l8
|
||||
+ QRinput::estimateBitsModeNum($q - $p) + 4 + $ln
|
||||
- QRinput::estimateBitsMode8($q); // - 4 - l8
|
||||
if($dif < 0) {
|
||||
break;
|
||||
} else {
|
||||
$p = $q;
|
||||
}
|
||||
} else if($mode == QR_MODE_AN) {
|
||||
$q = $p;
|
||||
while(self::isalnumat($this->dataStr, $q)) {
|
||||
$q++;
|
||||
}
|
||||
$dif = QRinput::estimateBitsMode8($p) // + 4 + l8
|
||||
+ QRinput::estimateBitsModeAn($q - $p) + 4 + $la
|
||||
- QRinput::estimateBitsMode8($q); // - 4 - l8
|
||||
if($dif < 0) {
|
||||
break;
|
||||
} else {
|
||||
$p = $q;
|
||||
}
|
||||
} else {
|
||||
$p++;
|
||||
}
|
||||
}
|
||||
|
||||
$run = $p;
|
||||
$ret = $this->input->append(QR_MODE_8, $run, str_split($this->dataStr));
|
||||
|
||||
if($ret < 0)
|
||||
return -1;
|
||||
|
||||
return $run;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function splitString()
|
||||
{
|
||||
while (strlen($this->dataStr) > 0)
|
||||
{
|
||||
if($this->dataStr == '')
|
||||
return 0;
|
||||
|
||||
$mode = $this->identifyMode(0);
|
||||
|
||||
switch ($mode) {
|
||||
case QR_MODE_NUM: $length = $this->eatNum(); break;
|
||||
case QR_MODE_AN: $length = $this->eatAn(); break;
|
||||
case QR_MODE_KANJI:
|
||||
if ($hint == QR_MODE_KANJI)
|
||||
$length = $this->eatKanji();
|
||||
else $length = $this->eat8();
|
||||
break;
|
||||
default: $length = $this->eat8(); break;
|
||||
|
||||
}
|
||||
|
||||
if($length == 0) return 0;
|
||||
if($length < 0) return -1;
|
||||
|
||||
$this->dataStr = substr($this->dataStr, $length);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function toUpper()
|
||||
{
|
||||
$stringLen = strlen($this->dataStr);
|
||||
$p = 0;
|
||||
|
||||
while ($p<$stringLen) {
|
||||
$mode = self::identifyMode(substr($this->dataStr, $p), $this->modeHint);
|
||||
if($mode == QR_MODE_KANJI) {
|
||||
$p += 2;
|
||||
} else {
|
||||
if (ord($this->dataStr[$p]) >= ord('a') && ord($this->dataStr[$p]) <= ord('z')) {
|
||||
$this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32);
|
||||
}
|
||||
$p++;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->dataStr;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function splitStringToQRinput($string, QRinput $input, $modeHint, $casesensitive = true)
|
||||
{
|
||||
if(is_null($string) || $string == '\0' || $string == '') {
|
||||
throw new Exception('empty string!!!');
|
||||
}
|
||||
|
||||
$split = new QRsplit($string, $input, $modeHint);
|
||||
|
||||
if(!$casesensitive)
|
||||
$split->toUpper();
|
||||
|
||||
return $split->splitString();
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
169
public/phpqrcode/qrsvg.php
Executable file
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
/*
|
||||
* PHP QR Code encoder
|
||||
*
|
||||
* SVG output support
|
||||
*
|
||||
* Based on libqrencode C library distributed under LGPL 2.1
|
||||
* Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
|
||||
*
|
||||
* PHP QR Code is distributed under LGPL 3
|
||||
* Copyright (C) 2010-2013 Dominik Dzienia <deltalab at poczta dot fm>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @addtogroup OutputGroup */
|
||||
/** @{ */
|
||||
|
||||
class QRsvgOutput extends QRarea {
|
||||
|
||||
public function __construct($source_tab)
|
||||
{
|
||||
parent::__construct($source_tab);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function mapX($px)
|
||||
{
|
||||
return $px;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function mapY($py)
|
||||
{
|
||||
return $py;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public function getRawSvg()
|
||||
{
|
||||
$lib = array();
|
||||
$svg = array();
|
||||
|
||||
$aggregate_paths = array();
|
||||
|
||||
foreach ($this->paths as $path) {
|
||||
switch ($path[0]) {
|
||||
case QR_AREA_PATH:
|
||||
$pNum = 0;
|
||||
|
||||
foreach($path[1] as $pathDetails) {
|
||||
|
||||
$px = array_shift($pathDetails);
|
||||
$py = array_shift($pathDetails);
|
||||
$rle_steps = array_shift($pathDetails);
|
||||
|
||||
$aggregate_add = 'M'.$px.','.$py.' ';
|
||||
|
||||
while(count($rle_steps) > 0) {
|
||||
|
||||
$delta = 1;
|
||||
|
||||
$operator = array_shift($rle_steps);
|
||||
if (($operator != 'R') && ($operator != 'L') && ($operator != 'T') && ($operator != 'B')) {
|
||||
$delta = (int)$operator;
|
||||
$operator = array_shift($rle_steps);
|
||||
}
|
||||
|
||||
if ($operator == 'R') $aggregate_add .= 'h'.$delta;
|
||||
if ($operator == 'L') $aggregate_add .= 'h-'.$delta;
|
||||
if ($operator == 'T') $aggregate_add .= 'v-'.$delta;
|
||||
if ($operator == 'B') $aggregate_add .= 'v'.$delta;
|
||||
}
|
||||
|
||||
$aggregate_paths[] = $aggregate_add;
|
||||
|
||||
$pNum++;
|
||||
}
|
||||
|
||||
break;
|
||||
case QR_AREA_POINT:
|
||||
|
||||
$symb = array_shift($path);
|
||||
|
||||
while(count($path) > 0) {
|
||||
$px = array_shift($path);
|
||||
$py = array_shift($path);
|
||||
|
||||
$aggregate_paths[] = 'M'.$px.','.$py.' v1h1v-1h-1';
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case QR_AREA_RECT:
|
||||
|
||||
$symb = array_shift($path);
|
||||
|
||||
while(count($path) > 0) {
|
||||
$px = array_shift($path);
|
||||
$py = array_shift($path);
|
||||
$ex = array_shift($path);
|
||||
$ey = array_shift($path);
|
||||
|
||||
$w = $ex-$px;
|
||||
$h = $ey-$py;
|
||||
|
||||
$aggregate_paths[] = 'M'.$px.','.$py.' h'.$w.'v'.$h.'h-'.$w.'v-'.$h;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case QR_AREA_LSHAPE:
|
||||
|
||||
$symb = array_shift($path);
|
||||
|
||||
$l_shapes[0] = 'm1,0h1v2h-2v-1h1z';
|
||||
$l_shapes[1] = 'h1v1h1v1h-2z';
|
||||
$l_shapes[2] = 'h2v2h-1v-1h-1z';
|
||||
$l_shapes[3] = 'h2v1h-1v1h-1z';
|
||||
|
||||
while(count($path) > 0) {
|
||||
$px = array_shift($path);
|
||||
$py = array_shift($path);
|
||||
$mode = (int)array_shift($path);
|
||||
|
||||
$aggregate_paths[] = 'M'.$px.','.$py.' '.$l_shapes[$mode];
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case QR_AREA_TRACKER:
|
||||
|
||||
if (!isset($lib['tracker'])) {
|
||||
$lib['tracker'] = '<symbol id="tracker"><path d="m 0 7 0 7 7 0 0 -7 -7 0 z m 1 1 5 0 0 5 -5 0 0 -5 z m 1 1 0 3 3 0 0 -3 -3 0 z" style="fill:#000000;stroke:none"></path></symbol>';
|
||||
}
|
||||
|
||||
$symb = array_shift($path);
|
||||
|
||||
$px = array_shift($path);
|
||||
$py = array_shift($path);
|
||||
|
||||
$svg[] = '<use x="'.$px.'" y="'.($py-7).'" xlink:href="#tracker"></use>';
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$svg[] = '<path d="'.join(' ', $aggregate_paths).'" style="fill:#000000;stroke:none" ></path>';
|
||||
|
||||
|
||||
|
||||
return join("\n", $lib)."\n".join("\n", $svg);
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
190
public/phpqrcode/qrtools.php
Executable file
@@ -0,0 +1,190 @@
|
||||
<?php
|
||||
/*
|
||||
* PHP QR Code encoder
|
||||
*
|
||||
* Toolset, handy and debug utilites.
|
||||
*
|
||||
* PHP QR Code is distributed under LGPL 3
|
||||
* Copyright (C) 2010-2013 Dominik Dzienia <deltalab at poczta dot fm>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @addtogroup CoreGroup */
|
||||
/** @{ */
|
||||
|
||||
/** Helper class */
|
||||
class QRtools {
|
||||
|
||||
public static $timeBenchmarkStarted = false;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function binarize($frame)
|
||||
{
|
||||
$len = count($frame);
|
||||
foreach ($frame as &$frameLine) {
|
||||
|
||||
for($i=0; $i<$len; $i++) {
|
||||
$frameLine[$i] = (ord($frameLine[$i])&1)?'1':'0';
|
||||
}
|
||||
}
|
||||
|
||||
return $frame;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function tcpdfBarcodeArray($code, $mode = 'QR,L', $tcPdfVersion = '4.5.037')
|
||||
{
|
||||
$barcode_array = array();
|
||||
|
||||
if (!is_array($mode))
|
||||
$mode = explode(',', $mode);
|
||||
|
||||
$eccLevel = 'L';
|
||||
|
||||
if (count($mode) > 1) {
|
||||
$eccLevel = $mode[1];
|
||||
}
|
||||
|
||||
$qrTab = QRcode::text($code, false, $eccLevel);
|
||||
$size = count($qrTab);
|
||||
|
||||
$barcode_array['num_rows'] = $size;
|
||||
$barcode_array['num_cols'] = $size;
|
||||
$barcode_array['bcode'] = array();
|
||||
|
||||
foreach ($qrTab as $line) {
|
||||
$arrAdd = array();
|
||||
foreach(str_split($line) as $char)
|
||||
$arrAdd[] = ($char=='1')?1:0;
|
||||
$barcode_array['bcode'][] = $arrAdd;
|
||||
}
|
||||
|
||||
return $barcode_array;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function clearCache()
|
||||
{
|
||||
self::$frames = array();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function buildCache()
|
||||
{
|
||||
QRtools::markTime('before_build_cache');
|
||||
|
||||
$mask = new QRmask();
|
||||
for ($a=1; $a <= QRSPEC_VERSION_MAX; $a++) {
|
||||
$frame = QRspec::newFrame($a);
|
||||
if (QR_IMAGE) {
|
||||
$fileName = QR_CACHE_DIR.'frame_'.$a.'.png';
|
||||
QRimage::png(self::binarize($frame), $fileName, 1, 0);
|
||||
}
|
||||
|
||||
$width = count($frame);
|
||||
$bitMask = array_fill(0, $width, array_fill(0, $width, 0));
|
||||
for ($maskNo=0; $maskNo<8; $maskNo++)
|
||||
$mask->makeMaskNo($maskNo, $width, $frame, $bitMask, true);
|
||||
}
|
||||
|
||||
QRtools::markTime('after_build_cache');
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function log($outfile, $err)
|
||||
{
|
||||
if (QR_LOG_DIR !== false) {
|
||||
if ($err != '') {
|
||||
if ($outfile !== false) {
|
||||
file_put_contents(QR_LOG_DIR.basename($outfile).'-errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND);
|
||||
} else {
|
||||
file_put_contents(QR_LOG_DIR.'errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function dumpMask($frame)
|
||||
{
|
||||
$width = count($frame);
|
||||
for($y=0;$y<$width;$y++) {
|
||||
for($x=0;$x<$width;$x++) {
|
||||
echo ord($frame[$y][$x]).',';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function startTimeBenchmark()
|
||||
{
|
||||
$GLOBALS['qr_time_bench'] = array();
|
||||
self::markTime('start');
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function markTime($markerId)
|
||||
{
|
||||
list($usec, $sec) = explode(" ", microtime());
|
||||
$time = ((float)$usec + (float)$sec);
|
||||
|
||||
if (!isset($GLOBALS['qr_time_bench']))
|
||||
$GLOBALS['qr_time_bench'] = array();
|
||||
|
||||
$GLOBALS['qr_time_bench'][$markerId] = $time;
|
||||
|
||||
if ((!self::$timeBenchmarkStarted)&&($markerId != 'start')) {
|
||||
self::$timeBenchmarkStarted = true;
|
||||
$GLOBALS['qr_time_bench']['start'] = $time;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
public static function timeBenchmark()
|
||||
{
|
||||
self::markTime('finish');
|
||||
|
||||
$lastTime = 0;
|
||||
$startTime = 0;
|
||||
$p = 0;
|
||||
|
||||
echo '<table cellpadding="3" cellspacing="1">
|
||||
<thead><tr style="border-bottom:1px solid silver"><td colspan="2" style="text-align:center">BENCHMARK</td></tr></thead>
|
||||
<tbody>';
|
||||
|
||||
foreach($GLOBALS['qr_time_bench'] as $markerId=>$thisTime) {
|
||||
if ($p > 0) {
|
||||
echo '<tr><th style="text-align:right">till '.$markerId.': </th><td>'.number_format($thisTime-$lastTime, 6).'s</td></tr>';
|
||||
} else {
|
||||
$startTime = $thisTime;
|
||||
}
|
||||
|
||||
$p++;
|
||||
$lastTime = $thisTime;
|
||||
}
|
||||
|
||||
echo '</tbody><tfoot>
|
||||
<tr style="border-top:2px solid black"><th style="text-align:right">TOTAL: </th><td>'.number_format($lastTime-$startTime, 6).'s</td></tr>
|
||||
</tfoot>
|
||||
</table>';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** @}*/
|
||||
|
||||
//##########################################################################
|
||||
|
||||
461
public/style.css
@@ -3,278 +3,412 @@ Infinity Squared CSS
|
||||
https://github.com/tomslominski/infinity-squared
|
||||
*/
|
||||
|
||||
/* Structure */
|
||||
body {
|
||||
background: #F1F1F1;
|
||||
color: black;
|
||||
font-family: 'Ubuntu', sans-serif, Helvetica, Arial;
|
||||
/* Set up */
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 62.5%;
|
||||
}
|
||||
|
||||
#container {
|
||||
width: 60%;
|
||||
min-width: 720px;
|
||||
margin: 0 auto;
|
||||
background-color: white;
|
||||
body {
|
||||
background: #F1F1F1;
|
||||
color: black;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
body, input {
|
||||
font-family: 'Open Sans', 'Trebuchet MS', Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
/* General */
|
||||
::selection {
|
||||
background: rgba(1,63,109,0.7);
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
input::selection {
|
||||
background: rgba(1,63,109,0.7);
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
::-moz-selection {
|
||||
background: rgba(1,63,109,0.7);
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
input::-moz-selection {
|
||||
background: rgba(1,63,109,0.7);
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
a, a:visited, .footer a, .footer a:visited {
|
||||
/* Structure and global design */
|
||||
a, a:visited {
|
||||
color: #013F6D;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
p, a {
|
||||
font-size: 1.2em;
|
||||
.wrapper {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
max-width: 900px;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'icons';
|
||||
src:url('fonts/icons.woff') format('woff'),
|
||||
url('fonts/icons.ttf') format('truetype'),
|
||||
url('fonts/icons.svg#icons') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
.content {
|
||||
background: white;
|
||||
padding: 15px;
|
||||
margin-top: 15px;
|
||||
border: 1px solid #D8D8D8;
|
||||
box-shadow: 0 0 3px 0 #CCC;
|
||||
}
|
||||
|
||||
[class^="icon-"], [class*=" icon-"] {
|
||||
font-family: 'icons';
|
||||
speak: none;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
/* Better Font Rendering =========== */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 720px) {
|
||||
.wrapper {
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1024px) {
|
||||
.wrapper {
|
||||
width: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
/* Header */
|
||||
header {
|
||||
width: 95%;
|
||||
padding: 2.5%;
|
||||
.site-header {
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
background: url(img/noise.png) #013F6D;
|
||||
.site-title {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
color: white;
|
||||
font-size: 7em;
|
||||
background: #013F6D;
|
||||
border-top: 4px #000 solid;
|
||||
margin: 0 auto;
|
||||
transition: background 0.5s;
|
||||
}
|
||||
|
||||
h1 a, h1 a:visited {
|
||||
.site-title h1 {
|
||||
font-size: 4rem;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.site-tite:visited h1 {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h1 a:hover {
|
||||
border-bottom: #FFF 1px dashed;
|
||||
.site-title:hover {
|
||||
background: #0D4B78;
|
||||
}
|
||||
|
||||
.menu {
|
||||
background: #000000; /* Old browsers */
|
||||
background: -moz-linear-gradient(top, #000000 0%, #141414 100%); /* FF3.6+ */
|
||||
background: -webkit-linear-gradient(top, #000000 0%,#141414 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, #000000 0%,#141414 100%); /* Opera 11.10+ */
|
||||
background: linear-gradient(to bottom, #000000 0%,#141414 100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#000000', endColorstr='#141414',GradientType=0 ); /* IE6-9 */
|
||||
display: block;
|
||||
float: left;
|
||||
background: black;
|
||||
margin: 0 auto;
|
||||
width: 96%;
|
||||
width: 100%;
|
||||
color: white;
|
||||
padding: 0 2% 0 2%;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.menu a {
|
||||
color: #FFF;
|
||||
text-decoration: none;
|
||||
line-height: 38px;
|
||||
display: block;
|
||||
padding: 0 10px;
|
||||
display: inline-block;
|
||||
padding: 12px;
|
||||
background: none;
|
||||
transition: background 800ms;
|
||||
-moz-transition: background 800ms; /* Firefox 4 */
|
||||
-webkit-transition: background 800ms; /* Safari and Chrome */
|
||||
-o-transition: background 800ms; /* Opera */
|
||||
transition: background 0.8s;
|
||||
}
|
||||
|
||||
.menu a:hover {
|
||||
transition: background 800ms;
|
||||
-moz-transition: background 800ms; /* Firefox 4 */
|
||||
-webkit-transition: background 800ms; /* Safari and Chrome */
|
||||
-o-transition: background 800ms; /* Opera */
|
||||
transition: background 0.8s;
|
||||
background: #292929;
|
||||
}
|
||||
|
||||
.menu li {
|
||||
list-style: none;
|
||||
float: left;
|
||||
line-height: 38px;
|
||||
width: auto;
|
||||
@media screen and (min-width: 720px) {
|
||||
.site-title h1 {
|
||||
font-size: 5rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Main style */
|
||||
.paragraph {
|
||||
padding: 0 2.5% 0 2.5%;
|
||||
@media screen and (min-width: 1024px) {
|
||||
.site-title h1 {
|
||||
font-size: 6rem;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: black;
|
||||
margin-bottom: -8px;
|
||||
/* Forms */
|
||||
.form-item {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 60%;
|
||||
float: right;
|
||||
.form-item p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.radio {
|
||||
margin-right: 10%;
|
||||
.full-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
input[type="radio"] {
|
||||
margin-right: 1%;
|
||||
.half-width {
|
||||
width: 49%;
|
||||
}
|
||||
|
||||
.bookmarklet:before {
|
||||
font-family: 'icons';
|
||||
content: "\e600";
|
||||
margin: 2px;
|
||||
.halves {
|
||||
display: flex;
|
||||
display: -webkit-flex;
|
||||
display: -moz-flex;
|
||||
justify-content: space-between;
|
||||
-webkit-justify-content: space-between;
|
||||
-moz-justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
-webkit-align-items: flex-end;
|
||||
-moz-align-items: flex-end;
|
||||
}
|
||||
|
||||
/* reCAPTCHA */
|
||||
.recaptcha-container {
|
||||
font-size: 1.2em;
|
||||
overflow: hidden;
|
||||
label {
|
||||
display: inline;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
/* Tooltips */
|
||||
.qtip-default {
|
||||
label.primary {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
label.secondary {
|
||||
color: #AFAFAF;
|
||||
}
|
||||
|
||||
input:not([type=submit]):not([type=file]) {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
font-size: 1.6rem;
|
||||
border: 1px solid #D8D8D8;
|
||||
margin-top: 5px;
|
||||
transition: box-shadow 0.5s, border 0.5s;
|
||||
-webkit-appearance: none;
|
||||
border-radius: 0;
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.g-recaptcha {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
input:not([type=submit]):not([type=file]):focus {
|
||||
box-shadow: 0px 0px 8px 0px rgba(1,63,109,0.59), inset 0px 0px 1px 0px rgba(0,0,0,1);
|
||||
border-color: #013F6D;
|
||||
background-color: #013F6D;
|
||||
color: #FFF;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.ui-tooltip-titlebar,
|
||||
.ui-tooltip-content{
|
||||
border-color: #013F6D;
|
||||
background-color: #013F6D;
|
||||
color: #FFF;
|
||||
input[type=submit] {
|
||||
font-size: 1.4rem;
|
||||
padding: 10px;
|
||||
border-radius: 0;
|
||||
outline: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.button {
|
||||
background: #F9F9F9;
|
||||
border: 1px solid #D3D3D3;
|
||||
transition: background 0.5s;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
padding: 7px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background: #E2E2E2;
|
||||
}
|
||||
|
||||
.submit-container {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* Output */
|
||||
.output label {
|
||||
width: 30%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.output input {
|
||||
width: 70%
|
||||
}
|
||||
|
||||
.error {
|
||||
color: red;
|
||||
padding-bottom: 20px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.social-sharer {
|
||||
.error p.message {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.error p .key {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.input-with-copy {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.input-with-copy input:not([type=submit]):not([type=file]) {
|
||||
width: calc( 100% - 45px );
|
||||
}
|
||||
|
||||
.input-with-copy .copy-button {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 5px;
|
||||
height: 45px;
|
||||
width: 45px;
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.copy-message {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
left: 1px;
|
||||
height: 43px;
|
||||
line-height: 43px;
|
||||
width: calc( 100% - 47px );
|
||||
text-align: center;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
transition: opacity 0.3s, visibility 0.3s;
|
||||
color: white;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
-webkit-transform: translate3d(0, 0, 0); // WebKit animation fix
|
||||
}
|
||||
|
||||
.copy-message.visible {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.copy-message .os {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.copy-message.error.macos .macos {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.copy-message.error.pc .pc {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.copy-message.error.mobile .mobile {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.copy-message.error.other .other {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.social-button {
|
||||
display: inline-block;
|
||||
padding: 0 2px;
|
||||
border-color: #F0F0F0;
|
||||
font-size: 0;
|
||||
margin-right: 2px;
|
||||
transition: opacity 0.5s;
|
||||
-webkit-transform: translate3d(0, 0, 0); // WebKit animation fix
|
||||
}
|
||||
|
||||
.output label {
|
||||
width: 20%;
|
||||
.social-button:hover {
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.output input {
|
||||
width: 60%
|
||||
.social-button svg {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding: 6px;
|
||||
fill: white;
|
||||
}
|
||||
|
||||
.output button {
|
||||
float: right;
|
||||
.social-button.twitter {
|
||||
background-color: #55ACEE;
|
||||
}
|
||||
|
||||
.output button.active {
|
||||
color:#013F6D;
|
||||
.social-button.appdotnet {
|
||||
background-color: #49474B;
|
||||
}
|
||||
|
||||
.social-button.facebook {
|
||||
background-color: #3B5998;
|
||||
}
|
||||
|
||||
.social-button.tumblr {
|
||||
background-color: #35465C;
|
||||
}
|
||||
|
||||
.social-button.linkedin {
|
||||
background-color: #0976B4;
|
||||
}
|
||||
|
||||
.social-button.googleplus {
|
||||
background-color: #DD4B39;
|
||||
}
|
||||
|
||||
.social-button.vk {
|
||||
background-color: #4D7198;
|
||||
}
|
||||
|
||||
svg#url-qr-code {
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
/* Bookmarklet */
|
||||
.bookmarklet-container {
|
||||
text-align: center;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.bookmarklet {
|
||||
font-size: 1.4rem;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.icon-move svg {
|
||||
vertical-align: center;
|
||||
height: 1.2rem;
|
||||
width: 1.2rem;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.footer {
|
||||
.site-footer {
|
||||
text-align: center;
|
||||
border-top: 2px solid #000;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.footer p {
|
||||
padding: 2%;
|
||||
margin: 0 auto;
|
||||
font-size: 1.1em;
|
||||
.site-footer p {
|
||||
font-size: 1.2rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.footer a {
|
||||
font-size: 1.1em;
|
||||
.site-footer .recaptcha-cookie {
|
||||
margin-top: 5px;
|
||||
color: #AFAFAF;
|
||||
}
|
||||
|
||||
.footer a:hover {
|
||||
.site-footer a:hover {
|
||||
text-decoration: none;
|
||||
border-bottom: dashed 1px #013F6D;
|
||||
}
|
||||
|
||||
.icon-github svg {
|
||||
height: 1.2rem;
|
||||
width: 1.2rem;
|
||||
transition: fill 0.5s;
|
||||
}
|
||||
|
||||
.icon-github svg:hover {
|
||||
fill: #013F6D;
|
||||
}
|
||||
|
||||
a.icon-github:hover {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* Mobile */
|
||||
@media screen and (max-width: 720px) {
|
||||
body {
|
||||
background:white;
|
||||
margin:0;
|
||||
.halves {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#container {
|
||||
min-width:0;
|
||||
.half-width {
|
||||
width: 100%;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
header {
|
||||
width:100%;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
.menu li {
|
||||
margin-top:0;
|
||||
}
|
||||
|
||||
.desktop-only, .zclip {
|
||||
display:none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,6 +421,3 @@ header {
|
||||
#wrap > p {
|
||||
color: red;
|
||||
}
|
||||
|
||||
/* Importing custom user styles */
|
||||
@import url("public/user-style.css");
|
||||
|
||||
178
result.php
@@ -1,43 +1,181 @@
|
||||
<?php
|
||||
include('header.php');
|
||||
|
||||
if ($recaptcha_json['success'] != 'true') {
|
||||
// What happens when the CAPTCHA was entered incorrectly
|
||||
die ( '<p class="error" title="' . $resp->error . '">' . yourls__( 'Are you a bot? Google thinks so. Go back and try again.', 'isq_translation' ) . '</p></div></div>' );
|
||||
if ( empty( $_REQUEST['url'] ) ) {
|
||||
display_error( yourls__( 'You haven\'t entered a URL to shorten.', 'isq_translation' ) );
|
||||
};
|
||||
|
||||
// Check if the keyword is reserved
|
||||
if ( !empty( $_REQUEST['keyword'] ) && yourls_keyword_is_reserved( $_REQUEST['keyword'] ) ) {
|
||||
display_error( sprintf( yourls__( 'The keyword %1$s is reserved.'), '<span class="key">' . $_REQUEST['keyword'] . '</span>' ) );
|
||||
}
|
||||
|
||||
$url = yourls_sanitize_url( $_REQUEST['url'] );
|
||||
$keyword = isset( $_REQUEST['keyword'] ) ? yourls_sanitize_keyword( $_REQUEST['keyword'] ): '' ;
|
||||
$title = isset( $_REQUEST['title'] ) ? yourls_sanitize_title( $_REQUEST['title'] ) : '' ;
|
||||
// Check if the keyword is taken
|
||||
if ( !empty( $_REQUEST['keyword'] ) && yourls_keyword_is_taken( $_REQUEST['keyword'] ) ) {
|
||||
display_error( sprintf( yourls__( 'The keyword %1$s is taken.'), '<span class="key">' . $_REQUEST['keyword'] . '</span>' ) );
|
||||
}
|
||||
|
||||
// Check what CAPTCHA method was used
|
||||
$antispam_method = $_REQUEST['antispam_method'];
|
||||
|
||||
switch( is_get_antispam_method() ) {
|
||||
case 'login':
|
||||
if( !yourls_is_valid_user() ) {
|
||||
display_error( yourls__( 'You are not logged in - please go back and try again.', 'isq_translation' ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'recaptcha_v3':
|
||||
$recaptcha_data = get_remote_file( 'https://www.google.com/recaptcha/api/siteverify?secret=' . ISQ::$recaptcha_v3['secret'] . '&response=' . $_POST['recaptcha_token'] );
|
||||
$recaptcha = json_decode( $recaptcha_data );
|
||||
|
||||
if( $recaptcha->success != true || $recaptcha->action != 'homepage' || $recaptcha->score < ISQ::$recaptcha_v3['threshold'] ) {
|
||||
display_error( yourls__( 'Are you a bot? Google certainly thinks you are.', 'isq_translation' ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'recaptcha':
|
||||
// Google reCAPTCHA is enabled
|
||||
$recaptcha_data = get_remote_file( 'https://www.google.com/recaptcha/api/siteverify?secret=' . ISQ::$recaptcha['secret'] . '&response=' . $_POST['g-recaptcha-response'] );
|
||||
$recaptcha_json = json_decode( $recaptcha_data, true );
|
||||
|
||||
// What happens when the reCAPTCHA was completed incorrectly
|
||||
if ( $recaptcha_json['success'] != 'true' ) {
|
||||
display_error( yourls__( 'Are you a bot? Google certainly thinks you are.', 'isq_translation' ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'basic':
|
||||
// Basic antispam protection fallback
|
||||
// What happens when it was not completed correctly
|
||||
if( !empty( $_POST['basic_antispam'] ) ) {
|
||||
display_error( yourls__( 'Are you a bot? The anti-spam check was not completed successfully.', 'isq_translation' ) );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// No anti-spam check was completed at all
|
||||
display_error( yourls__( 'Are you a bot? No anti-spam check was completed successfully.', 'isq_translation' ) );
|
||||
break;
|
||||
}
|
||||
|
||||
// Get parameters -- they will all be sanitized in yourls_add_new_link()
|
||||
$url = $_REQUEST['url'];
|
||||
$keyword = isset( $_REQUEST['keyword'] ) ? $_REQUEST['keyword'] : '' ;
|
||||
$title = isset( $_REQUEST['title'] ) ? $_REQUEST['title'] : '' ;
|
||||
$text = isset( $_REQUEST['text'] ) ? $_REQUEST['text'] : '' ;
|
||||
|
||||
// Create short URL, receive array $return with various information
|
||||
$return = yourls_add_new_link( $url, $keyword, $title );
|
||||
|
||||
$shorturl = isset( $return['shorturl'] ) ? $return['shorturl'] : '';
|
||||
$message = isset( $return['message'] ) ? $return['message'] : '';
|
||||
$title = isset( $return['title'] ) ? $return['title'] : '';
|
||||
$status = isset( $return['status'] ) ? $return['status'] : '';
|
||||
|
||||
// Check for all other errors
|
||||
if( empty( $shorturl ) ) {
|
||||
display_error( yourls__( 'The URL could not be shortened.', 'isq_translation' ) );
|
||||
}
|
||||
|
||||
// URL encoded links used in the social sharing buttons
|
||||
$encoded_shorturl = urlencode($shorturl);
|
||||
$encoded_title = urlencode($title);
|
||||
|
||||
// Add dependencies
|
||||
$dependencies[] = 'clipboard.js';
|
||||
|
||||
?>
|
||||
|
||||
<div class="content result">
|
||||
<!-- Error reporting -->
|
||||
<?php echo $error; ?>
|
||||
<?php isset( $error ) ? $error : ''; ?>
|
||||
|
||||
<!-- Default output -->
|
||||
<h2><?php yourls_e( 'Results', 'isq_translation'); ?></h2>
|
||||
<p><?php yourls_e( 'View your short URL', 'isq_translation'); ?></p>
|
||||
<h2><?php yourls_e( 'Your short URL', 'isq_translation'); ?></h2>
|
||||
|
||||
<div class="output">
|
||||
<p><label for="longurl"><?php yourls_e( 'Original URL:', 'isq_translation'); ?></label> <input type="text" name="longurl" onclick="this.select();" onload="this.select();" value="<?php echo $url; ?>" id="long-copy"> <?php if (!empty(ISQ::$general['clipboard'])) { echo '<button id="long-copy" data-clipboard-target="long-copy" class="desktop-only">' . yourls__( 'Copy to Clipboard', 'isq-translation' ) . '</button>'; } ?> </p>
|
||||
<p><label for="shorturl"><?php yourls_e( 'Short URL:', 'isq_translation'); ?></label> <input type="text" name="shorturl" onclick="this.select();" onload="this.select();" value="<?php echo $shorturl; ?>" id="short-copy"> <?php if (!empty(ISQ::$general['clipboard'])) { echo '<button id="short-copy" data-clipboard-target="short-copy" class="desktop-only">' . yourls__( 'Copy to Clipboard', 'isq-translation' ) . '</button>'; } ?> </p>
|
||||
<p><label for="stats"><?php /* translators: This is short for statistics */ yourls_e( 'Stats:', 'isq_translation'); ?></label> <input type="text" name="stats" onclick="this.select();" onload="this.select();" value="<?php echo $shorturl . '+'; ?>" id="stats-copy"> <?php if (!empty(ISQ::$general['clipboard'])) { echo '<button id="stats-copy" data-clipboard-target="stats-copy" class="desktop-only">' . yourls__( 'Copy to Clipboard', 'isq-translation' ) . '</button>'; } ?> </p>
|
||||
<p class="desktop-only"><?php yourls_e( 'Click on a link and press Ctrl+C to quickly copy it.', 'isq_translation'); ?></p>
|
||||
<div class="form-item full-width">
|
||||
<label for="longurl" class="primary"><?php yourls_e( 'Original URL', 'isq_translation'); ?></label>
|
||||
<div class="input-with-copy">
|
||||
<input type="text" name="longurl" id="longurl" onclick="this.select();" onload="this.select();" value="<?php echo $url; ?>">
|
||||
<button data-clipboard-target="#longurl" class="copy-button button" title="<?php yourls_e( 'Copy to clipboard', 'isq_translation' ); ?>"><img src="public/images/clippy.svg"></button>
|
||||
<div class="copy-message success" id="copy-success"><?php yourls_e( 'Copied to clipboard', 'isq_translation' ); ?></div>
|
||||
<div class="copy-message error" id="copy-error">
|
||||
<span class="os macos"><?php yourls_e( 'Press ⌘+C to copy', 'isq_translation' ); ?></span>
|
||||
<span class="os pc"><?php yourls_e( 'Press Ctrl+C to copy', 'isq_translation' ); ?></span>
|
||||
<span class="os mobile"><?php yourls_e( 'Tap copy', 'isq_translation' ); ?></span>
|
||||
<span class="os other"><?php yourls_e( 'Failed to copy', 'isq_translation' ); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- QR code -->
|
||||
<?php if (!empty(ISQ::$general['qr'])) { echo '<h2>' . yourls__( 'QR code', 'isq-translation' ) . '</h2><p>' . yourls__( 'Share your link with external devices', 'isq-translation' ) . '</p><img class="qr" src="https://chart.googleapis.com/chart?cht=qr&chs=250x250&chl=$shorturl&chld=L|0" alt="QR" width="250px" height="250px" />'; } ?>
|
||||
<div class="halves">
|
||||
<div class="form-item half-width left">
|
||||
<label for="shorturl" class="primary"><?php yourls_e( 'Short URL', 'isq_translation'); ?></label>
|
||||
<div class="input-with-copy">
|
||||
<input type="text" name="shorturl" id="shorturl" onclick="this.select();" value="<?php echo $shorturl; ?>">
|
||||
<button data-clipboard-target="#shorturl" class="copy-button button" title="<?php yourls_e( 'Copy to clipboard', 'isq_translation' ); ?>"><img src="public/images/clippy.svg"></button>
|
||||
<div class="copy-message success" id="copy-success"><?php yourls_e( 'Copied to clipboard', 'isq_translation' ); ?></div>
|
||||
<div class="copy-message error" id="copy-error">
|
||||
<span class="os macos"><?php yourls_e( 'Press ⌘+C to copy', 'isq_translation' ); ?></span>
|
||||
<span class="os pc"><?php yourls_e( 'Press Ctrl+C to copy', 'isq_translation' ); ?></span>
|
||||
<span class="os mobile"><?php yourls_e( 'Tap copy', 'isq_translation' ); ?></span>
|
||||
<span class="os other"><?php yourls_e( 'Failed to copy', 'isq_translation' ); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-item half-width right">
|
||||
<label for="stats" class="primary"><?php /* translators: This is short for statistics */ yourls_e( 'Stats', 'isq_translation'); ?></label>
|
||||
<div class="input-with-copy">
|
||||
<input type="text" name="stats" id="stats" onclick="this.select();" value="<?php echo $shorturl . '+'; ?>" id="stats-copy">
|
||||
<button data-clipboard-target="#stats" class="copy-button button" title="<?php yourls_e( 'Copy to clipboard', 'isq_translation' ); ?>"><img src="public/images/clippy.svg"></button>
|
||||
<div class="copy-message success" id="copy-success"><?php yourls_e( 'Copied to clipboard', 'isq_translation' ); ?></div>
|
||||
<div class="copy-message error" id="copy-error">
|
||||
<span class="os macos"><?php yourls_e( 'Press ⌘+C to copy', 'isq_translation' ); ?></span>
|
||||
<span class="os pc"><?php yourls_e( 'Press Ctrl+C to copy', 'isq_translation' ); ?></span>
|
||||
<span class="os mobile"><?php yourls_e( 'Tap copy', 'isq_translation' ); ?></span>
|
||||
<span class="os other"><?php yourls_e( 'Failed to copy', 'isq_translation' ); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Social sharers -->
|
||||
<h2><?php yourls_e( 'Share', 'isq_translation'); ?></h2>
|
||||
<p><?php yourls_e( 'Share your short URL', 'isq_translation'); ?></p>
|
||||
<?php if (!empty(ISQ::$social['facebook'])) { echo '<div class="social-sharer"><a href="http://facebook.com/sharer.php?u=' . $shorturl . '" class="share-button" target="_blank"><img src="public/img/facebook.png" alt="Facebook" width="55px" height="62px" /></a></div>'; } ?>
|
||||
<?php if (!empty(ISQ::$social['twitter'])) { echo '<div class="social-sharer"><a href="http://twitter.com/share" class="twitter-share-button" data-url="' . $shorturl . '" data-text="'. $title .'" data-count="vertical">Tweet</a><script src="http://platform.twitter.com/widgets.js"></script></div>'; } ?>
|
||||
<?php if (!empty(ISQ::$social['plus'])) { echo '<div class="g-plus social-sharer" data-action="share" data-annotation="vertical-bubble" data-height="62" data-href="' . $shorturl . '"></div>'; } ?>
|
||||
<?php if (!empty(ISQ::$social['linkedin'])) { echo '<div class="social-sharer"><script src="http://platform.linkedin.com/in.js"></script><script type="IN/Share" data-url="' . $shorturl . '" data-counter="top"></script></div>'; } ?>
|
||||
<?php if (!empty(ISQ::$social['tumblr'])) { echo '<a href="http://www.tumblr.com/share/link?url='. urlencode($shorturl) .'&name='. urlencode($title) .'" title="Share on Tumblr"><img src="public/img/tumblr.png" alt="Share on Tumblr" width="55px" height="62px" /></a>'; } ?>
|
||||
<div class="social-sharing">
|
||||
<?php
|
||||
if ( ISQ::$social['twitter'] ) { echo '<span onclick="window.open(\'https://twitter.com/intent/tweet?url=' . $encoded_shorturl . '&text=' . $encoded_title . '\',\'_blank\',\'width=550,height=380\')" class="button social-button twitter" title="Share on Twitter">' . file_get_contents('public/images/twitter.svg') . '</span>'; }
|
||||
|
||||
if ( ISQ::$social['appdotnet'] ) { echo '<span onclick="window.open(\'https://account.app.net/intent/post/?text=' . $encoded_title . '&url=' . $encoded_shorturl . '\',\'_blank\',\'width=550,height=380\')" class="button social-button appdotnet" title="Share on App.net">' . file_get_contents('public/images/appdotnet.svg') . '</span>'; }
|
||||
|
||||
if ( ISQ::$social['facebook'] ) { echo '<span onclick="window.open(\'https://www.facebook.com/sharer/sharer.php?u=' . $shorturl . '\',\'_blank\',\'width=550,height=380\')" class="button social-button facebook" title="Share on Facebook">' . file_get_contents('public/images/facebook.svg') . '</span>'; }
|
||||
|
||||
if ( ISQ::$social['tumblr'] ) { echo '<span onclick="window.open(\'http://www.tumblr.com/share/link?url=' . $encoded_shorturl . '&name=' . $encoded_title . '\',\'_blank\',\'width=550,height=380\')" class="button social-button tumblr" title="Share on Tumblr">' . file_get_contents('public/images/tumblr.svg') . '</span>'; }
|
||||
|
||||
if ( ISQ::$social['linkedin'] ) { echo '<span onclick="window.open(\'https://www.linkedin.com/shareArticle?mini=true&url=' . $encoded_shorturl . '&title=' . $encoded_title . '\',\'_blank\',\'width=550,height=380\')" class="button social-button linkedin" title="Share on LinkedIn">' . file_get_contents('public/images/linkedin.svg') . '</span>'; }
|
||||
|
||||
if ( ISQ::$social['googleplus'] ) { echo '<span onclick="window.open(\'https://plus.google.com/share?url=' . $encoded_shorturl . '\',\'_blank\',\'width=550,height=380\')" class="button social-button googleplus" title="Share on Google+">' . file_get_contents('public/images/googleplus.svg') . '</span>'; }
|
||||
|
||||
if ( ISQ::$social['vk'] ) { echo '<span onclick="window.open(\'https://vk.com/share.php?url=' . $encoded_shorturl . '\',\'_blank\',\'width=550,height=380\')" class="button social-button vk" title="Share on VK">' . file_get_contents('public/images/vk.svg') . '</span>'; }
|
||||
?>
|
||||
</div>
|
||||
|
||||
<?php if ( ISQ::$general['qr'] ) : ?>
|
||||
<!-- QR code -->
|
||||
<h2><?php yourls_e( 'QR code', 'isq_translation' ); ?></h2>
|
||||
<p><?php yourls_e( 'Share your link with external devices', 'isq_translation' ); ?></p>
|
||||
|
||||
<?php
|
||||
// PHP QR Code is LGPL licensed
|
||||
include('public/phpqrcode/qrlib.php');
|
||||
|
||||
echo QRcode::svg( $shorturl, 'url-qr-code', false, QR_ECLEVEL_L, '600' );
|
||||
endif; ?>
|
||||
|
||||
</div>
|
||||
|
||||
<?php include('footer.php'); ?>
|
||||
|
||||