diff --git a/doc/Development.md b/doc/Development.md index cab93660..e8030271 100644 --- a/doc/Development.md +++ b/doc/Development.md @@ -63,11 +63,21 @@ If an image changes, simply rename it eg. `logo-20210815.gif`. For now we'd rath ## Versioning of CSS/JS not handled by Vite -Since removing Juicer, it is still possible to add versioning to JS/CSS that is not handled by Vite. There is still a mod_rewrite rule in `.htaccess` which can handle css/js files through `version/cache.php` based on file naming pattern: +It is possible to add versioning to JS/CSS that is not handled by Vite. -`/web/vendor/some-lib.min.js` => `/web/vendor/some-lib-v20210815.min.js` +There is a mod_rewrite rule in `.htaccess` which matches a filename pattern containing a version number (eg. a YYYYMMDD date), and routes these through a php scrip that sets far future expire headers. -This will cause the file to be gzipped and add far future expire headers + the client will refresh its cache if the hash changed. + RewriteRule ^(.*)\.[a-z0-9]+\.(css|js)$ /version/cache.php?file=$0 [L] + +A file named... + + /web/vendor/some-lib.min.js + +... is referenced in the app (php/js) as: + + /web/vendor/some-lib-v20210815.min.js + +The `htaccess` rule will match the pattern, and get the original file, add far future expire headers, and return it as gzipped content. # Scripts execution diff --git a/docker/php-apache/bash/.bash_aliases b/docker/php-apache/bash/.bash_aliases index 8fac1a0c..6c6e5b97 100644 --- a/docker/php-apache/bash/.bash_aliases +++ b/docker/php-apache/bash/.bash_aliases @@ -73,6 +73,9 @@ alias ncu='./node_modules/.bin/ncu' # KOOHII DEV ############### +# watch custom error log with colored output (see lib/ColorizedLogger.php) +alias kklog='tail -f koohii-log.txt' + # build / alias for favicon generator (see src/web/favicons/README.md) alias real-favicon=./node_modules/.bin/real-favicon diff --git a/src/apps/koohii/config/koohiiConfiguration.class.php b/src/apps/koohii/config/koohiiConfiguration.class.php index b897f133..1875f977 100644 --- a/src/apps/koohii/config/koohiiConfiguration.class.php +++ b/src/apps/koohii/config/koohiiConfiguration.class.php @@ -23,6 +23,8 @@ public function configure() define('KK_ENV_DEV', CORE_ENVIRONMENT === 'dev'); define('KK_ENV_PROD', CORE_ENVIRONMENT === 'prod'); + define('KK_ENV_FORK', sfConfig::get('app_fork')); + // FIXME obsolete, clean up define('CJ_MODE', 'rtk'); define('CJ_HANZI', false); diff --git a/src/apps/koohii/lib/helper/BootstrapHelper.php b/src/apps/koohii/lib/helper/BootstrapHelper.php index 1366e65a..a7865b7d 100644 --- a/src/apps/koohii/lib/helper/BootstrapHelper.php +++ b/src/apps/koohii/lib/helper/BootstrapHelper.php @@ -22,13 +22,12 @@ * * COMMON HELPERS * - * _bs_button() MUST add Bootstrap css as option 'class' => 'btn btn-success ...' - * _bs_button_with_icon() DONT add 'btn btn-success' ... MUST add 'icon' => 'fa-icon-id' + * _bs_button() * * * FORM HELPERS * - * _bs_formgroup([array $options], ...) + * _bs_formgroup([array $options], ...) * * $options (optional) ... passed to Symfony tag helpers * @@ -38,21 +37,17 @@ * Example: * _bs_formgroup(['validate' => 'username'], ...) * - * _bs_input_checkbox($name, $options = array()) + * _bs_input_checkbox($name, $options = array()) * * OPTIONAL 'label' => 'Label text' * NOTE! The input's `value` is ALWAYS "1" * - * _bs_input_text ($name, $options = array()) - * - * _bs_input_textarea($name, $options = array()) - * - * _bs_input_email ($name, $options = array()) - * - * _bs_input_password($name, $options = array()) - * - * _bs_submit_tag ($label, $options = array()) + * _bs_input_email ($name, $options = array()) + * _bs_input_password($name, $options = array()) + * _bs_input_text ($name, $options = array()) + * _bs_input_textarea($name, $options = array()) * + * _bs_submit_tag ($label, $options = array()) * * * FORM LAYOUT @@ -67,41 +62,43 @@ */ /** - * Returns html for a Bootstrap button. + * Similar to sf's button_to(), but outputs a + + - + - - + +
+

+ Hooray! Your restudy list is empty! +

-
- -
+ - - new Koohii.UX.AjaxTable('FailedListTable'); - + + diff --git a/src/apps/koohii/modules/study/templates/indexSuccess.php b/src/apps/koohii/modules/study/templates/indexSuccess.php index 983d28fe..605d9f12 100755 --- a/src/apps/koohii/modules/study/templates/indexSuccess.php +++ b/src/apps/koohii/modules/study/templates/indexSuccess.php @@ -1,6 +1,9 @@
- false, 'intro' => true /* <- could be "false" */ ]) ?> + false, + 'isBeginRestudy' => false + ]) ?>
diff --git a/src/apps/koohii/modules/study/templates/mystoriesSuccess.php b/src/apps/koohii/modules/study/templates/mystoriesSuccess.php index aa320e5e..d3c01844 100755 --- a/src/apps/koohii/modules/study/templates/mystoriesSuccess.php +++ b/src/apps/koohii/modules/study/templates/mystoriesSuccess.php @@ -19,7 +19,14 @@
- 'fa-file']); ?> + ', + 'study/export', + [ + 'class' => 'ko-Btn ko-Btn--success', + ] + ); + ?>
diff --git a/src/apps/koohii/templates/_navbar.php b/src/apps/koohii/templates/_navbar.php index e9f2726a..92ad8d0c 100755 --- a/src/apps/koohii/templates/_navbar.php +++ b/src/apps/koohii/templates/_navbar.php @@ -172,7 +172,7 @@ function nav_m_i($label, $id, $url) { } else { - $nav_items[] = nav_m_t('Study', 'study', 'fa-book', [ + $nav_items[] = nav_m_t('Study', 'study', 'fa-book-open', [ nav_m_i('Index', 's-i', 'study/index'), nav_m_i('Restudy', 's-r', 'study/failedlist' ), nav_m_i('My Stories', 's-ms', 'study/mystories' ), diff --git a/src/apps/koohii/templates/fullscreenLayout.php b/src/apps/koohii/templates/fullscreenLayout.php index 91189b2c..84211bf4 100644 --- a/src/apps/koohii/templates/fullscreenLayout.php +++ b/src/apps/koohii/templates/fullscreenLayout.php @@ -14,9 +14,8 @@ include_stylesheets(); include_javascripts(); + include_fontawesome(); ?> - - diff --git a/src/apps/koohii/templates/layout.php b/src/apps/koohii/templates/layout.php index 23332438..278b1c4c 100644 --- a/src/apps/koohii/templates/layout.php +++ b/src/apps/koohii/templates/layout.php @@ -17,9 +17,8 @@ include_stylesheets(); include_javascripts(); + include_fontawesome(); ?> - - diff --git a/src/lib/peer/LearnedKanjiPeer.php b/src/lib/peer/LearnedKanjiPeer.php index f9c982ec..e7a9e8c7 100755 --- a/src/lib/peer/LearnedKanjiPeer.php +++ b/src/lib/peer/LearnedKanjiPeer.php @@ -118,9 +118,6 @@ public static function clearKanjis($userId, array $ucsIds) */ public static function clearAll($userId) { - $user = sfContext::getInstance()->getUser(); - $user->getAttributeHolder()->remove(rtkUser::IS_RESTUDY_SESSION); - return self::getInstance()->delete('userid = ?', $userId); } diff --git a/src/lib/peer/ReviewsPeer.php b/src/lib/peer/ReviewsPeer.php index 4def0ed7..88399bd3 100755 --- a/src/lib/peer/ReviewsPeer.php +++ b/src/lib/peer/ReviewsPeer.php @@ -21,6 +21,9 @@ * getSelectForDetailedList() * getSelectForExport() * getFlashcardsForReview() + * + * getRestudyKanjiCount($userId) + * getRestudyKanjiListSelect($userId) * * hasFlashcard($userId, $ucsId) * isFailedCard($userId, $ucsId) @@ -672,18 +675,29 @@ public static function getRestudyKanjiCount($userId) /** * Return select object for the Restudy Kanji list. * - * @param integer $userId + * @param int $userId * * @return coreDatabaseSelect */ public static function getRestudyKanjiListSelect($userId) { $select = self::getInstance() - ->select(['seq_nr' => rtkIndex::getSqlCol(), 'kanji', 'successcount', 'failurecount', 'ts_lastreview' => 'UNIX_TIMESTAMP(lastreview)']); + ->select([ + 'kanji', + 'seq_nr' => rtkIndex::getSqlCol(), + 'successcount', + 'failurecount', + 'ts_lastreview' => 'UNIX_TIMESTAMP(lastreview)', + 'is_learned' => new coreDbExpr('(lk.ucs_id IS NOT NULL)') + ]); + + $select->joinLeftUsing(LearnedKanjiPeer::getInstance()->getName().' lk', 'userid,ucs_id'); + $select = KanjisPeer::joinLeftUsingUCS($select); $select = CustkeywordsPeer::addCustomKeywordJoin($select, $userId); $select->where('leitnerbox=1 AND totalreviews>0'); $select = self::filterByUserId($select, $userId); + return $select; } @@ -837,8 +851,7 @@ public static function putFlashcardData($ucsId, $oData) } // clear relearned kanji if successfull answer - // NOTE: expected for API - if ($result && rtkApi::isApiModule() + if ($result && ($oData->r === LeitnerSRS::RATE_HARD || $oData->r === LeitnerSRS::RATE_YES || $oData->r === LeitnerSRS::RATE_NO || diff --git a/src/vite/package-lock.json b/src/vite/package-lock.json index 4899b18b..1f38a2a5 100644 --- a/src/vite/package-lock.json +++ b/src/vite/package-lock.json @@ -206,7 +206,8 @@ "@babel/helper-validator-identifier": { "version": "7.14.9", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", - "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==" + "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==", + "dev": true }, "@babel/helper-validator-option": { "version": "7.12.17", @@ -291,7 +292,8 @@ "@babel/parser": { "version": "7.15.5", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.5.tgz", - "integrity": "sha512-2hQstc6I7T6tQsWzlboMh3SgMRPaS4H6H7cPQsJkdzTzEGqQrpLDsE2BGASU5sBPoEQyHzeqU6C8uKbFeEk6sg==" + "integrity": "sha512-2hQstc6I7T6tQsWzlboMh3SgMRPaS4H6H7cPQsJkdzTzEGqQrpLDsE2BGASU5sBPoEQyHzeqU6C8uKbFeEk6sg==", + "dev": true }, "@babel/template": { "version": "7.12.13", @@ -352,6 +354,7 @@ "version": "7.15.4", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.4.tgz", "integrity": "sha512-0f1HJFuGmmbrKTCZtbm3cU+b/AqdEYk5toj5iQur58xkVMlS0JWaKxTBSmCXd47uiN7vbcozAupm6Mvs80GNhw==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.14.9", "to-fast-properties": "^2.0.0" @@ -362,27 +365,6 @@ "resolved": "https://registry.npmjs.org/@element-plus/icons/-/icons-0.0.11.tgz", "integrity": "sha512-iKQXSxXu131Ai+I9Ymtcof9WId7kaXvB1+WRfAfpQCW7UiAMYgdNDqb/u0hgTo2Yq3MwC4MWJnNuTBEpG8r7+A==" }, - "@emmetio/abbreviation": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@emmetio/abbreviation/-/abbreviation-2.2.3.tgz", - "integrity": "sha512-87pltuCPt99aL+y9xS6GPZ+Wmmyhll2WXH73gG/xpGcQ84DRnptBsI2r0BeIQ0EB/SQTOe2ANPqFqj3Rj5FOGA==", - "requires": { - "@emmetio/scanner": "^1.0.0" - } - }, - "@emmetio/css-abbreviation": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@emmetio/css-abbreviation/-/css-abbreviation-2.1.4.tgz", - "integrity": "sha512-qk9L60Y+uRtM5CPbB0y+QNl/1XKE09mSO+AhhSauIfr2YOx/ta3NJw2d8RtCFxgzHeRqFRr8jgyzThbu+MZ4Uw==", - "requires": { - "@emmetio/scanner": "^1.0.0" - } - }, - "@emmetio/scanner": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@emmetio/scanner/-/scanner-1.0.0.tgz", - "integrity": "sha512-8HqW8EVqjnCmWXVpqAOZf+EGESdkR27odcMMMGefgKXtar00SoYNSryGv//TELI4T3QFsECo78p+0lmalk/CFA==" - }, "@eslint/eslintrc": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", @@ -822,151 +804,75 @@ "dev": true }, "@volar/code-gen": { - "version": "0.31.4", - "resolved": "https://registry.npmjs.org/@volar/code-gen/-/code-gen-0.31.4.tgz", - "integrity": "sha512-ngivMEbBNd19v+EHdLyCJoIGRaoD9J4P20ZgdCEGf2voztja59u3Tilpf9r9ENy/731nG7XncToYm4+c1t/LhA==", + "version": "0.33.7", + "resolved": "https://registry.npmjs.org/@volar/code-gen/-/code-gen-0.33.7.tgz", + "integrity": "sha512-h3mezVitiCtd3KUI8ydHNK+dJFi6T1l4Uh733ulaZJxUn8aBfRIFgrQpQtwuNJVtR6qpRU9Kbjo+ePfMVWNdpQ==", "requires": { - "@volar/shared": "0.31.4", - "@volar/source-map": "0.31.4" + "@volar/source-map": "0.33.7" } }, - "@volar/html2pug": { - "version": "0.31.4", - "resolved": "https://registry.npmjs.org/@volar/html2pug/-/html2pug-0.31.4.tgz", - "integrity": "sha512-+whoP4C34kbCIRyoojZE6luqs7Ep/0YDBD9yEWu82G1ECLIFoujtkZXHbAHiQH8MIs/GwjUmozd85pUGAVQf1w==", + "@volar/pug-language-service": { + "version": "0.33.7", + "resolved": "https://registry.npmjs.org/@volar/pug-language-service/-/pug-language-service-0.33.7.tgz", + "integrity": "sha512-WbDpG8l5QxhJjMoaaDiaEIeoI0B2T5is5t0AsENIRMEYi0RLVLSHJj7Q5pH5A/tRLW2/0Y2Uu+zIryOVpxc+vA==", "requires": { - "domelementtype": "^2.2.0", - "domhandler": "^4.3.0", - "htmlparser2": "^7.2.0", - "pug": "^3.0.2" - }, - "dependencies": { - "dom-serializer": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", - "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "dependencies": { - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" - } - } - }, - "domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" - }, - "domhandler": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", - "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", - "requires": { - "domelementtype": "^2.2.0" - } - }, - "domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - } - }, - "entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==" - }, - "htmlparser2": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", - "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.2", - "domutils": "^2.8.0", - "entities": "^3.0.1" - } - } + "@volar/code-gen": "0.33.7", + "@volar/shared": "0.33.7", + "@volar/source-map": "0.33.7", + "@volar/transforms": "0.33.7", + "pug-lexer": "^5.0.1", + "pug-parser": "^6.0.0", + "vscode-languageserver-textdocument": "^1.0.3", + "vscode-languageserver-types": "^3.17.0-next.6" } }, "@volar/shared": { - "version": "0.31.4", - "resolved": "https://registry.npmjs.org/@volar/shared/-/shared-0.31.4.tgz", - "integrity": "sha512-mKSH4GKFde2t3GVEGibBu84jbCk7O1sccELxTgCGHX7ue4nJqgHup8lXhwyfUOfdJ7eyx9luyDsVuJ4BY3gfeg==", + "version": "0.33.7", + "resolved": "https://registry.npmjs.org/@volar/shared/-/shared-0.33.7.tgz", + "integrity": "sha512-c2A+cpNqniUK3p6/77X5zm1ED82PzW5mP5PXk2/sIG34zbm+rK2MhkajbAhr+bG9O1XhgdPZljpalhpsdLedpw==", "requires": { "upath": "^2.0.1", - "vscode-html-languageservice": "^4.2.1", "vscode-jsonrpc": "^8.0.0-next.5", "vscode-uri": "^3.0.3" } }, "@volar/source-map": { - "version": "0.31.4", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-0.31.4.tgz", - "integrity": "sha512-lX/XKKc3ESNt6QArq1T54LSxXvu7ARDctQfkt6qUSNLVR/ccUXwzM+4qiOj39WBbmoDzET33riVYnMXMeGJMvg==", - "requires": { - "@volar/shared": "0.31.4", - "vscode-languageserver-textdocument": "^1.0.3" - } + "version": "0.33.7", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-0.33.7.tgz", + "integrity": "sha512-2mfZg97iAuKx3XcYUrCfLfGmmBW/ku0G6XfwjRKeTOmYAx0j+7/mCiwGbDbR1X8RoS8H1Y5vD+ulc8MdHJS75A==" }, "@volar/transforms": { - "version": "0.31.4", - "resolved": "https://registry.npmjs.org/@volar/transforms/-/transforms-0.31.4.tgz", - "integrity": "sha512-081QI2zBvdja4XN3eAtIWmBqDkAyDuuK3xP5mD04T9vMrVfy+WKrzB7n3/Zru7z4DiM70Qo5PoTapQ3Xnz9NzQ==", + "version": "0.33.7", + "resolved": "https://registry.npmjs.org/@volar/transforms/-/transforms-0.33.7.tgz", + "integrity": "sha512-76VYq5j5mXTD2vysuews0CCyVNVnwPPe42aLtNSXeTXx4NzFkwJe3Jp+R72vC8asUCEPP/X88CMUlSn8eHiJHw==", "requires": { - "@volar/shared": "0.31.4", + "@volar/shared": "0.33.7", "vscode-languageserver-types": "^3.17.0-next.6" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.17.0-next.7", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.0-next.7.tgz", - "integrity": "sha512-KH4zdG1qBXxoso61ChgpeoZYyHGJo8bV7Jv4I+fwQ1Ryy59JAxoZ9GAbhR5TeeafHctLcg6RFvY3m8Jqfu17cg==" - } } }, "@volar/vue-code-gen": { - "version": "0.31.4", - "resolved": "https://registry.npmjs.org/@volar/vue-code-gen/-/vue-code-gen-0.31.4.tgz", - "integrity": "sha512-1ypZfzQfH+lV8JcOOKfYMTAmD6OUeBQSDwu7YRHQkuvoSQzPiXXrjupi0DvHrcWR0hQfh4yRnme6I+ChutW69w==", + "version": "0.33.7", + "resolved": "https://registry.npmjs.org/@volar/vue-code-gen/-/vue-code-gen-0.33.7.tgz", + "integrity": "sha512-5OmWKwHyD+wyhZcxPqozg6NB3FKgxdVmbIJMXzTTROYFMxpwHunFR6yXeaWRBA/nvOZted41QSGej2gzyl77Uw==", "requires": { - "@volar/code-gen": "0.31.4", - "@volar/shared": "0.31.4", - "@volar/source-map": "0.31.4", + "@volar/code-gen": "0.33.7", + "@volar/source-map": "0.33.7", "@vue/compiler-core": "^3.2.27", "@vue/compiler-dom": "^3.2.27", - "@vue/shared": "^3.2.27", - "upath": "^2.0.1" + "@vue/shared": "^3.2.27" } }, - "@vscode/emmet-helper": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/@vscode/emmet-helper/-/emmet-helper-2.8.4.tgz", - "integrity": "sha512-lUki5QLS47bz/U8IlG9VQ+1lfxMtxMZENmU5nu4Z71eOD5j9FK0SmYGL5NiVJg9WBWeAU0VxRADMY2Qpq7BfVg==", - "requires": { - "emmet": "^2.3.0", - "jsonc-parser": "^2.3.0", - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.15.1", - "vscode-nls": "^5.0.0", - "vscode-uri": "^2.1.2" - }, - "dependencies": { - "vscode-uri": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", - "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" - } + "@volar/vue-typescript": { + "version": "0.33.7", + "resolved": "https://registry.npmjs.org/@volar/vue-typescript/-/vue-typescript-0.33.7.tgz", + "integrity": "sha512-NPB7/esOe617J96jRAMTab3gVFc5a/+zXiwKns3+1osNIckfpe2VUbdK8P6v+XSmN9RPA5AXXRG47z4epK8zcg==", + "requires": { + "@volar/code-gen": "0.33.7", + "@volar/pug-language-service": "0.33.7", + "@volar/source-map": "0.33.7", + "@volar/vue-code-gen": "0.33.7", + "@vue/compiler-sfc": "^3.2.27", + "@vue/reactivity": "^3.2.27" } }, "@vue/compiler-core": { @@ -1280,11 +1186,6 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" - }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -1293,11 +1194,6 @@ "safer-buffer": "~2.1.0" } }, - "assert-never": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", - "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" - }, "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", @@ -1400,14 +1296,6 @@ "follow-redirects": "^1.14.4" } }, - "babel-walk": { - "version": "3.0.0-canary-5", - "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", - "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", - "requires": { - "@babel/types": "^7.9.6" - } - }, "bail": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", @@ -1799,15 +1687,6 @@ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, - "constantinople": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", - "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", - "requires": { - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.1" - } - }, "convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", @@ -1998,11 +1877,6 @@ "esutils": "^2.0.2" } }, - "doctypes": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", - "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=" - }, "dom-serializer": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", @@ -2095,15 +1969,6 @@ "normalize-wheel-es": "^1.1.0" } }, - "emmet": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/emmet/-/emmet-2.3.6.tgz", - "integrity": "sha512-pLS4PBPDdxuUAmw7Me7+TcHbykTsBKN/S9XJbUOMFQrNv9MoshzyMFK/R57JBm94/6HSL4vHnDeEmxlC82NQ4A==", - "requires": { - "@emmetio/abbreviation": "^2.2.3", - "@emmetio/css-abbreviation": "^2.1.4" - } - }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", @@ -3063,9 +2928,9 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, "has-tostringtag": { "version": "1.0.0", @@ -3293,6 +3158,7 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "dev": true, "requires": { "has": "^1.0.3" } @@ -3385,11 +3251,6 @@ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, - "is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" - }, "is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -3441,11 +3302,6 @@ "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=" }, - "js-stringify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", - "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=" - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -3518,11 +3374,6 @@ "minimist": "^1.2.5" } }, - "jsonc-parser": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.3.1.tgz", - "integrity": "sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==" - }, "jsonlines": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsonlines/-/jsonlines-0.1.1.tgz", @@ -3544,15 +3395,6 @@ "verror": "1.10.0" } }, - "jstransformer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", - "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=", - "requires": { - "is-promise": "^2.0.0", - "promise": "^7.0.1" - } - }, "keyv": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", @@ -4442,7 +4284,8 @@ "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true }, "path-type": { "version": "4.0.0", @@ -4922,14 +4765,6 @@ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "requires": { - "asap": "~2.0.3" - } - }, "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", @@ -4958,63 +4793,11 @@ "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" }, - "pug": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", - "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==", - "requires": { - "pug-code-gen": "^3.0.2", - "pug-filters": "^4.0.0", - "pug-lexer": "^5.0.1", - "pug-linker": "^4.0.0", - "pug-load": "^3.0.0", - "pug-parser": "^6.0.0", - "pug-runtime": "^3.0.1", - "pug-strip-comments": "^2.0.0" - } - }, - "pug-attrs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", - "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", - "requires": { - "constantinople": "^4.0.1", - "js-stringify": "^1.0.2", - "pug-runtime": "^3.0.0" - } - }, - "pug-code-gen": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", - "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", - "requires": { - "constantinople": "^4.0.1", - "doctypes": "^1.1.0", - "js-stringify": "^1.0.2", - "pug-attrs": "^3.0.0", - "pug-error": "^2.0.0", - "pug-runtime": "^3.0.0", - "void-elements": "^3.1.0", - "with": "^7.0.0" - } - }, "pug-error": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==" }, - "pug-filters": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", - "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", - "requires": { - "constantinople": "^4.0.1", - "jstransformer": "1.0.0", - "pug-error": "^2.0.0", - "pug-walk": "^2.0.0", - "resolve": "^1.15.1" - } - }, "pug-lexer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", @@ -5025,24 +4808,6 @@ "pug-error": "^2.0.0" } }, - "pug-linker": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", - "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", - "requires": { - "pug-error": "^2.0.0", - "pug-walk": "^2.0.0" - } - }, - "pug-load": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", - "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", - "requires": { - "object-assign": "^4.1.1", - "pug-walk": "^2.0.0" - } - }, "pug-parser": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", @@ -5052,24 +4817,6 @@ "token-stream": "1.0.0" } }, - "pug-runtime": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", - "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==" - }, - "pug-strip-comments": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", - "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", - "requires": { - "pug-error": "^2.0.0" - } - }, - "pug-walk": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", - "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" - }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -5370,6 +5117,7 @@ "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, "requires": { "is-core-module": "^2.2.0", "path-parse": "^1.0.6" @@ -6310,7 +6058,8 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true }, "to-readable-stream": { "version": "1.0.0", @@ -6402,9 +6151,9 @@ } }, "typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", + "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==", "dev": true }, "uc.micro": { @@ -6812,72 +6561,10 @@ } } }, - "void-elements": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", - "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=" - }, - "vscode-css-languageservice": { - "version": "5.1.13", - "resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-5.1.13.tgz", - "integrity": "sha512-FA0foqMzMmEoO0WJP+MjoD4dRERhKS+Ag+yBrtmWQDmw2OuZ1R/5FkvI/XdTkCpHmTD9VMczugpHRejQyTXCNQ==", - "requires": { - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.16.0", - "vscode-nls": "^5.0.0", - "vscode-uri": "^3.0.2" - } - }, - "vscode-html-languageservice": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-4.2.1.tgz", - "integrity": "sha512-PgaToZVXJ44nFWEBuSINdDgVV6EnpC3MnXBsysR3O5TKcAfywbYeRGRy+Y4dVR7YeUgDvtb+JkJoSkaYC0mxXQ==", - "requires": { - "vscode-languageserver-textdocument": "^1.0.1", - "vscode-languageserver-types": "^3.16.0", - "vscode-nls": "^5.0.0", - "vscode-uri": "^3.0.2" - } - }, - "vscode-json-languageservice": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-4.2.0.tgz", - "integrity": "sha512-XNawv0Vdy/sUK0S+hGf7cq/qsVAbIniGJr89TvZOqMCNJmpgKTy1e8PL1aWW0uy6BfWMG7vxa5lZb3ypuFtuGQ==", - "requires": { - "jsonc-parser": "^3.0.0", - "vscode-languageserver-textdocument": "^1.0.3", - "vscode-languageserver-types": "^3.16.0", - "vscode-nls": "^5.0.0", - "vscode-uri": "^3.0.3" - }, - "dependencies": { - "jsonc-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", - "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==" - } - } - }, "vscode-jsonrpc": { - "version": "8.0.0-next.6", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.0.0-next.6.tgz", - "integrity": "sha512-6Ld3RYjygn5Ih7CkAtcAwiDQC+rakj2O+PnASfNyYv3sLmm44eJpEKzuPUN30Iy2UB09AZg8T6LBKWTJTEJDVw==" - }, - "vscode-languageserver-protocol": { - "version": "3.17.0-next.14", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.0-next.14.tgz", - "integrity": "sha512-iangobY8dL6sFZkOx4OhRPJM9gN0I1caUsOVR+MnPozsqQUtwMXmbIcfaIf0Akp0pd3KhJDPf/tdwRX68QGeeA==", - "requires": { - "vscode-jsonrpc": "8.0.0-next.6", - "vscode-languageserver-types": "3.17.0-next.7" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.17.0-next.7", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.0-next.7.tgz", - "integrity": "sha512-KH4zdG1qBXxoso61ChgpeoZYyHGJo8bV7Jv4I+fwQ1Ryy59JAxoZ9GAbhR5TeeafHctLcg6RFvY3m8Jqfu17cg==" - } - } + "version": "8.0.0-next.7", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.0.0-next.7.tgz", + "integrity": "sha512-JX/F31LEsims0dAlOTKFE4E+AJMiJvdRSRViifFJSqSN7EzeYyWlfuDchF7g91oRNPZOIWfibTkDf3/UMsQGzQ==" }, "vscode-languageserver-textdocument": { "version": "1.0.4", @@ -6885,79 +6572,15 @@ "integrity": "sha512-/xhqXP/2A2RSs+J8JNXpiiNVvvNM0oTosNVmQnunlKvq9o4mupHOBAnnzH0lwIPKazXKvAKsVp1kr+H/K4lgoQ==" }, "vscode-languageserver-types": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz", - "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==" - }, - "vscode-nls": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-5.0.0.tgz", - "integrity": "sha512-u0Lw+IYlgbEJFF6/qAqG2d1jQmJl0eyAGJHoAJqr2HT4M2BNuQYSEiSE75f52pXHSJm8AlTjnLLbBFPrdz2hpA==" - }, - "vscode-pug-languageservice": { - "version": "0.31.4", - "resolved": "https://registry.npmjs.org/vscode-pug-languageservice/-/vscode-pug-languageservice-0.31.4.tgz", - "integrity": "sha512-StQWV+v1v+an/pGKNPg4YkODFyKeYpUEzaSAoXIUsIoh7O4Nuv6zjd1M/fPxaMSD6Kk+OH/JGE36hbXsKXOz5A==", - "requires": { - "@volar/code-gen": "0.31.4", - "@volar/shared": "0.31.4", - "@volar/source-map": "0.31.4", - "@volar/transforms": "0.31.4", - "pug-lexer": "^5.0.1", - "pug-parser": "^6.0.0", - "vscode-languageserver-textdocument": "^1.0.3", - "vscode-languageserver-types": "^3.17.0-next.6" - }, - "dependencies": { - "vscode-languageserver-types": { - "version": "3.17.0-next.7", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.0-next.7.tgz", - "integrity": "sha512-KH4zdG1qBXxoso61ChgpeoZYyHGJo8bV7Jv4I+fwQ1Ryy59JAxoZ9GAbhR5TeeafHctLcg6RFvY3m8Jqfu17cg==" - } - } - }, - "vscode-typescript-languageservice": { - "version": "0.31.4", - "resolved": "https://registry.npmjs.org/vscode-typescript-languageservice/-/vscode-typescript-languageservice-0.31.4.tgz", - "integrity": "sha512-nsnRPEfg9t3oDlwzm3WTAv0p83vceqCuxvRo/+N7hXbmtaO7WMGCMvJx0xyIuUDS4NgaEK31oMR9FnX9JNcEQQ==", - "requires": { - "@volar/shared": "0.31.4", - "semver": "^7.3.5", - "upath": "^2.0.1", - "vscode-languageserver-protocol": "^3.17.0-next.12", - "vscode-languageserver-textdocument": "^1.0.3", - "vscode-nls": "^5.0.0" - } + "version": "3.17.0-next.9", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.0-next.9.tgz", + "integrity": "sha512-9/PeDNPYduaoXRUzYpqmu4ZV9L01HGo0wH9FUt+sSHR7IXwA7xoXBfNUlv8gB9H0D2WwEmMomSy1NmhjKQyn3A==" }, "vscode-uri": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.3.tgz", "integrity": "sha512-EcswR2S8bpR7fD0YPeS7r2xXExrScVMxg4MedACaWHEtx9ftCF/qHG1xGkolzTPcEmjTavCQgbVzHUIdTMzFGA==" }, - "vscode-vue-languageservice": { - "version": "0.31.4", - "resolved": "https://registry.npmjs.org/vscode-vue-languageservice/-/vscode-vue-languageservice-0.31.4.tgz", - "integrity": "sha512-Pyvtj5iokBilGDH8KY6bocJh8NcIGoFmUksPOOZKBb+4usEHTBtWw/uoH4hjxWwLszMRQuStkXLMaSKtBIv3gQ==", - "requires": { - "@volar/code-gen": "0.31.4", - "@volar/html2pug": "0.31.4", - "@volar/shared": "0.31.4", - "@volar/source-map": "0.31.4", - "@volar/transforms": "0.31.4", - "@volar/vue-code-gen": "0.31.4", - "@vscode/emmet-helper": "^2.8.3", - "@vue/reactivity": "^3.2.27", - "@vue/shared": "^3.2.27", - "upath": "^2.0.1", - "vscode-css-languageservice": "^5.1.9", - "vscode-html-languageservice": "^4.2.1", - "vscode-json-languageservice": "^4.1.10", - "vscode-languageserver-protocol": "^3.17.0-next.12", - "vscode-languageserver-textdocument": "^1.0.3", - "vscode-pug-languageservice": "0.31.4", - "vscode-typescript-languageservice": "0.31.4" - } - }, "vue": { "version": "3.2.31", "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.31.tgz", @@ -7016,12 +6639,11 @@ } }, "vue-tsc": { - "version": "0.31.4", - "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-0.31.4.tgz", - "integrity": "sha512-8RnKGmQRo/0rbXkyZmKCOdT62fNWyEaMdS/BDAPE+saGNAniUZsjpOSOjAiLwsQc5qgeI9/mY1W3o4tX7H/7MA==", + "version": "0.33.7", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-0.33.7.tgz", + "integrity": "sha512-m5Pl4QsrNjfRmtrbsuQJgNnnvXgMtBFT6/P4kgyqIj0EsrWtcyzj/xrFGIvONuU8+o/ui2AQJxWCF9eoC3yOgQ==", "requires": { - "@volar/shared": "0.31.4", - "vscode-vue-languageservice": "0.31.4" + "@volar/vue-typescript": "0.33.7" } }, "wanakana": { @@ -7088,17 +6710,6 @@ } } }, - "with": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", - "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", - "requires": { - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "assert-never": "^1.2.1", - "babel-walk": "3.0.0-canary-5" - } - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", diff --git a/src/vite/package.json b/src/vite/package.json index da649e36..6ecc455c 100644 --- a/src/vite/package.json +++ b/src/vite/package.json @@ -27,7 +27,7 @@ "esbuild": "^0.14.23", "npm-check-updates": "^11.8.5", "vue": "^3.2.31", - "vue-tsc": "^0.31.4", + "vue-tsc": "^0.33.7", "wanakana": "^4.0.2" }, "devDependencies": { @@ -51,7 +51,7 @@ "stylelint-config-recommended-scss": "4.3.x", "stylelint-scss": "3.21.x", "tailwindcss": "^3.0.x", - "typescript": "^4.4.4", + "typescript": "^4.6.2", "vite": "^2.8.4", "vite-plugin-element-plus": "^0.0.12", "vite-plugin-md": "^0.11.8" diff --git a/src/vite/src/assets/sass/_markdown.scss b/src/vite/src/assets/sass/_markdown.scss index c10153ed..a6ab43c6 100644 --- a/src/vite/src/assets/sass/_markdown.scss +++ b/src/vite/src/assets/sass/_markdown.scss @@ -51,6 +51,12 @@ padding-left: 2em; } +.markdown ol { + list-style-type: decimal; + margin: 0 0 calc(var(--vunit) * 1.5); + padding-left: 2em; +} + // blockquote .markdown blockquote { @apply text-body-light pl-[2em] italic; diff --git a/src/vite/src/assets/sass/_utilities.scss b/src/vite/src/assets/sass/_utilities.scss index b6f11213..942a477f 100644 --- a/src/vite/src/assets/sass/_utilities.scss +++ b/src/vite/src/assets/sass/_utilities.scss @@ -1,6 +1,11 @@ // ==================================================================== // UTILITIES // +// Layout +// +// ux-flexButtonRow ... simple horizontal spacing of * > childrens +// +// // Sizes / Spacings // // ux-maxWidth300/360 @@ -10,11 +15,12 @@ /* @define utilities */ // -------------------------------------------------------------------- -// MAX WIDTH +// MIN/MAX WIDTH +// +// Useful to align *block* and *inline-block* elements: // -// Abstraction of small/medium/wide alignment of vertically -// stacked elements like centered content (with mx-auto) or form -// fields. +// - Use on buttons so they are not too small when label is small. +// - Use on centered buttons stacked vertically so they are aligned. // // Example: // @@ -25,7 +31,43 @@ $maxWidthItems: ("300" 300px, "360" 360px); @each $item in $maxWidthItems { $key: nth($item, 1); $val: nth($item, 2); + ////////////////////////////////////////////////////////////////// + // Output: + // .ux-maxWidth300 { + // max-width: 300px; + // } + ////////////////////////////////////////////////////////////////// .ux-maxWidth#{$key} { max-width: $val; } } + +$minWidthItems: ("100" 100px, "200" 200px); +@each $item in $minWidthItems { + $key: nth($item, 1); + $val: nth($item, 2); + ////////////////////////////////////////////////////////////////// + // Output: + // .ux-minWidth300 { + // min-width: 300px; + // } + ////////////////////////////////////////////////////////////////// + .ux-minWidth#{$key} { + min-width: $val; + } +} + +// -------------------------------------------------------------------- +// FLEX / BUTTON ROW +// +// Simple spacer for button rows +// +// -------------------------------------------------------------------- +.ux-flexButtonRow { + $gutter: 0.5rem; + @apply flex flex-wrap items-center; + margin-left: -$gutter; + > * { + margin-left: $gutter; + } +} diff --git a/src/vite/src/assets/sass/abstracts/_mixins.scss b/src/vite/src/assets/sass/abstracts/_mixins.scss index 2005c0a2..22f3062b 100644 --- a/src/vite/src/assets/sass/abstracts/_mixins.scss +++ b/src/vite/src/assets/sass/abstracts/_mixins.scss @@ -1,12 +1,138 @@ // ==================================================================== // MIXINS // +// Css declaration shortcuts: +// +// button-color() +// font() +// mx() +// my() +// px() +// py() +// // Responsive & Media Queries: // -// screen() +// breakpoint-up() min-width bp : md/lg/xl +// breakpoint-down() max-width bp : md/lg/xl +// screen() custom ranges: mbl/dsk // // ==================================================================== +@use "sass:color" as color; + +// -------------------------------------------------------------------- +// BUTTONS +// +// Helper to create CSS vars & handle states for each button style. +// -------------------------------------------------------------------- +@mixin button-color($bg: blue, $text: #fff, $mix: darken) { + --ko-btn-bg: #{$bg}; + --ko-btn-border: #{$bg}; + --ko-btn-text: #{$text}; + + // a darker shade of the main button color + --ko-btn-bg-darker: #{darken(saturate($bg, 5), 10)}; + + // :hover colors + --ko-btn-hover-text: #{$text}; + + @if $mix == "darken" { + --ko-btn-hover-bg: #{darken(saturate($bg, 5), 10)}; + --ko-btn-hover-border: #{darken(saturate($bg, 5), 10)}; + } @else if $mix == "lighten" { + --ko-btn-hover-bg: #{lighten(saturate($bg, 5), 10)}; + --ko-btn-hover-border: #{lighten(saturate($bg, 5), 10)}; + } @else if $mix == false { + --ko-btn-hover-bg: #{$bg}; + --ko-btn-hover-border: #{$bg}; + } + + // .is-disabled + $--disabled-bg: #{lighten(desaturate($bg, 15), 0)}; + $--disabled-bg: #cdcdcd; // #{color.scale($bg, $saturation: -80%)}; + --ko-btn-disabled-bg: #{$--disabled-bg}; + --ko-btn-disabled-border: #{$--disabled-bg}; + --ko-btn-disabled-text: #757575; + + // outline aka "ghost" buttons + &.is-ghost { + --ko-btn-bg: transparent; + --ko-btn-border: #{$bg}; + --ko-btn-text: var(--ko-btn-bg-darker); + --ko-btn-hover-bg: transparent; + --ko-btn-hover-border: var(--ko-btn-bg-darker); + --ko-btn-hover-text: #{darken(saturate($bg, 10), 20)}; + } +} + +// -------------------------------------------------------------------- +// FONT +// +// Examples: +// +// @include font(16px, 1.3em, 500); +// @include font(16px, 1.2em); +// +// @include font($lineHeight: 1.2em); +// +// @include font($size: 12px, $weight: 500); +// @include font(12px, $weight: 500); +// +// @include font($family: '"Courier New", monospace'); +// +// -------------------------------------------------------------------- +@mixin font($size: null, $lineHeight: null, $weight: null, $family: null) { + @if $size != null { + font-size: $size; + } + + @if $lineHeight != null { + line-height: $lineHeight; + } + + @if $weight != null { + font-weight: $weight; + } + + @if $family != null { + font-family: unquote($family); + } +} + +// -------------------------------------------------------------------- +// MX / MY +// +// Shorthand to set horizontal margins. +// +// Commonly used for negative margins, eg: +// +// @include mx(-10px); +// +// -------------------------------------------------------------------- +@mixin mx($unit) { + margin-left: $unit; + margin-right: $unit; +} +@mixin my($unit) { + margin-top: $unit; + margin-bottom: $unit; +} + +// -------------------------------------------------------------------- +// PX / PY +// +// Shorthand to set horizontal / vertical padding only. +// +// -------------------------------------------------------------------- +@mixin px($unit) { + padding-left: $unit; + padding-right: $unit; +} +@mixin py($unit) { + padding-top: $unit; + padding-bottom: $unit; +} + // -------------------------------------------------------------------- // BREAKPOINT-UP (min-width) // diff --git a/src/vite/src/assets/sass/abstracts/_variables.scss b/src/vite/src/assets/sass/abstracts/_variables.scss index 9172f62f..1552f7ea 100644 --- a/src/vite/src/assets/sass/abstracts/_variables.scss +++ b/src/vite/src/assets/sass/abstracts/_variables.scss @@ -3,7 +3,7 @@ // ==================================================================== // -------------------------------------------------------------------- -// layout / breakpoints (used by breakpoint mixins) +// Layout / breakpoints (used by breakpoint mixins) // // References: // https://getbootstrap.com/docs/5.0/layout/breakpoints/#available-breakpoints @@ -17,7 +17,43 @@ $--bp-lg: 992px; // 992px = 62rem $--bp-xl: 1280px; // 1280px = 80rem // -------------------------------------------------------------------- -// colors +// Borders +// -------------------------------------------------------------------- +$--border-radius-md: 4px; +$--border-radius-lg: 6px; + +// -------------------------------------------------------------------- +// Buttons +// -------------------------------------------------------------------- +$--button-font-size-sm: 14px; +$--button-font-size-md: 14px; +$--button-font-size-lg: 15px; +$--button-font-size-xl: 18px; + +// -------------------------------------------------------------------- +// Colors / Brand (should match tailwind config) +// -------------------------------------------------------------------- +$--color-btn-default: #8e8d8c; + +// main primary color (saturated blue/cyan) +$--color-btn-primary: #3272d1; + +// main red color +$--color-btn-danger: #d9534f; + +// main green color +$--color-btn-success: #4ea84e; + +// utilities +$--color-mix-white: #ffffff; + +// -------------------------------------------------------------------- +// Colors / Text +// -------------------------------------------------------------------- +$--color-text-body: #42413d; + +// -------------------------------------------------------------------- +// Colors ( legacy sass stuff - needs renaming/merging ) // -------------------------------------------------------------------- $--clr-bg-body: #f4f0e5; $--clr-bg-1: #e7e1d3; /* shaded background 1 */ diff --git a/src/vite/src/assets/sass/components/_LeitnerChart.scss b/src/vite/src/assets/sass/components/_LeitnerChart.scss index 49d8983f..4a6083f9 100644 --- a/src/vite/src/assets/sass/components/_LeitnerChart.scss +++ b/src/vite/src/assets/sass/components/_LeitnerChart.scss @@ -74,6 +74,7 @@ width: 100%; padding: 0; color: #444; + font-size: 14px; font-weight: normal; white-space: nowrap; text-align: center; diff --git a/src/vite/src/assets/sass/components/_buttons.scss b/src/vite/src/assets/sass/components/_buttons.scss index 6402f21b..c6a9ab05 100644 --- a/src/vite/src/assets/sass/components/_buttons.scss +++ b/src/vite/src/assets/sass/components/_buttons.scss @@ -1,91 +1,236 @@ // ==================================================================== -// BUTTONS +// KOOHII BUTTONS +// +// Base: +// +// ko-Btn Handles :focus, :hover etc +// +// Colors: +// +// ko-Btn--danger +// ko-Btn--primary +// ko-Btn--success +// +// ko-Btn--editcard +// +// States: +// +// is-ghost Use outline aka "ghost" style +// is-disabled Use grayed out colors +// +// Sizes: +// +// ko-Btn--small ~31px high, 14px text +// ko-Btn ~36px high, medium size, good for forms +// ko-Btn--large ~41px high, good for primary actions/ux +// +// +// @see /ux page for live demos // -// For now, Bootstrap buttons tweaks/overrides // ==================================================================== // -------------------------------------------------------------------- -// fix the hover styles +// Base class // -------------------------------------------------------------------- -.btn, -.btn:hover { +.ko-Btn { + display: inline-block; + font-weight: 400; + line-height: 1; + text-align: center; text-decoration: none; -} + vertical-align: middle; + white-space: nowrap; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + border: 1px solid transparent; + transition: none; -.btn-link { - text-decoration: underline; -} + border-radius: $--border-radius-md; + padding: 0.375rem 0.75rem; -// -------------------------------------------------------------------- -// override the button colors - the BS mixins dont create nice hovers -// -------------------------------------------------------------------- -// NOTE! because the php helper auto-adds `btn-success`, declare other colors *after* -.btn-success { - color: #fff; - background-color: #5cb85c; - border-color: #4cae4c; + // apply colors + background-color: var(--ko-btn-bg); + border-color: var(--ko-btn-border); + color: var(--ko-btn-text); - &:hover { - color: #fff; - background-color: #449d44; - border-color: #398439; + // apply :hover + // apply :focus + &:hover, + &:focus { + background-color: var(--ko-btn-hover-bg); + border-color: var(--ko-btn-hover-border); + color: var(--ko-btn-hover-text); + text-decoration: none; // when applied to + } + + // + &.is-disabled { + &, + &:hover, + &:focus { + cursor: not-allowed; + background-color: var(--ko-btn-disabled-bg); + border-color: var(--ko-btn-disabled-border); + color: var(--ko-btn-disabled-text); + } } } -.btn-danger { - color: #fff; - background-color: #d9534f; - border-color: #d43f3a; +// -------------------------------------------------------------------- +// Colors +// -------------------------------------------------------------------- +.ko-Btn { + @include button-color($bg: $--color-btn-default); - &:hover { - color: #fff; - background-color: #c9302c; - border-color: #ac2925; + // (override) warm color for the default outline button + &.is-ghost { + --ko-btn-border: #d4cdba; + --ko-btn-text: #6f6961; + --ko-btn-hover-text: #3f3931; + --ko-btn-hover-border: #928c7d; } } -// set :focus text color (override Bootstrap's selector created by their mixin) -.btn-success, -.btn-danger { - .btn-check:focus + &, - &:focus { - color: #fff; - } +.ko-Btn--primary { + @include button-color($bg: $--color-btn-primary); +} +.ko-Btn--danger { + @include button-color($bg: $--color-btn-danger); +} +.ko-Btn--success { + @include button-color($bg: $--color-btn-success); } // -------------------------------------------------------------------- -// GHOST BUTTON +// Sizes +// +// Note selector specificity required due to element's `.el-button.is-round` // -------------------------------------------------------------------- -.btn-ghost { - color: #6f6961; - background-color: inherit; - border-color: $--clr-bg-1s; +.ko-Btn { + @include font($--button-font-size-md); + padding: 10px 12px; // ~36px height + border-radius: $--border-radius-lg; } -.btn-default { - background-color: $--clr-bg-1; - color: #444; - border-color: $--clr-bg-1s; +.ko-Btn--small { + @include font($--button-font-size-sm); + padding: 8px 10px; // ~31 px height + border-radius: $--border-radius-lg; } -/* cf. BootstrapHelper :: _bs_button_with_icon() .fa .far .fas */ -.btn i { - margin-right: 0.5em; +.ko-Btn--large { + @include font($--button-font-size-lg); + padding: 12px 14px; // ~41px height + border-radius: $--border-radius-lg; } -/* push buttons (note :hover & :active same style due to touch :active -> :hover */ -.btn-go { - color: #fff; - background-color: #5cb85c; - border: none; - border-bottom: 3px solid #318a31; +// -------------------------------------------------------------------- +// Shapes +// -------------------------------------------------------------------- + +// -------------------------------------------------------------------- +// Misc. special styles +// -------------------------------------------------------------------- + +// used on legacy homepage, maybe reuse for something else later +// +// -------------------------------------------------------------------- +.ko-Btn--srs { + border-radius: $--border-radius-lg; + border-width: 0 0 0 0; + border-bottom: 3px solid #318a31; + + @include font($--button-font-size-xl); + padding: 15px 1rem 13px; // ~49px height + + // flashcard count on the button label + strong { + color: #fff; + } + + &:active, + &:focus, + &:hover { + border-bottom-width: 1px; + margin-top: 2px; + } + + // srs button colors + &.is-srs-due { + --ko-btn-text: #502a00; + --ko-btn-hover-text: #502a00; + --ko-btn-bg: #f7a247; + --ko-btn-hover-bg: #f7a247; + border-bottom-color: #d2633f; + } + &.is-srs-failed { + --ko-btn-text: #601008; + --ko-btn-hover-text: #601008; + --ko-btn-bg: #f86464; + --ko-btn-hover-bg: #f86464; + border-bottom-color: #d2633f; + } + &.is-srs-new { + --ko-btn-text: #0c2b5a; + --ko-btn-hover-text: #0c2b5a; + --ko-btn-bg: #79b8e9; + --ko-btn-hover-bg: #79b8e9; + border-bottom-color: #3d83ac; + } } -.btn-lg.btn-go { - padding: 12px 16px 10px; + +// -------------------------------------------------------------------- +// A "sample" button as used in the Help page, when documentation +// refers to a button (ie. "select *Some Button* to do xyz"). +// +// The Button +// -------------------------------------------------------------------- +.ko-ExBtn { + padding: 0.2em 0.4em; + border-radius: 0.25em; + @include mx(0.25em); + border: 1px solid #d4cdba; + color: #6f6961; + + &--danger { + $text: $--color-btn-danger; + border-color: $text; + color: #{darken(saturate($text, 5), 10)}; + } + + &--success { + $text: $--color-btn-success; + border-color: $text; + color: #{darken(saturate($text, 5), 10)}; + } } diff --git a/src/vite/src/assets/sass/home.build.scss b/src/vite/src/assets/sass/home.build.scss index 42d24f96..b609a010 100644 --- a/src/vite/src/assets/sass/home.build.scss +++ b/src/vite/src/assets/sass/home.build.scss @@ -20,6 +20,7 @@ @import "./layout/_layout.scss"; // components +@import "./components/_buttons.scss"; @import "./_navbar.scss"; // pages diff --git a/src/vite/src/assets/sass/layout/_layout.scss b/src/vite/src/assets/sass/layout/_layout.scss index c304cf0f..42ace8da 100644 --- a/src/vite/src/assets/sass/layout/_layout.scss +++ b/src/vite/src/assets/sass/layout/_layout.scss @@ -67,6 +67,7 @@ $GRID_GUTTER_X: 15px; // A few places can afford columns in tablet portrait mode (md) .col-md-3, +.col-md-6, .col-md-9 { @apply grow-0 w-full; padding-left: $GRID_GUTTER_X; @@ -76,6 +77,9 @@ $GRID_GUTTER_X: 15px; .col-md-3 { @apply w-3/12; } + .col-md-6 { + @apply w-6/12; + } .col-md-9 { @apply w-9/12; } diff --git a/src/vite/src/assets/sass/legacy/_widgets.scss b/src/vite/src/assets/sass/legacy/_widgets.scss index 08849776..4229bdea 100644 --- a/src/vite/src/assets/sass/legacy/_widgets.scss +++ b/src/vite/src/assets/sass/legacy/_widgets.scss @@ -148,8 +148,10 @@ .uiTable { // crude solution for horizontal scrolling on small screens - overflow-y: auto; _overflow: auto; margin: 0 0 1em; border-right:1px dotted #bdbcaa; -} + overflow-y: auto; + _overflow: auto; + margin: 0 0 1em; + } .uiTabular { border:1px solid #BDBCAA; border-top:1px solid #D9D8CE; width:100%; } /* thead */ @@ -167,7 +169,7 @@ .uiTabular th a.sortdesc { padding-right:12px; background:url(/assets/legacy/widgets-selecttable.gif) no-repeat 100% -72px; } /* tbody */ .uiTabular td { - padding:8px 10px; + padding:10px 10px; color:#666; font-size:13px; line-height:1.1em; diff --git a/src/vite/src/assets/sass/legacy/vendor/yui2-container.css b/src/vite/src/assets/sass/legacy/vendor/yui2-container.css index e3c14ce1..3175466a 100644 --- a/src/vite/src/assets/sass/legacy/vendor/yui2-container.css +++ b/src/vite/src/assets/sass/legacy/vendor/yui2-container.css @@ -4,4 +4,4 @@ Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html version: 2.9.0 */ -.yui-overlay,.yui-panel-container{visibility:hidden;position:absolute;z-index:2}.yui-panel{position:relative}.yui-panel-container form{margin:0}.mask{z-index:1;display:none;position:absolute;top:0;left:0;right:0;bottom:0}.mask.block-scrollbars{overflow:auto}.masked select,.drag select,.hide-select select{_visibility:hidden}.yui-panel-container select{_visibility:inherit}.hide-scrollbars,.hide-scrollbars *{overflow:hidden}.hide-scrollbars select{display:none}.show-scrollbars{overflow:auto}.yui-panel-container.show-scrollbars,.yui-tt.show-scrollbars{overflow:visible}.yui-panel-container.show-scrollbars .underlay,.yui-tt.show-scrollbars .yui-tt-shadow{overflow:auto}.yui-panel-container.shadow .underlay.yui-force-redraw{padding-bottom:1px}.yui-effect-fade .underlay,.yui-effect-fade .yui-tt-shadow{display:none}.yui-tt-shadow{position:absolute}.yui-override-padding{padding:0!important}.yui-panel-container .container-close{overflow:hidden;text-indent:-10000em;text-decoration:none}.yui-overlay.yui-force-redraw,.yui-panel-container.yui-force-redraw{margin-bottom:1px}.yui-skin-sam .mask{background-color:#000;opacity:.25;filter:alpha(opacity=25)}.yui-skin-sam .yui-panel-container{padding:0 1px;*padding:2px}.yui-skin-sam .yui-panel{position:relative;left:0;top:0;border-style:solid;border-width:1px 0;border-color:#808080;z-index:1;*border-width:1px;*zoom:1;_zoom:normal}.yui-skin-sam .yui-panel .hd,.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{border-style:solid;border-width:0 1px;border-color:#808080;margin:0 -1px;*margin:0;*border:0}.yui-skin-sam .yui-panel .hd{border-bottom:solid 1px #ccc}.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{background-color:#f2f2f2}.yui-skin-sam .yui-panel .hd{padding:0 10px;font-size:93%;line-height:2;*line-height:1.9;font-weight:bold;color:#000;background:red}.yui-skin-sam .yui-panel .bd{padding:10px}.yui-skin-sam .yui-panel .ft{border-top:solid 1px #808080;padding:5px 10px;font-size:77%}.yui-skin-sam .container-close{position:absolute;top:5px;right:6px;width:25px;height:15px;background:red;cursor:pointer}.yui-skin-sam .yui-panel-container .underlay{right:-1px;left:-1px}.yui-skin-sam .yui-panel-container.matte{padding:9px 10px;background-color:#fff}.yui-skin-sam .yui-panel-container.shadow{_padding:2px 4px 0 2px}.yui-skin-sam .yui-panel-container.shadow .underlay{position:absolute;top:2px;left:-3px;right:-3px;bottom:-3px;*top:4px;*left:-1px;*right:-1px;*bottom:-1px;_top:0;_left:0;_right:0;_bottom:0;_margin-top:3px;_margin-left:-1px;background-color:#000;opacity:.12;filter:alpha(opacity=12)}.yui-skin-sam .yui-dialog .ft{border-top:0;padding:0 10px 10px 10px;font-size:100%}.yui-skin-sam .yui-dialog .ft .button-group{display:block;text-align:right}.yui-skin-sam .yui-dialog .ft button.default{font-weight:bold}.yui-skin-sam .yui-dialog .ft span.default{border-color:#304369;background-position:0 -1400px}.yui-skin-sam .yui-dialog .ft span.default .first-child{border-color:#304369}.yui-skin-sam .yui-dialog .ft span.default button{color:#fff}.yui-skin-sam .yui-dialog .ft span.yui-button-disabled{background-position:0 -1500px;border-color:#ccc}.yui-skin-sam .yui-dialog .ft span.yui-button-disabled .first-child{border-color:#ccc}.yui-skin-sam .yui-dialog .ft span.yui-button-disabled button{color:#a6a6a6}.yui-skin-sam .yui-simple-dialog .bd .yui-icon{background:red;width:16px;height:16px;margin-right:10px;float:left}.yui-skin-sam .yui-simple-dialog .bd span.blckicon{background-position:0 -1100px}.yui-skin-sam .yui-simple-dialog .bd span.alrticon{background-position:0 -1050px}.yui-skin-sam .yui-simple-dialog .bd span.hlpicon{background-position:0 -1150px}.yui-skin-sam .yui-simple-dialog .bd span.infoicon{background-position:0 -1200px}.yui-skin-sam .yui-simple-dialog .bd span.warnicon{background-position:0 -1900px}.yui-skin-sam .yui-simple-dialog .bd span.tipicon{background-position:0 -1250px}.yui-skin-sam .yui-tt .bd{position:relative;top:0;left:0;z-index:1;color:#000;padding:2px 5px;border-color:#d4c237 #A6982b #a6982b #A6982B;border-width:1px;border-style:solid;background-color:#ffee69}.yui-skin-sam .yui-tt.show-scrollbars .bd{overflow:auto}.yui-skin-sam .yui-tt-shadow{top:2px;right:-3px;left:-3px;bottom:-3px;background-color:#000}.yui-skin-sam .yui-tt-shadow-visible{opacity:.12;filter:alpha(opacity=12)} +.yui-overlay,.yui-panel-container{visibility:hidden;position:absolute;z-index:2}.yui-panel{position:relative}.yui-panel-container form{margin:0}.mask{z-index:1;display:none;position:absolute;top:0;left:0;right:0;bottom:0}.mask.block-scrollbars{overflow:auto}.masked select,.drag select,.hide-select select{_visibility:hidden}.yui-panel-container select{_visibility:inherit}.hide-scrollbars,.hide-scrollbars *{overflow:hidden}.hide-scrollbars select{display:none}.show-scrollbars{overflow:auto}.yui-panel-container.show-scrollbars,.yui-tt.show-scrollbars{overflow:visible}.yui-panel-container.show-scrollbars .underlay,.yui-tt.show-scrollbars .yui-tt-shadow{overflow:auto}.yui-panel-container.shadow .underlay.yui-force-redraw{padding-bottom:1px}.yui-effect-fade .underlay,.yui-effect-fade .yui-tt-shadow{display:none}.yui-tt-shadow{position:absolute}.yui-override-padding{padding:0!important}.yui-panel-container .container-close{overflow:hidden;text-indent:-10000em;text-decoration:none}.yui-overlay.yui-force-redraw,.yui-panel-container.yui-force-redraw{margin-bottom:1px}.yui-skin-sam .mask{background-color:#000;opacity:.25;filter:alpha(opacity=25)}.yui-skin-sam .yui-panel-container{padding:0 1px;}.yui-skin-sam .yui-panel{position:relative;left:0;top:0;border-style:solid;border-width:1px 0;border-color:#808080;z-index:1;}.yui-skin-sam .yui-panel .hd,.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{border-style:solid;border-width:0 1px;border-color:#808080;margin:0 -1px;}.yui-skin-sam .yui-panel .hd{border-bottom:solid 1px #ccc}.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{background-color:#f2f2f2}.yui-skin-sam .yui-panel .hd{padding:0 10px;font-size:93%;line-height:2;font-weight:bold;color:#000;background:red}.yui-skin-sam .yui-panel .bd{padding:10px}.yui-skin-sam .yui-panel .ft{border-top:solid 1px #808080;padding:5px 10px;font-size:77%}.yui-skin-sam .container-close{position:absolute;top:5px;right:6px;width:25px;height:15px;background:red;cursor:pointer}.yui-skin-sam .yui-panel-container .underlay{right:-1px;left:-1px}.yui-skin-sam .yui-panel-container.matte{padding:9px 10px;background-color:#fff}.yui-skin-sam .yui-panel-container.shadow{_padding:2px 4px 0 2px}.yui-skin-sam .yui-panel-container.shadow .underlay{position:absolute;top:2px;left:-3px;right:-3px;bottom:-3px;_top:0;_left:0;_right:0;_bottom:0;_margin-top:3px;_margin-left:-1px;background-color:#000;opacity:.12;filter:alpha(opacity=12)}.yui-skin-sam .yui-dialog .ft{border-top:0;padding:0 10px 10px 10px;font-size:100%}.yui-skin-sam .yui-dialog .ft .button-group{display:block;text-align:right}.yui-skin-sam .yui-dialog .ft button.default{font-weight:bold}.yui-skin-sam .yui-dialog .ft span.default{border-color:#304369;background-position:0 -1400px}.yui-skin-sam .yui-dialog .ft span.default .first-child{border-color:#304369}.yui-skin-sam .yui-dialog .ft span.default button{color:#fff}.yui-skin-sam .yui-dialog .ft span.yui-button-disabled{background-position:0 -1500px;border-color:#ccc}.yui-skin-sam .yui-dialog .ft span.yui-button-disabled .first-child{border-color:#ccc}.yui-skin-sam .yui-dialog .ft span.yui-button-disabled button{color:#a6a6a6}.yui-skin-sam .yui-simple-dialog .bd .yui-icon{background:red;width:16px;height:16px;margin-right:10px;float:left}.yui-skin-sam .yui-simple-dialog .bd span.blckicon{background-position:0 -1100px}.yui-skin-sam .yui-simple-dialog .bd span.alrticon{background-position:0 -1050px}.yui-skin-sam .yui-simple-dialog .bd span.hlpicon{background-position:0 -1150px}.yui-skin-sam .yui-simple-dialog .bd span.infoicon{background-position:0 -1200px}.yui-skin-sam .yui-simple-dialog .bd span.warnicon{background-position:0 -1900px}.yui-skin-sam .yui-simple-dialog .bd span.tipicon{background-position:0 -1250px}.yui-skin-sam .yui-tt .bd{position:relative;top:0;left:0;z-index:1;color:#000;padding:2px 5px;border-color:#d4c237 #A6982b #a6982b #A6982B;border-width:1px;border-style:solid;background-color:#ffee69}.yui-skin-sam .yui-tt.show-scrollbars .bd{overflow:auto}.yui-skin-sam .yui-tt-shadow{top:2px;right:-3px;left:-3px;bottom:-3px;background-color:#000}.yui-skin-sam .yui-tt-shadow-visible{opacity:.12;filter:alpha(opacity=12)} diff --git a/src/vite/src/assets/sass/main.build.scss b/src/vite/src/assets/sass/main.build.scss index 58f30932..6cf2884f 100644 --- a/src/vite/src/assets/sass/main.build.scss +++ b/src/vite/src/assets/sass/main.build.scss @@ -57,14 +57,6 @@ } } -/* ajax table container div (cf. ./legacy/_widgets.scss) */ -.uiTable { - overflow-y: auto; - _overflow: auto; - margin: 0 0 1em; - border-right: 1px dotted #bdbcaa; -} - /* when footer gradient is used */ body.with-footer { background: #f0ddd4; @@ -130,10 +122,36 @@ a.admin-edit { -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); } -/* content boxes */ -.padded-box { - @apply px-4 py-4; - background-color: $--clr-bg-1; +.ko-Box { + --ko-box-px: 14px; + --ko-box-py: 14px; + --ko-box-bg: #e7e1d3; + + background-color: var(--ko-box-bg); + border-color: var(--ko-box-bg); + border-width: 2px; + border-radius: $--border-radius-lg; + @include px(var(--ko-box-px)); + @include py(var(--ko-box-py)); + + // a style of bordered box, clear filling + &--stroke { + background: transparent; + border-width: 2px; + border-color: var(--ko-box-bg, transparent); + } + + // colors + &--danger { + --ko-box-bg: #ffd1c9; + } + &--danger#{&}--stroke { + --ko-box-bg: #F2A5A5; // slightly darker for border variant + } + + &--success { + --ko-box-bg: #d1e2bb; + } } /* ---------------------------- */ @@ -353,36 +371,6 @@ div.col-box-bis { padding-top: 24px; } -/* ---------------------------- */ -/* Site wide elements */ -/* ---------------------------- */ - -/* Study and SRS */ -.btn-srs strong { - color: #fff; - font-size: 120%; -} -.btn-srs.btn-failed { - color: #601008; - background-color: #f86464; - border-bottom: 3px solid rgb(210, 99, 63); -} -.btn-srs.btn-due { - color: #502a00; - background-color: #f7a247; - border-bottom: 3px solid rgb(210, 99, 63); -} -.btn-srs.btn-new { - color: #0c2b5a; - background-color: #79b8e9; - border-bottom: 3px solid rgb(61, 131, 172); -} - -.btn-srs:active { - border-bottom: 0; - margin-top: 3px; -} - /* ---------------------------- */ /* Footer & Support (Nov 2016) */ /* ---------------------------- */ @@ -854,11 +842,6 @@ table.lessons td { min-height: 3em; } -#home-qs .btn-go { - font-size: 18px; - min-width: 150px; -} - #home-qs a { text-decoration: none; } @@ -887,7 +870,7 @@ table.lessons td { * ---------------------------- */ .ko-CustomReviewForm { - @extend .padded-box; + @extend .ko-Box; @apply rounded; font-size: 14px; min-height: 120px; @@ -1035,37 +1018,6 @@ table.lessons td { margin: 10px 0; } -/* ------------------ */ -/* Social */ -/* ------------------ */ - -#custom-tweet-button { - margin: 2.5em 0 0; - max-width: 125px; - text-align: center; -} -#custom-tweet-button a { - display: inline-block; - padding: 4px 8px; - font-weight: bold; - font-size: 18px; - color: #fff; - cursor: pointer; - text-decoration: none; - background: #4faeec; /*1b95e0*/ - border-radius: 3px; -} -#custom-tweet-button i { - width: 16px; - padding: 0 0.5em 0 0; - text-align: center; - color: #fff; -} -#custom-tweet-button span { - font-family: "Helvetica Neue", Arial, sans-serif; - font-size: 0.8em; -} - /* ------------------ */ /* CJK Fonts */ /* ------------------ */ @@ -1116,6 +1068,17 @@ table.lessons td { background: var(--bg); } +// -------------------------------------------------------------------- +// Restudy List +// -------------------------------------------------------------------- +.ko-RestudyList { + // small "learned" tag in the Restudy List + &-learned { + @apply px-[.4em] py-[.3em] rounded; + @apply bg-[#6cbe6b] text-[#fff]; + } +} + // -------------------------------------------------------------------- // (last) tailwind utilities // -------------------------------------------------------------------- diff --git a/src/vite/src/assets/sass/manage.build.scss b/src/vite/src/assets/sass/manage.build.scss index a3041967..9d1946ea 100644 --- a/src/vite/src/assets/sass/manage.build.scss +++ b/src/vite/src/assets/sass/manage.build.scss @@ -28,9 +28,6 @@ } /* remove flashcards list */ -.selection-table .uiTabular td { - padding: 4px 10px; -} .selection-table .uiTabular tbody td { cursor: pointer; } diff --git a/src/vite/src/assets/sass/pages/_about-support.scss b/src/vite/src/assets/sass/pages/_about-support.scss index 5763aab8..f031f86e 100644 --- a/src/vite/src/assets/sass/pages/_about-support.scss +++ b/src/vite/src/assets/sass/pages/_about-support.scss @@ -38,18 +38,11 @@ } } -.btn-patreon { - color: #fff; - background: #eb491d; - &:hover { - color: #fff; - } +// extend our base buttons +.ko-Btn--patreon { + @include button-color($bg: #eb491d, $mix: lighten); } -.btn-paypal { - color: #fff; - background: #40acda; - &:hover { - color: #fff; - } +.ko-Btn--paypal { + @include button-color($bg: #40acda, $mix: lighten); } diff --git a/src/vite/src/assets/sass/pages/_landing-page.scss b/src/vite/src/assets/sass/pages/_landing-page.scss index 08ceb4d7..a5495365 100644 --- a/src/vite/src/assets/sass/pages/_landing-page.scss +++ b/src/vite/src/assets/sass/pages/_landing-page.scss @@ -201,13 +201,13 @@ section { text-decoration: none; } -#its-free .btn-signup { +#its-free .ko-ButtonSignup { background-color: #a4156c; + border-radius: 0.25rem; padding: 21px 82px; color: #fff; font-size: 21px; line-height: 1em; - margin-bottom: 1em; text-decoration: none; box-shadow: 0 1px 2px 1px rgba(0, 0, 0, 0.2); } diff --git a/src/vite/src/assets/sass/pages/_review-home.scss b/src/vite/src/assets/sass/pages/_review-home.scss index 846bae23..4d5aaeec 100644 --- a/src/vite/src/assets/sass/pages/_review-home.scss +++ b/src/vite/src/assets/sass/pages/_review-home.scss @@ -17,29 +17,13 @@ margin: 2px 0 0; } -/* due/new/failed review buttons */ -#srs-home_actions { - margin: 0 0 1em; -} -#srs-home_actions .btn { - margin-right: 0.5em; - margin-bottom: 0.4em; -} -#srs-home_actions .btn-lg { - padding: 10px 15px; - font-size: 16px; -} /* helps fit new/due/restudy in there */ - @media (max-width: 374px) { - #srs-home_actions .btn-lg { + #srs-home_actions .ko-Btn--srs { font-size: 13px; margin-right: 5px; } /* iPhone 5 */ } -/*#srs-home_actions .fa-cog { font-size:120%; } -#srs-home_actions .btn-align-right { float:right; }*/ - /* ---------------------------- */ /* Due cards graph */ /* ---------------------------- */ diff --git a/src/vite/src/assets/sass/study-base.build.scss b/src/vite/src/assets/sass/study-base.build.scss index 8ae3aa78..170d81fc 100644 --- a/src/vite/src/assets/sass/study-base.build.scss +++ b/src/vite/src/assets/sass/study-base.build.scss @@ -354,40 +354,6 @@ /* Learned */ /* ------------------ */ -/* unlike search box, these blocks do not extend to edges, so they are distinct - from the search bar, and appear as part of the main content */ -.study-action-comp { - @apply py-2 px-4; -} -.study-action-comp h3, -.study-action-comp .btn { - font-size: 18px; -} -.study-action-comp h3 { - font-weight: normal; - line-height: 34px; -} - -/* tighten buttons a bit*/ -.study-action-comp .btn { - padding: 7px 12px; - line-height: 1em; -} - -/* restudy pane */ -#study-restudy { - background: #ff7875; -} -#study-restudy, -#study-restudy h3 { - color: #861c1c; -} -#study-restudy .btn-primary { - background: inherit; - border-color: rgba(134, 28, 28, 0.4); - color: #fff; -} - /* learned pane */ #study-learned { background: #c7dfa9; @@ -399,20 +365,6 @@ color: #0f7439; } -#study-learned .dismiss-msg { - font-size: 18px; - color: #457a45; -} -#study-learned .btn-dismiss .fa { - margin: 0; -} - -#study-learned .btn-danger { - border-color: #26a65b; - color: #06863b; - background: inherit; -} /* clear */ - /* ------------------- */ /* Search autocomplete */ /* ------------------- */ @@ -466,12 +418,6 @@ color: #444; } /* small images in dropdown */ -/* failed kanji */ -table.failed-kanji td { - background-color: #fff; - border-top: 1px solid #eee; -} - @include breakpoint-up(lg) { /* less contrating themes for desktop sidebar */ #browse { diff --git a/src/vite/src/assets/sass/vendor/_bootstrap.scss b/src/vite/src/assets/sass/vendor/_bootstrap.scss index 4642a3ae..974e8003 100644 --- a/src/vite/src/assets/sass/vendor/_bootstrap.scss +++ b/src/vite/src/assets/sass/vendor/_bootstrap.scss @@ -1,18 +1,16 @@ // ==================================================================== // Selective import of Bootstrap 5 * FORMS *. // -// - we just want the forms, since styling forms is a PITA +// - we just want the forms, since styling forms is a PITA, +// and they are reset by tailwind's included `normalize` // // - we want to avoid most everything else in Bootstrap since it // does not mix well with the atomic css approach of BEM/tailwind // -// - we also need default styles to all form elements, since they are -// reset by tailwind's included `normalize` -// // - we DONT want Bootstrap's "reboot" since it is a fork of normalize, // which is already included in tailwind // -// - design wise, Bootstrap's rounded input styles fits well on Koohii. +// - design wise, Bootstrap's rounded input styles fits well on Koohii // // @see https://getbootstrap.com/docs/5.0/customize/sass/ // @@ -39,13 +37,6 @@ $input-disabled-border-color: $--clr-bg-1s; $input-font-size: 15px; $input-placeholder-color: #9b9b9b; -$btn-border-radius: 0.25rem; -$btn-font-size: 14px; -$btn-transition: none; -// $btn-padding-y-lg: $input-btn-padding-y-lg; -// $btn-padding-x-lg: $input-btn-padding-x-lg; -$btn-font-size-lg: 18px; - $form-feedback-invalid-color: #a94442; // generated with icones.js <3 $form-feedback-icon-invalid: url('data:image/svg+xml,'); @@ -56,12 +47,6 @@ $form-feedback-icon-invalid: url('data:image/svg+xml, { console.log("@entry-styleguide"); diff --git a/src/vite/src/vue/KoohiiEditStory.vue b/src/vite/src/vue/KoohiiEditStory.vue index d6cf431b..14f766df 100644 --- a/src/vite/src/vue/KoohiiEditStory.vue +++ b/src/vite/src/vue/KoohiiEditStory.vue @@ -3,6 +3,7 @@
+
@@ -75,7 +76,7 @@ name="txtStory" > -
+
Share this story
-
+
@@ -141,7 +142,7 @@ type="submit" name="doLearned" value="Add to learned list" - class="btn btn-success" + class="ko-Btn ko-Btn--success ko-Btn--small" />
@@ -222,6 +223,7 @@ export default defineComponent({ initFavoriteStory: { type: Boolean, default: false }, // Study page only, "Add to learned list" functionality + fromRestudyList: { type: Boolean, default: false }, showLearnButton: { type: Boolean, default: false }, showLearnedMessage: { type: Boolean, default: false }, diff --git a/src/vite/src/vue/recognition/RecognitionApp.vue b/src/vite/src/vue/recognition/RecognitionApp.vue index 1b3468ae..b94c1abe 100644 --- a/src/vite/src/vue/recognition/RecognitionApp.vue +++ b/src/vite/src/vue/recognition/RecognitionApp.vue @@ -23,7 +23,7 @@ > @@ -56,7 +56,7 @@
-
diff --git a/src/vite/src/vue/styleguide/Styleguide.vue b/src/vite/src/vue/styleguide/Styleguide.vue new file mode 100644 index 00000000..be7568ae --- /dev/null +++ b/src/vite/src/vue/styleguide/Styleguide.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/src/vite/src/vue/styleguide/index.vue b/src/vite/src/vue/styleguide/index.vue deleted file mode 100644 index d3061cd5..00000000 --- a/src/vite/src/vue/styleguide/index.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - - - diff --git a/src/vite/tailwind.config.js b/src/vite/tailwind.config.js index 78b36382..7f347b2b 100644 --- a/src/vite/tailwind.config.js +++ b/src/vite/tailwind.config.js @@ -20,11 +20,25 @@ module.exports = { danger: { DEFAULT: "#9f0e0b", + dark: "#D23C3C", + darker: "#BD2420", }, shaded: { DEFAULT: "#e7e1d3", }, + + success: { + dark: "#479947", + darker: "#2C892C", + }, + + transparent: "transparent", + + warm: { + DEFAULT: "#87847D", + light: "#A9A396", + }, }, // redeclare to remove the baked-in line-height, and add `md` alias diff --git a/src/web/.htaccess_default b/src/web/.htaccess_default index fabcbed5..9d309772 100644 --- a/src/web/.htaccess_default +++ b/src/web/.htaccess_default @@ -1,7 +1,32 @@ +# webfonts +AddType application/vnd.ms-fontobject .eot +AddType application/x-font-opentype .otf +AddType application/x-font-ttf .ttf +AddType application/x-font-woff .woff +AddType application/font-woff2 .woff2 +AddType image/svg+xml .svg + + + ExpiresActive On + # media (change the path/file name when updating those files) + ExpiresByType image/gif "access plus 1 month" + ExpiresByType image/jpg "access plus 1 month" + ExpiresByType image/jpeg "access plus 1 month" + ExpiresByType image/png "access plus 1 month" + ExpiresByType image/svg "access plus 1 month" + ExpiresByType image/svg+xml "access plus 1 year" + # fonts (change the path/file name when updating those files) + ExpiresByType application/vnd.ms-fontobject "access plus 1 year" + ExpiresByType application/x-font-opentype "access plus 1 year" + ExpiresByType application/x-font-ttf "access plus 1 year" + ExpiresByType application/x-font-woff "access plus 1 year" + ExpiresByType application/font-woff2 "access plus 1 year" + + RewriteEngine On - # php handler for versioning of front end assets + # set far future expire headers for hashed assets RewriteRule ^(.*)\.[a-z0-9]+\.(css|js)$ /version/cache.php?file=$0 [L] # we skip all files with .something