j1-template 2020.0.22 → 2020.0.24
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/_includes/themes/j1/layouts/content_generator_page.html +1 -1
- data/_includes/themes/j1/layouts/content_generator_post.html +63 -161
- data/_includes/themes/j1/modules/connectors/ad/google-adsense.html +14 -0
- data/_includes/themes/j1/modules/connectors/analytic/google-analytics.html +1 -3
- data/_includes/themes/j1/modules/connectors/comment/disqus.html +37 -24
- data/_includes/themes/j1/modules/navigator/generator.html +8 -3
- data/_includes/themes/j1/modules/navigator/procedures/topsearch.proc +36 -26
- data/_includes/themes/j1/procedures/layouts/module_writer.proc +1 -1
- data/_includes/themes/j1/procedures/posts/create_series_header.proc +9 -5
- data/assets/data/banner.html +1 -1
- data/assets/data/fam.html +124 -0
- data/assets/data/mmenu_sidebar.html +3 -3
- data/assets/data/panel.html +9 -9
- data/assets/data/quicklinks.html +13 -13
- data/assets/error_pages/HTTP204.html +1 -0
- data/assets/error_pages/HTTP400.html +3 -2
- data/assets/error_pages/HTTP401.html +3 -2
- data/assets/error_pages/HTTP403.html +3 -2
- data/assets/error_pages/HTTP404.html +3 -2
- data/assets/error_pages/HTTP500.html +3 -2
- data/assets/error_pages/HTTP501.html +3 -2
- data/assets/error_pages/HTTP502.html +3 -2
- data/assets/error_pages/HTTP503.html +3 -2
- data/assets/error_pages/HTTP520.html +3 -2
- data/assets/error_pages/HTTP521.html +3 -2
- data/assets/error_pages/HTTP533.html +3 -2
- data/assets/themes/j1/adapter/js/{ssm.js → fam.js} +248 -138
- data/assets/themes/j1/adapter/js/framer.js +72 -56
- data/assets/themes/j1/adapter/js/gallery_customizer.js +2 -1
- data/assets/themes/j1/adapter/js/j1.js +8 -2
- data/assets/themes/j1/adapter/js/{searcher.js → lunr_search.js} +68 -65
- data/assets/themes/j1/adapter/js/toccer.js +62 -30
- data/assets/themes/j1/core/css/bootstrap.css +7154 -0
- data/assets/themes/j1/core/css/bootstrap.min.css +6 -0
- data/assets/themes/j1/core/css/custom.scss +28 -0
- data/assets/themes/j1/core/css/globals.css +14523 -0
- data/assets/themes/j1/core/css/globals.min.css +1 -0
- data/assets/themes/j1/core/css/globals.scss +28 -0
- data/assets/themes/j1/core/css/theme_extensions.css +11558 -0
- data/assets/themes/j1/core/css/theme_extensions.min.css +1 -0
- data/assets/themes/j1/core/css/themes/bootstrap/bootstrap.css +7 -4
- data/assets/themes/j1/core/css/themes/bootstrap/bootstrap.min.css +2 -2
- data/assets/themes/j1/core/css/themes/uno-dark/bootstrap.css +7 -4
- data/assets/themes/j1/core/css/themes/uno-dark/bootstrap.min.css +2 -2
- data/assets/themes/j1/core/css/themes/uno-light/bootstrap.css +514 -417
- data/assets/themes/j1/core/css/themes/uno-light/bootstrap.min.css +2 -2
- data/assets/themes/j1/core/css/uno.css +11823 -0
- data/assets/themes/j1/core/css/uno.min.css +1 -0
- data/assets/themes/j1/core/css/uno.scss +28 -0
- data/assets/themes/j1/core/css/vendor.css +5 -4
- data/assets/themes/j1/core/css/vendor.min.css +1 -1
- data/assets/themes/j1/core/css/vendor.scss +28 -0
- data/assets/themes/j1/core/js/template.js +6 -11
- data/assets/themes/j1/core/js/template.js.map +1 -1
- data/assets/themes/j1/core/js/template.min.js +1 -1
- data/assets/themes/j1/modules/bmd/js/bootstrap-material-design.js +6 -0
- data/assets/themes/j1/modules/cash/js/cash.js +1374 -0
- data/assets/themes/j1/modules/cash/js/cash.min.js +42 -0
- data/assets/themes/j1/modules/fam/css/uno/fam.css +369 -0
- data/assets/themes/j1/modules/fam/js/fam.js +477 -0
- data/assets/themes/j1/modules/iframeResizer/examples/frame.nested.html +1 -1
- data/assets/themes/j1/modules/iframeResizer/js/{iframeResizer.js → resizer.js} +0 -0
- data/assets/themes/j1/modules/iframeResizer/js/{iframeResizer.map → resizer.map} +0 -0
- data/assets/themes/j1/modules/iframeResizer/js/{iframeResizer.min.js → resizer.min.js} +0 -0
- data/assets/themes/j1/modules/jquery/js/require.js +2145 -0
- data/assets/themes/j1/modules/jquery/js/require.min.js +5 -0
- data/assets/themes/j1/modules/lunrSearch/css/lunr_search.css +32 -0
- data/assets/themes/j1/modules/lunrSearch/css/lunr_search.min.css +25 -0
- data/assets/themes/j1/modules/lunrSearch/js/dateformat.js +125 -0
- data/assets/themes/j1/modules/lunrSearch/js/dateformat.min.js +14 -0
- data/assets/themes/j1/modules/lunrSearch/js/lunr.js +3475 -0
- data/assets/themes/j1/modules/lunrSearch/js/lunr.min.js +51 -0
- data/assets/themes/j1/modules/lunrSearch/js/lunr_search.js +184 -0
- data/assets/themes/j1/modules/lunrSearch/js/lunr_search.min.js +17 -0
- data/assets/themes/j1/modules/lunrSearch/js/mustache.js +772 -0
- data/assets/themes/j1/modules/lunrSearch/js/mustache.min.js +772 -0
- data/assets/themes/j1/modules/lunrSearch/js/uri.js +2340 -0
- data/assets/themes/j1/modules/lunrSearch/js/uri.min.js +93 -0
- data/assets/themes/j1/modules/materialize/js/anime.js +1283 -0
- data/assets/themes/j1/modules/materialize/js/anime.min.js +34 -0
- data/assets/themes/j1/modules/materialize/js/autocomplete.js +450 -0
- data/assets/themes/j1/modules/materialize/js/buttons.js +409 -0
- data/assets/themes/j1/modules/materialize/js/cards.js +40 -0
- data/assets/themes/j1/modules/materialize/js/carousel.js +717 -0
- data/assets/themes/j1/modules/materialize/js/cash-dom.js +1044 -0
- data/assets/themes/j1/modules/materialize/js/cash.js +960 -0
- data/assets/themes/j1/modules/materialize/js/characterCounter.js +136 -0
- data/assets/themes/j1/modules/materialize/js/chips.js +481 -0
- data/assets/themes/j1/modules/materialize/js/collapsible.js +275 -0
- data/assets/themes/j1/modules/materialize/js/component.js +44 -0
- data/assets/themes/j1/modules/materialize/js/datepicker.js +975 -0
- data/assets/themes/j1/modules/materialize/js/dropdown.js +617 -0
- data/assets/themes/j1/modules/materialize/js/forms.js +275 -0
- data/assets/themes/j1/modules/materialize/js/global.js +427 -0
- data/assets/themes/j1/modules/materialize/js/materialbox.js +453 -0
- data/assets/themes/j1/modules/materialize/js/modal.js +382 -0
- data/assets/themes/j1/modules/materialize/js/parallax.js +138 -0
- data/assets/themes/j1/modules/materialize/js/pushpin.js +145 -0
- data/assets/themes/j1/modules/materialize/js/range.js +263 -0
- data/assets/themes/j1/modules/materialize/js/ripple.js +335 -0
- data/assets/themes/j1/modules/materialize/js/scrollspy.js +295 -0
- data/assets/themes/j1/modules/materialize/js/select.js +432 -0
- data/assets/themes/j1/modules/materialize/js/sidenav.js +580 -0
- data/assets/themes/j1/modules/materialize/js/slider.js +359 -0
- data/assets/themes/j1/modules/materialize/js/tabs.js +402 -0
- data/assets/themes/j1/modules/materialize/js/tapTarget.js +314 -0
- data/assets/themes/j1/modules/materialize/js/timepicker.js +647 -0
- data/assets/themes/j1/modules/materialize/js/toasts.js +310 -0
- data/assets/themes/j1/modules/materialize/js/tooltip.js +303 -0
- data/assets/themes/j1/modules/materialize/js/waves.js +335 -0
- data/assets/themes/j1/modules/materialize/scss/components/_badges.scss +55 -0
- data/assets/themes/j1/modules/materialize/scss/components/_buttons.scss +322 -0
- data/assets/themes/j1/modules/materialize/scss/components/_cards.scss +195 -0
- data/assets/themes/j1/modules/materialize/scss/components/_carousel.scss +90 -0
- data/assets/themes/j1/modules/materialize/scss/components/_chips.scss +90 -0
- data/assets/themes/j1/modules/materialize/scss/components/_collapsible.scss +91 -0
- data/assets/themes/j1/modules/materialize/scss/components/_color-classes.scss +32 -0
- data/assets/themes/j1/modules/materialize/scss/components/_color-variables.scss +370 -0
- data/assets/themes/j1/modules/materialize/scss/components/_datepicker.scss +191 -0
- data/assets/themes/j1/modules/materialize/scss/components/_dropdown.scss +85 -0
- data/assets/themes/j1/modules/materialize/scss/components/_global.scss +769 -0
- data/assets/themes/j1/modules/materialize/scss/components/_grid.scss +156 -0
- data/assets/themes/j1/modules/materialize/scss/components/_icons-material-design.scss +5 -0
- data/assets/themes/j1/modules/materialize/scss/components/_materialbox.scss +43 -0
- data/assets/themes/j1/modules/materialize/scss/components/_modal.scss +94 -0
- data/assets/themes/j1/modules/materialize/scss/components/_navbar.scss +208 -0
- data/assets/themes/j1/modules/materialize/scss/components/_normalize.scss +447 -0
- data/assets/themes/j1/modules/materialize/scss/components/_preloader.scss +334 -0
- data/assets/themes/j1/modules/materialize/scss/components/_pulse.scss +34 -0
- data/assets/themes/j1/modules/materialize/scss/components/_sidenav.scss +216 -0
- data/assets/themes/j1/modules/materialize/scss/components/_slider.scss +92 -0
- data/assets/themes/j1/modules/materialize/scss/components/_table_of_contents.scss +33 -0
- data/assets/themes/j1/modules/materialize/scss/components/_tabs.scss +99 -0
- data/assets/themes/j1/modules/materialize/scss/components/_tapTarget.scss +103 -0
- data/assets/themes/j1/modules/materialize/scss/components/_timepicker.scss +183 -0
- data/assets/themes/j1/modules/materialize/scss/components/_toast.scss +58 -0
- data/assets/themes/j1/modules/materialize/scss/components/_tooltip.scss +32 -0
- data/assets/themes/j1/modules/materialize/scss/components/_transitions.scss +13 -0
- data/assets/themes/j1/modules/materialize/scss/components/_typography.scss +60 -0
- data/assets/themes/j1/modules/materialize/scss/components/_variables.scss +349 -0
- data/assets/themes/j1/modules/materialize/scss/components/_waves.scss +114 -0
- data/assets/themes/j1/modules/materialize/scss/components/forms/_checkboxes.scss +200 -0
- data/assets/themes/j1/modules/materialize/scss/components/forms/_file-input.scss +44 -0
- data/assets/themes/j1/modules/materialize/scss/components/forms/_forms.scss +22 -0
- data/assets/themes/j1/modules/materialize/scss/components/forms/_input-fields.scss +354 -0
- data/assets/themes/j1/modules/materialize/scss/components/forms/_radio-buttons.scss +115 -0
- data/assets/themes/j1/modules/materialize/scss/components/forms/_range.scss +161 -0
- data/assets/themes/j1/modules/materialize/scss/components/forms/_select.scss +180 -0
- data/assets/themes/j1/modules/materialize/scss/components/forms/_switches.scss +89 -0
- data/assets/themes/j1/modules/materialize/scss/materialize.scss +41 -0
- data/assets/themes/j1/modules/{bsThemeSwitcher → themeSwitcher}/js/switcher.js +0 -0
- data/assets/themes/j1/modules/{bsThemeSwitcher → themeSwitcher}/js/switcher.min.js +0 -0
- data/lib/j1/version.rb +1 -1
- data/lib/starter_web/Gemfile +12 -16
- data/lib/starter_web/_config.yml +95 -21
- data/lib/starter_web/_data/blocks/banner.yml +1 -1
- data/lib/starter_web/_data/blocks/panel.yml +6 -6
- data/lib/starter_web/_data/j1_config.yml +7 -6
- data/lib/starter_web/_data/layouts/home.yml +13 -3
- data/lib/starter_web/_data/layouts/page.yml +10 -0
- data/lib/starter_web/_data/layouts/post.yml +10 -0
- data/lib/starter_web/_data/modules/defaults/{ssm.yml → fam.yml} +12 -15
- data/lib/starter_web/_data/modules/defaults/lunr_search.yml +171 -0
- data/lib/starter_web/_data/modules/defaults/navigator.yml +4 -4
- data/lib/starter_web/_data/modules/defaults/toccer.yml +4 -2
- data/lib/starter_web/_data/modules/fam.yml +158 -0
- data/lib/starter_web/_data/modules/{back2top.yml → lunr_search.yml} +15 -9
- data/lib/starter_web/_data/modules/navigator.yml +2 -2
- data/lib/starter_web/_data/modules/navigator_menu.yml +57 -6
- data/lib/starter_web/_data/modules/toccer.yml +0 -73
- data/lib/starter_web/_data/resources.yml +151 -104
- data/lib/starter_web/_includes/attributes.asciidoc +2 -2
- data/lib/starter_web/_includes/breadcrumbs.html +11 -0
- data/lib/starter_web/_plugins/debug.rb +0 -1
- data/lib/starter_web/_plugins/filters.rb +0 -1
- data/lib/starter_web/_plugins/{lorem-inline.rb → lorem_inline.rb} +1 -2
- data/lib/starter_web/_plugins/lunr_index.rb +313 -0
- data/lib/starter_web/_plugins/prettify.rb +0 -3
- data/lib/starter_web/_plugins/simple_search_filter.rb +0 -1
- data/lib/starter_web/_plugins/symlink_watcher.rb +2 -3
- data/lib/starter_web/assets/images/modules/attics/banner/lunr-banner-1280x800.jpg +0 -0
- data/lib/starter_web/assets/images/pages/winlogbeat/coordinate-map.png +0 -0
- data/lib/starter_web/assets/images/pages/winlogbeat/kibana-powershell.jpg +0 -0
- data/lib/starter_web/assets/images/pages/winlogbeat/option_ignore_outgoing.png +0 -0
- data/lib/starter_web/assets/images/pages/winlogbeat/winlogbeat-dashboard.png +0 -0
- data/lib/starter_web/collections/posts/public/featured/_posts/2018-05-01-confusion-about-base-url.adoc +2 -4
- data/lib/starter_web/collections/posts/public/featured/_posts/2019-05-01-top-open-source-static-site-generators.adoc +4 -2
- data/lib/starter_web/collections/posts/public/featured/_posts/2019-06-01-about-cookies.adoc +3 -2
- data/lib/starter_web/collections/posts/public/series/_posts/2018-11-01-docker-using-shared-folders.adoc +5 -4
- data/lib/starter_web/collections/posts/public/series/_posts/2020-01-01-post-test-series.adoc +144 -0
- data/lib/starter_web/collections/posts/public/series/_posts/2020-01-02-post-test-series.adoc +146 -0
- data/lib/starter_web/collections/posts/public/series/_posts/2020-01-03-post-test-series.adoc +146 -0
- data/lib/starter_web/collections/posts/public/series/_posts/2020-01-04-post-test-series.adoc +146 -0
- data/lib/starter_web/collections/posts/public/test_posts/_posts/2020-09-11-test_post.adoc +2 -4
- data/lib/starter_web/collections/posts/public/wikipedia/_posts/2016-11-20-minneapolis.adoc +2 -3
- data/lib/starter_web/collections/posts/public/wikipedia/_posts/2016-11-24-narcisse-snake-dens.adoc +2 -7
- data/lib/starter_web/collections/posts/public/wikipedia/_posts/2016-11-26-columbia-river.adoc +2 -6
- data/lib/starter_web/index.html +16 -10
- data/lib/starter_web/package.json +5 -2
- data/lib/starter_web/pages/public/about/about_site.adoc +0 -2
- data/lib/starter_web/pages/public/about/become_a_patron.adoc +1 -3
- data/lib/starter_web/pages/public/blog/navigator/archive.html +8 -1
- data/lib/starter_web/pages/public/blog/navigator/archive/categoryview.html +7 -3
- data/lib/starter_web/pages/public/blog/navigator/archive/dateview.html +8 -1
- data/lib/starter_web/pages/public/blog/navigator/archive/tagview.html +7 -2
- data/lib/starter_web/pages/public/blog/navigator/index.html +6 -2
- data/lib/starter_web/pages/public/learn/kickstarter/web_in_a_day/100_meet_and_greet_jekyll.adoc +3 -4
- data/lib/starter_web/pages/public/learn/kickstarter/web_in_a_day/200_preparations.adoc +3 -4
- data/lib/starter_web/pages/public/learn/kickstarter/web_in_a_day/300_first_awesome_web.adoc +3 -4
- data/lib/starter_web/pages/public/learn/roundtrip/100_present_images.adoc +25 -20
- data/lib/starter_web/pages/public/learn/roundtrip/100_present_videos.adoc +14 -12
- data/lib/starter_web/pages/public/learn/roundtrip/200_typography.adoc +20 -20
- data/lib/starter_web/pages/public/learn/roundtrip/300_icon_fonts.adoc +13 -8
- data/lib/starter_web/pages/public/learn/roundtrip/400_asciidoc_extensions.adoc +14 -9
- data/lib/starter_web/pages/public/learn/roundtrip/410_bs_modals_extentions.adoc +9 -6
- data/lib/starter_web/pages/public/learn/roundtrip/420_responsive_tables_extensions.adoc +62 -8
- data/lib/starter_web/pages/public/learn/roundtrip/500_themes.adoc +9 -7
- data/lib/starter_web/pages/public/learn/roundtrip/600_lunr.adoc +237 -0
- data/lib/starter_web/pages/public/learn/roundtrip/610_fam.adoc +302 -0
- data/lib/starter_web/pages/public/learn/where_to_go.adoc +3 -7
- data/lib/starter_web/pages/public/legal/de/100_impress.adoc +3 -2
- data/lib/starter_web/pages/public/legal/de/200_terms_of_use.adoc +2 -1
- data/lib/starter_web/pages/public/legal/de/300_privacy.adoc +2 -1
- data/lib/starter_web/pages/public/legal/de/400_license_agreement.adoc +2 -1
- data/lib/starter_web/pages/public/legal/de/500_support.adoc +2 -1
- data/lib/starter_web/pages/public/legal/en/000_copyright.adoc +30 -27
- data/lib/starter_web/pages/public/legal/en/100_impress.adoc +8 -5
- data/lib/starter_web/pages/public/legal/en/200_terms_of_use.adoc +12 -8
- data/lib/starter_web/pages/public/legal/en/300_privacy.adoc +7 -0
- data/lib/starter_web/pages/public/legal/en/400_license_agreement.adoc +8 -1
- data/lib/starter_web/pages/public/legal/en/500_support.adoc +8 -1
- data/lib/starter_web/pages/public/previewer/bootstrap_theme.adoc +3 -1
- data/lib/starter_web/pages/public/previewer/iframer.adoc +36 -28
- data/lib/starter_web/pages/public/previewer/justified_gallery.html +2 -1
- data/lib/starter_web/pages/public/previewer/mdi_icons_preview.adoc +2 -1
- data/lib/starter_web/pages/public/previewer/rouge.adoc +4 -2
- data/lib/starter_web/pages/public/previewer/twitter_emoji_preview.adoc +2 -1
- data/lib/starter_web/pages/public/test_pages/breadcrumbs_tester.adoc +62 -0
- data/lib/starter_web/pages/public/test_pages/deck_of_posts.adoc +3 -0
- data/lib/starter_web/pages/public/test_pages/floating_actions_button.adoc +523 -0
- data/lib/starter_web/pages/public/test_pages/floating_ad.adoc +1 -0
- data/lib/starter_web/pages/public/test_pages/floating_div.adoc +1 -0
- data/lib/starter_web/pages/public/test_pages/lunr_tester.adoc +89 -0
- data/lib/starter_web/pages/public/test_pages/nav_pagination_tester.adoc +1 -0
- data/lib/starter_web/pages/public/test_pages/page_attribute_tester.adoc +1 -0
- data/lib/starter_web/pages/public/test_pages/responsive_images.adoc +3 -2
- data/lib/starter_web/pages/public/test_pages/responsive_tables.adoc +1 -0
- data/lib/starter_web/pages/public/test_pages/toccer_tester.adoc +2245 -0
- data/lib/starter_web/utilsrv/_defaults/package.json +1 -1
- data/lib/starter_web/utilsrv/package.json +1 -1
- metadata +137 -29
- data/assets/data/search.json +0 -165
- data/assets/data/ssm.html +0 -242
- data/assets/themes/j1/adapter/js/back2top.js +0 -231
- data/assets/themes/j1/modules/jekyllSearch/js/simple-jekyll-search.js +0 -468
- data/assets/themes/j1/modules/jekyllSearch/js/simple-jekyll-search.min.js +0 -6
- data/assets/themes/j1/modules/tocbot/css/theme/uno.css +0 -95
- data/assets/themes/j1/modules/tocbot/css/theme/uno.min.css +0 -15
- data/assets/themes/j1/modules/tocbot/css/tocbot.css +0 -75
- data/assets/themes/j1/modules/tocbot/css/tocbot.min.css +0 -19
- data/assets/themes/j1/modules/tocbot/js/tocbot.js +0 -19
- data/assets/themes/j1/modules/tocbot/js/tocbot.min.js +0 -19
- data/lib/starter_web/_data/modules/defaults/back2top.yml +0 -146
- data/lib/starter_web/_data/modules/defaults/stickybits.yml +0 -36
- data/lib/starter_web/_data/modules/ssm.yml +0 -142
@@ -0,0 +1,51 @@
|
|
1
|
+
/**
|
2
|
+
* lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9
|
3
|
+
* Copyright (C) 2020 Oliver Nightingale
|
4
|
+
* @license MIT
|
5
|
+
*/
|
6
|
+
!function(){var e,t,r,i,n,s,o,a,u,l,c,h,d,f,p,y,m,g,x,v,w,Q,k,S,E,L,b,P,T=function(e){var t=new T.Builder;return t.pipeline.add(T.trimmer,T.stopWordFilter,T.stemmer),t.searchPipeline.add(T.stemmer),e.call(t,t),t.build()};T.version="2.3.9"
|
7
|
+
/*!
|
8
|
+
* lunr.utils
|
9
|
+
* Copyright (C) 2020 Oliver Nightingale
|
10
|
+
*/,T.utils={},T.utils.warn=(e=this,function(t){e.console&&console.warn&&console.warn(t)}),T.utils.asString=function(e){return null==e?"":e.toString()},T.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),r=Object.keys(e),i=0;i<r.length;i++){var n=r[i],s=e[n];if(Array.isArray(s))t[n]=s.slice();else{if("string"!=typeof s&&"number"!=typeof s&&"boolean"!=typeof s)throw new TypeError("clone is not deep and does not support nested objects");t[n]=s}}return t},T.FieldRef=function(e,t,r){this.docRef=e,this.fieldName=t,this._stringValue=r},T.FieldRef.joiner="/",T.FieldRef.fromString=function(e){var t=e.indexOf(T.FieldRef.joiner);if(-1===t)throw"malformed field ref string";var r=e.slice(0,t),i=e.slice(t+1);return new T.FieldRef(i,r,e)},T.FieldRef.prototype.toString=function(){return null==this._stringValue&&(this._stringValue=this.fieldName+T.FieldRef.joiner+this.docRef),this._stringValue}
|
11
|
+
/*!
|
12
|
+
* lunr.Set
|
13
|
+
* Copyright (C) 2020 Oliver Nightingale
|
14
|
+
*/,T.Set=function(e){if(this.elements=Object.create(null),e){this.length=e.length;for(var t=0;t<this.length;t++)this.elements[e[t]]=!0}else this.length=0},T.Set.complete={intersect:function(e){return e},union:function(){return this},contains:function(){return!0}},T.Set.empty={intersect:function(){return this},union:function(e){return e},contains:function(){return!1}},T.Set.prototype.contains=function(e){return!!this.elements[e]},T.Set.prototype.intersect=function(e){var t,r,i,n=[];if(e===T.Set.complete)return this;if(e===T.Set.empty)return e;this.length<e.length?(t=this,r=e):(t=e,r=this),i=Object.keys(t.elements);for(var s=0;s<i.length;s++){var o=i[s];o in r.elements&&n.push(o)}return new T.Set(n)},T.Set.prototype.union=function(e){return e===T.Set.complete?T.Set.complete:e===T.Set.empty?this:new T.Set(Object.keys(this.elements).concat(Object.keys(e.elements)))},T.idf=function(e,t){var r=0;for(var i in e)"_index"!=i&&(r+=Object.keys(e[i]).length);var n=(t-r+.5)/(r+.5);return Math.log(1+Math.abs(n))},T.Token=function(e,t){this.str=e||"",this.metadata=t||{}},T.Token.prototype.toString=function(){return this.str},T.Token.prototype.update=function(e){return this.str=e(this.str,this.metadata),this},T.Token.prototype.clone=function(e){return e=e||function(e){return e},new T.Token(e(this.str,this.metadata),this.metadata)}
|
15
|
+
/*!
|
16
|
+
* lunr.tokenizer
|
17
|
+
* Copyright (C) 2020 Oliver Nightingale
|
18
|
+
*/,T.tokenizer=function(e,t){if(null==e||null==e)return[];if(Array.isArray(e))return e.map(function(e){return new T.Token(T.utils.asString(e).toLowerCase(),T.utils.clone(t))});for(var r=e.toString().toLowerCase(),i=r.length,n=[],s=0,o=0;s<=i;s++){var a=s-o;if(r.charAt(s).match(T.tokenizer.separator)||s==i){if(a>0){var u=T.utils.clone(t)||{};u.position=[o,a],u.index=n.length,n.push(new T.Token(r.slice(o,s),u))}o=s+1}}return n},T.tokenizer.separator=/[\s\-]+/
|
19
|
+
/*!
|
20
|
+
* lunr.Pipeline
|
21
|
+
* Copyright (C) 2020 Oliver Nightingale
|
22
|
+
*/,T.Pipeline=function(){this._stack=[]},T.Pipeline.registeredFunctions=Object.create(null),T.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&T.utils.warn("Overwriting existing registered function: "+t),e.label=t,T.Pipeline.registeredFunctions[e.label]=e},T.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||T.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},T.Pipeline.load=function(e){var t=new T.Pipeline;return e.forEach(function(e){var r=T.Pipeline.registeredFunctions[e];if(!r)throw new Error("Cannot load unregistered function: "+e);t.add(r)}),t},T.Pipeline.prototype.add=function(){Array.prototype.slice.call(arguments).forEach(function(e){T.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},T.Pipeline.prototype.after=function(e,t){T.Pipeline.warnIfFunctionNotRegistered(t);var r=this._stack.indexOf(e);if(-1==r)throw new Error("Cannot find existingFn");r+=1,this._stack.splice(r,0,t)},T.Pipeline.prototype.before=function(e,t){T.Pipeline.warnIfFunctionNotRegistered(t);var r=this._stack.indexOf(e);if(-1==r)throw new Error("Cannot find existingFn");this._stack.splice(r,0,t)},T.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},T.Pipeline.prototype.run=function(e){for(var t=this._stack.length,r=0;r<t;r++){for(var i=this._stack[r],n=[],s=0;s<e.length;s++){var o=i(e[s],s,e);if(null!=o&&""!==o)if(Array.isArray(o))for(var a=0;a<o.length;a++)n.push(o[a]);else n.push(o)}e=n}return e},T.Pipeline.prototype.runString=function(e,t){var r=new T.Token(e,t);return this.run([r]).map(function(e){return e.toString()})},T.Pipeline.prototype.reset=function(){this._stack=[]},T.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return T.Pipeline.warnIfFunctionNotRegistered(e),e.label})}
|
23
|
+
/*!
|
24
|
+
* lunr.Vector
|
25
|
+
* Copyright (C) 2020 Oliver Nightingale
|
26
|
+
*/,T.Vector=function(e){this._magnitude=0,this.elements=e||[]},T.Vector.prototype.positionForIndex=function(e){if(0==this.elements.length)return 0;for(var t=0,r=this.elements.length/2,i=r-t,n=Math.floor(i/2),s=this.elements[2*n];i>1&&(s<e&&(t=n),s>e&&(r=n),s!=e);)i=r-t,n=t+Math.floor(i/2),s=this.elements[2*n];return s==e?2*n:s>e?2*n:s<e?2*(n+1):void 0},T.Vector.prototype.insert=function(e,t){this.upsert(e,t,function(){throw"duplicate index"})},T.Vector.prototype.upsert=function(e,t,r){this._magnitude=0;var i=this.positionForIndex(e);this.elements[i]==e?this.elements[i+1]=r(this.elements[i+1],t):this.elements.splice(i,0,e,t)},T.Vector.prototype.magnitude=function(){if(this._magnitude)return this._magnitude;for(var e=0,t=this.elements.length,r=1;r<t;r+=2){var i=this.elements[r];e+=i*i}return this._magnitude=Math.sqrt(e)},T.Vector.prototype.dot=function(e){for(var t=0,r=this.elements,i=e.elements,n=r.length,s=i.length,o=0,a=0,u=0,l=0;u<n&&l<s;)(o=r[u])<(a=i[l])?u+=2:o>a?l+=2:o==a&&(t+=r[u+1]*i[l+1],u+=2,l+=2);return t},T.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},T.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,r=0;t<this.elements.length;t+=2,r++)e[r]=this.elements[t];return e},T.Vector.prototype.toJSON=function(){return this.elements}
|
27
|
+
/*!
|
28
|
+
* lunr.stemmer
|
29
|
+
* Copyright (C) 2020 Oliver Nightingale
|
30
|
+
* Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt
|
31
|
+
*/,T.stemmer=(t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},r={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},i="[aeiouy]",n="[^aeiou][^aeiouy]*",s=new RegExp("^([^aeiou][^aeiouy]*)?[aeiouy][aeiou]*[^aeiou][^aeiouy]*"),o=new RegExp("^([^aeiou][^aeiouy]*)?[aeiouy][aeiou]*[^aeiou][^aeiouy]*[aeiouy][aeiou]*[^aeiou][^aeiouy]*"),a=new RegExp("^([^aeiou][^aeiouy]*)?[aeiouy][aeiou]*[^aeiou][^aeiouy]*([aeiouy][aeiou]*)?$"),u=new RegExp("^([^aeiou][^aeiouy]*)?[aeiouy]"),l=/^(.+?)(ss|i)es$/,c=/^(.+?)([^s])s$/,h=/^(.+?)eed$/,d=/^(.+?)(ed|ing)$/,f=/.$/,p=/(at|bl|iz)$/,y=new RegExp("([^aeiouylsz])\\1$"),m=new RegExp("^"+n+i+"[^aeiouwxy]$"),g=/^(.+?[^aeiou])y$/,x=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,v=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,w=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,Q=/^(.+?)(s|t)(ion)$/,k=/^(.+?)e$/,S=/ll$/,E=new RegExp("^"+n+i+"[^aeiouwxy]$"),L=function(e){var i,n,L,b,P,T,O;if(e.length<3)return e;if("y"==(L=e.substr(0,1))&&(e=L.toUpperCase()+e.substr(1)),P=c,(b=l).test(e)?e=e.replace(b,"$1$2"):P.test(e)&&(e=e.replace(P,"$1$2")),P=d,(b=h).test(e)){var I=b.exec(e);(b=s).test(I[1])&&(b=f,e=e.replace(b,""))}else if(P.test(e)){i=(I=P.exec(e))[1],(P=u).test(i)&&(T=y,O=m,(P=p).test(e=i)?e+="e":T.test(e)?(b=f,e=e.replace(b,"")):O.test(e)&&(e+="e"))}(b=g).test(e)&&(e=(i=(I=b.exec(e))[1])+"i");(b=x).test(e)&&(i=(I=b.exec(e))[1],n=I[2],(b=s).test(i)&&(e=i+t[n]));(b=v).test(e)&&(i=(I=b.exec(e))[1],n=I[2],(b=s).test(i)&&(e=i+r[n]));if(P=Q,(b=w).test(e))i=(I=b.exec(e))[1],(b=o).test(i)&&(e=i);else if(P.test(e)){i=(I=P.exec(e))[1]+I[2],(P=o).test(i)&&(e=i)}(b=k).test(e)&&(i=(I=b.exec(e))[1],P=a,T=E,((b=o).test(i)||P.test(i)&&!T.test(i))&&(e=i));return P=o,(b=S).test(e)&&P.test(e)&&(b=f,e=e.replace(b,"")),"y"==L&&(e=L.toLowerCase()+e.substr(1)),e},function(e){return e.update(L)}),T.Pipeline.registerFunction(T.stemmer,"stemmer")
|
32
|
+
/*!
|
33
|
+
* lunr.stopWordFilter
|
34
|
+
* Copyright (C) 2020 Oliver Nightingale
|
35
|
+
*/,T.generateStopWordFilter=function(e){var t=e.reduce(function(e,t){return e[t]=t,e},{});return function(e){if(e&&t[e.toString()]!==e.toString())return e}},T.stopWordFilter=T.generateStopWordFilter(["a","able","about","across","after","all","almost","also","am","among","an","and","any","are","as","at","be","because","been","but","by","can","cannot","could","dear","did","do","does","either","else","ever","every","for","from","get","got","had","has","have","he","her","hers","him","his","how","however","i","if","in","into","is","it","its","just","least","let","like","likely","may","me","might","most","must","my","neither","no","nor","not","of","off","often","on","only","or","other","our","own","rather","said","say","says","she","should","since","so","some","than","that","the","their","them","then","there","these","they","this","tis","to","too","twas","us","wants","was","we","were","what","when","where","which","while","who","whom","why","will","with","would","yet","you","your"]),T.Pipeline.registerFunction(T.stopWordFilter,"stopWordFilter")
|
36
|
+
/*!
|
37
|
+
* lunr.trimmer
|
38
|
+
* Copyright (C) 2020 Oliver Nightingale
|
39
|
+
*/,T.trimmer=function(e){return e.update(function(e){return e.replace(/^\W+/,"").replace(/\W+$/,"")})},T.Pipeline.registerFunction(T.trimmer,"trimmer")
|
40
|
+
/*!
|
41
|
+
* lunr.TokenSet
|
42
|
+
* Copyright (C) 2020 Oliver Nightingale
|
43
|
+
*/,T.TokenSet=function(){this.final=!1,this.edges={},this.id=T.TokenSet._nextId,T.TokenSet._nextId+=1},T.TokenSet._nextId=1,T.TokenSet.fromArray=function(e){for(var t=new T.TokenSet.Builder,r=0,i=e.length;r<i;r++)t.insert(e[r]);return t.finish(),t.root},T.TokenSet.fromClause=function(e){return"editDistance"in e?T.TokenSet.fromFuzzyString(e.term,e.editDistance):T.TokenSet.fromString(e.term)},T.TokenSet.fromFuzzyString=function(e,t){for(var r=new T.TokenSet,i=[{node:r,editsRemaining:t,str:e}];i.length;){var n=i.pop();if(n.str.length>0){var s,o=n.str.charAt(0);o in n.node.edges?s=n.node.edges[o]:(s=new T.TokenSet,n.node.edges[o]=s),1==n.str.length&&(s.final=!0),i.push({node:s,editsRemaining:n.editsRemaining,str:n.str.slice(1)})}if(0!=n.editsRemaining){if("*"in n.node.edges)var a=n.node.edges["*"];else{a=new T.TokenSet;n.node.edges["*"]=a}if(0==n.str.length&&(a.final=!0),i.push({node:a,editsRemaining:n.editsRemaining-1,str:n.str}),n.str.length>1&&i.push({node:n.node,editsRemaining:n.editsRemaining-1,str:n.str.slice(1)}),1==n.str.length&&(n.node.final=!0),n.str.length>=1){if("*"in n.node.edges)var u=n.node.edges["*"];else{u=new T.TokenSet;n.node.edges["*"]=u}1==n.str.length&&(u.final=!0),i.push({node:u,editsRemaining:n.editsRemaining-1,str:n.str.slice(1)})}if(n.str.length>1){var l,c=n.str.charAt(0),h=n.str.charAt(1);h in n.node.edges?l=n.node.edges[h]:(l=new T.TokenSet,n.node.edges[h]=l),1==n.str.length&&(l.final=!0),i.push({node:l,editsRemaining:n.editsRemaining-1,str:c+n.str.slice(2)})}}}return r},T.TokenSet.fromString=function(e){for(var t=new T.TokenSet,r=t,i=0,n=e.length;i<n;i++){var s=e[i],o=i==n-1;if("*"==s)t.edges[s]=t,t.final=o;else{var a=new T.TokenSet;a.final=o,t.edges[s]=a,t=a}}return r},T.TokenSet.prototype.toArray=function(){for(var e=[],t=[{prefix:"",node:this}];t.length;){var r=t.pop(),i=Object.keys(r.node.edges),n=i.length;r.node.final&&(r.prefix.charAt(0),e.push(r.prefix));for(var s=0;s<n;s++){var o=i[s];t.push({prefix:r.prefix.concat(o),node:r.node.edges[o]})}}return e},T.TokenSet.prototype.toString=function(){if(this._str)return this._str;for(var e=this.final?"1":"0",t=Object.keys(this.edges).sort(),r=t.length,i=0;i<r;i++){var n=t[i];e=e+n+this.edges[n].id}return e},T.TokenSet.prototype.intersect=function(e){for(var t=new T.TokenSet,r=void 0,i=[{qNode:e,output:t,node:this}];i.length;){r=i.pop();for(var n=Object.keys(r.qNode.edges),s=n.length,o=Object.keys(r.node.edges),a=o.length,u=0;u<s;u++)for(var l=n[u],c=0;c<a;c++){var h=o[c];if(h==l||"*"==l){var d=r.node.edges[h],f=r.qNode.edges[l],p=d.final&&f.final,y=void 0;h in r.output.edges?(y=r.output.edges[h]).final=y.final||p:((y=new T.TokenSet).final=p,r.output.edges[h]=y),i.push({qNode:f,output:y,node:d})}}}return t},T.TokenSet.Builder=function(){this.previousWord="",this.root=new T.TokenSet,this.uncheckedNodes=[],this.minimizedNodes={}},T.TokenSet.Builder.prototype.insert=function(e){var t,r=0;if(e<this.previousWord)throw new Error("Out of order word insertion");for(var i=0;i<e.length&&i<this.previousWord.length&&e[i]==this.previousWord[i];i++)r++;this.minimize(r),t=0==this.uncheckedNodes.length?this.root:this.uncheckedNodes[this.uncheckedNodes.length-1].child;for(i=r;i<e.length;i++){var n=new T.TokenSet,s=e[i];t.edges[s]=n,this.uncheckedNodes.push({parent:t,char:s,child:n}),t=n}t.final=!0,this.previousWord=e},T.TokenSet.Builder.prototype.finish=function(){this.minimize(0)},T.TokenSet.Builder.prototype.minimize=function(e){for(var t=this.uncheckedNodes.length-1;t>=e;t--){var r=this.uncheckedNodes[t],i=r.child.toString();i in this.minimizedNodes?r.parent.edges[r.char]=this.minimizedNodes[i]:(r.child._str=i,this.minimizedNodes[i]=r.child),this.uncheckedNodes.pop()}}
|
44
|
+
/*!
|
45
|
+
* lunr.Index
|
46
|
+
* Copyright (C) 2020 Oliver Nightingale
|
47
|
+
*/,T.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},T.Index.prototype.search=function(e){return this.query(function(t){new T.QueryParser(e,t).parse()})},T.Index.prototype.query=function(e){for(var t=new T.Query(this.fields),r=Object.create(null),i=Object.create(null),n=Object.create(null),s=Object.create(null),o=Object.create(null),a=0;a<this.fields.length;a++)i[this.fields[a]]=new T.Vector;e.call(t,t);for(a=0;a<t.clauses.length;a++){var u=t.clauses[a],l=null,c=T.Set.empty;l=u.usePipeline?this.pipeline.runString(u.term,{fields:u.fields}):[u.term];for(var h=0;h<l.length;h++){var d=l[h];u.term=d;var f=T.TokenSet.fromClause(u),p=this.tokenSet.intersect(f).toArray();if(0===p.length&&u.presence===T.Query.presence.REQUIRED){for(var y=0;y<u.fields.length;y++){s[F=u.fields[y]]=T.Set.empty}break}for(var m=0;m<p.length;m++){var g=p[m],x=this.invertedIndex[g],v=x._index;for(y=0;y<u.fields.length;y++){var w=x[F=u.fields[y]],Q=Object.keys(w),k=g+"/"+F,S=new T.Set(Q);if(u.presence==T.Query.presence.REQUIRED&&(c=c.union(S),void 0===s[F]&&(s[F]=T.Set.complete)),u.presence!=T.Query.presence.PROHIBITED){if(i[F].upsert(v,u.boost,function(e,t){return e+t}),!n[k]){for(var E=0;E<Q.length;E++){var L,b=Q[E],P=new T.FieldRef(b,F),O=w[b];void 0===(L=r[P])?r[P]=new T.MatchData(g,F,O):L.add(g,F,O)}n[k]=!0}}else void 0===o[F]&&(o[F]=T.Set.empty),o[F]=o[F].union(S)}}}if(u.presence===T.Query.presence.REQUIRED)for(y=0;y<u.fields.length;y++){s[F=u.fields[y]]=s[F].intersect(c)}}var I=T.Set.complete,R=T.Set.empty;for(a=0;a<this.fields.length;a++){var F;s[F=this.fields[a]]&&(I=I.intersect(s[F])),o[F]&&(R=R.union(o[F]))}var C=Object.keys(r),N=[],j=Object.create(null);if(t.isNegated()){C=Object.keys(this.fieldVectors);for(a=0;a<C.length;a++){P=C[a];var _=T.FieldRef.fromString(P);r[P]=new T.MatchData}}for(a=0;a<C.length;a++){var D=(_=T.FieldRef.fromString(C[a])).docRef;if(I.contains(D)&&!R.contains(D)){var A,B=this.fieldVectors[_],V=i[_.fieldName].similarity(B);if(void 0!==(A=j[D]))A.score+=V,A.matchData.combine(r[_]);else{var z={ref:D,score:V,matchData:r[_]};j[D]=z,N.push(z)}}}return N.sort(function(e,t){return t.score-e.score})},T.Index.prototype.toJSON=function(){var e=Object.keys(this.invertedIndex).sort().map(function(e){return[e,this.invertedIndex[e]]},this),t=Object.keys(this.fieldVectors).map(function(e){return[e,this.fieldVectors[e].toJSON()]},this);return{version:T.version,fields:this.fields,fieldVectors:t,invertedIndex:e,pipeline:this.pipeline.toJSON()}},T.Index.load=function(e){var t={},r={},i=e.fieldVectors,n=Object.create(null),s=e.invertedIndex,o=new T.TokenSet.Builder,a=T.Pipeline.load(e.pipeline);e.version!=T.version&&T.utils.warn("Version mismatch when loading serialised index. Current version of lunr '"+T.version+"' does not match serialized index '"+e.version+"'");for(var u=0;u<i.length;u++){var l=(h=i[u])[0],c=h[1];r[l]=new T.Vector(c)}for(u=0;u<s.length;u++){var h,d=(h=s[u])[0],f=h[1];o.insert(d),n[d]=f}return o.finish(),t.fields=e.fields,t.fieldVectors=r,t.invertedIndex=n,t.tokenSet=o.root,t.pipeline=a,new T.Index(t)}
|
48
|
+
/*!
|
49
|
+
* lunr.Builder
|
50
|
+
* Copyright (C) 2020 Oliver Nightingale
|
51
|
+
*/,T.Builder=function(){this._ref="id",this._fields=Object.create(null),this._documents=Object.create(null),this.invertedIndex=Object.create(null),this.fieldTermFrequencies={},this.fieldLengths={},this.tokenizer=T.tokenizer,this.pipeline=new T.Pipeline,this.searchPipeline=new T.Pipeline,this.documentCount=0,this._b=.75,this._k1=1.2,this.termIndex=0,this.metadataWhitelist=[]},T.Builder.prototype.ref=function(e){this._ref=e},T.Builder.prototype.field=function(e,t){if(/\//.test(e))throw new RangeError("Field '"+e+"' contains illegal character '/'");this._fields[e]=t||{}},T.Builder.prototype.b=function(e){this._b=e<0?0:e>1?1:e},T.Builder.prototype.k1=function(e){this._k1=e},T.Builder.prototype.add=function(e,t){var r=e[this._ref],i=Object.keys(this._fields);this._documents[r]=t||{},this.documentCount+=1;for(var n=0;n<i.length;n++){var s=i[n],o=this._fields[s].extractor,a=o?o(e):e[s],u=this.tokenizer(a,{fields:[s]}),l=this.pipeline.run(u),c=new T.FieldRef(r,s),h=Object.create(null);this.fieldTermFrequencies[c]=h,this.fieldLengths[c]=0,this.fieldLengths[c]+=l.length;for(var d=0;d<l.length;d++){var f=l[d];if(null==h[f]&&(h[f]=0),h[f]+=1,null==this.invertedIndex[f]){var p=Object.create(null);p._index=this.termIndex,this.termIndex+=1;for(var y=0;y<i.length;y++)p[i[y]]=Object.create(null);this.invertedIndex[f]=p}null==this.invertedIndex[f][s][r]&&(this.invertedIndex[f][s][r]=Object.create(null));for(var m=0;m<this.metadataWhitelist.length;m++){var g=this.metadataWhitelist[m],x=f.metadata[g];null==this.invertedIndex[f][s][r][g]&&(this.invertedIndex[f][s][r][g]=[]),this.invertedIndex[f][s][r][g].push(x)}}}},T.Builder.prototype.calculateAverageFieldLengths=function(){for(var e=Object.keys(this.fieldLengths),t=e.length,r={},i={},n=0;n<t;n++){var s=T.FieldRef.fromString(e[n]),o=s.fieldName;i[o]||(i[o]=0),i[o]+=1,r[o]||(r[o]=0),r[o]+=this.fieldLengths[s]}var a=Object.keys(this._fields);for(n=0;n<a.length;n++){var u=a[n];r[u]=r[u]/i[u]}this.averageFieldLength=r},T.Builder.prototype.createFieldVectors=function(){for(var e={},t=Object.keys(this.fieldTermFrequencies),r=t.length,i=Object.create(null),n=0;n<r;n++){for(var s=T.FieldRef.fromString(t[n]),o=s.fieldName,a=this.fieldLengths[s],u=new T.Vector,l=this.fieldTermFrequencies[s],c=Object.keys(l),h=c.length,d=this._fields[o].boost||1,f=this._documents[s.docRef].boost||1,p=0;p<h;p++){var y,m,g,x=c[p],v=l[x],w=this.invertedIndex[x]._index;void 0===i[x]?(y=T.idf(this.invertedIndex[x],this.documentCount),i[x]=y):y=i[x],m=y*((this._k1+1)*v)/(this._k1*(1-this._b+this._b*(a/this.averageFieldLength[o]))+v),m*=d,m*=f,g=Math.round(1e3*m)/1e3,u.insert(w,g)}e[s]=u}this.fieldVectors=e},T.Builder.prototype.createTokenSet=function(){this.tokenSet=T.TokenSet.fromArray(Object.keys(this.invertedIndex).sort())},T.Builder.prototype.build=function(){return this.calculateAverageFieldLengths(),this.createFieldVectors(),this.createTokenSet(),new T.Index({invertedIndex:this.invertedIndex,fieldVectors:this.fieldVectors,tokenSet:this.tokenSet,fields:Object.keys(this._fields),pipeline:this.searchPipeline})},T.Builder.prototype.use=function(e){var t=Array.prototype.slice.call(arguments,1);t.unshift(this),e.apply(this,t)},T.MatchData=function(e,t,r){for(var i=Object.create(null),n=Object.keys(r||{}),s=0;s<n.length;s++){var o=n[s];i[o]=r[o].slice()}this.metadata=Object.create(null),void 0!==e&&(this.metadata[e]=Object.create(null),this.metadata[e][t]=i)},T.MatchData.prototype.combine=function(e){for(var t=Object.keys(e.metadata),r=0;r<t.length;r++){var i=t[r],n=Object.keys(e.metadata[i]);null==this.metadata[i]&&(this.metadata[i]=Object.create(null));for(var s=0;s<n.length;s++){var o=n[s],a=Object.keys(e.metadata[i][o]);null==this.metadata[i][o]&&(this.metadata[i][o]=Object.create(null));for(var u=0;u<a.length;u++){var l=a[u];null==this.metadata[i][o][l]?this.metadata[i][o][l]=e.metadata[i][o][l]:this.metadata[i][o][l]=this.metadata[i][o][l].concat(e.metadata[i][o][l])}}}},T.MatchData.prototype.add=function(e,t,r){if(!(e in this.metadata))return this.metadata[e]=Object.create(null),void(this.metadata[e][t]=r);if(t in this.metadata[e])for(var i=Object.keys(r),n=0;n<i.length;n++){var s=i[n];s in this.metadata[e][t]?this.metadata[e][t][s]=this.metadata[e][t][s].concat(r[s]):this.metadata[e][t][s]=r[s]}else this.metadata[e][t]=r},T.Query=function(e){this.clauses=[],this.allFields=e},T.Query.wildcard=new String("*"),T.Query.wildcard.NONE=0,T.Query.wildcard.LEADING=1,T.Query.wildcard.TRAILING=2,T.Query.presence={OPTIONAL:1,REQUIRED:2,PROHIBITED:3},T.Query.prototype.clause=function(e){return"fields"in e||(e.fields=this.allFields),"boost"in e||(e.boost=1),"usePipeline"in e||(e.usePipeline=!0),"wildcard"in e||(e.wildcard=T.Query.wildcard.NONE),e.wildcard&T.Query.wildcard.LEADING&&e.term.charAt(0)!=T.Query.wildcard&&(e.term="*"+e.term),e.wildcard&T.Query.wildcard.TRAILING&&e.term.slice(-1)!=T.Query.wildcard&&(e.term=e.term+"*"),"presence"in e||(e.presence=T.Query.presence.OPTIONAL),this.clauses.push(e),this},T.Query.prototype.isNegated=function(){for(var e=0;e<this.clauses.length;e++)if(this.clauses[e].presence!=T.Query.presence.PROHIBITED)return!1;return!0},T.Query.prototype.term=function(e,t){if(Array.isArray(e))return e.forEach(function(e){this.term(e,T.utils.clone(t))},this),this;var r=t||{};return r.term=e.toString(),this.clause(r),this},T.QueryParseError=function(e,t,r){this.name="QueryParseError",this.message=e,this.start=t,this.end=r},T.QueryParseError.prototype=new Error,T.QueryLexer=function(e){this.lexemes=[],this.str=e,this.length=e.length,this.pos=0,this.start=0,this.escapeCharPositions=[]},T.QueryLexer.prototype.run=function(){for(var e=T.QueryLexer.lexText;e;)e=e(this)},T.QueryLexer.prototype.sliceString=function(){for(var e=[],t=this.start,r=this.pos,i=0;i<this.escapeCharPositions.length;i++)r=this.escapeCharPositions[i],e.push(this.str.slice(t,r)),t=r+1;return e.push(this.str.slice(t,this.pos)),this.escapeCharPositions.length=0,e.join("")},T.QueryLexer.prototype.emit=function(e){this.lexemes.push({type:e,str:this.sliceString(),start:this.start,end:this.pos}),this.start=this.pos},T.QueryLexer.prototype.escapeCharacter=function(){this.escapeCharPositions.push(this.pos-1),this.pos+=1},T.QueryLexer.prototype.next=function(){if(this.pos>=this.length)return T.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},T.QueryLexer.prototype.width=function(){return this.pos-this.start},T.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},T.QueryLexer.prototype.backup=function(){this.pos-=1},T.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{t=(e=this.next()).charCodeAt(0)}while(t>47&&t<58);e!=T.QueryLexer.EOS&&this.backup()},T.QueryLexer.prototype.more=function(){return this.pos<this.length},T.QueryLexer.EOS="EOS",T.QueryLexer.FIELD="FIELD",T.QueryLexer.TERM="TERM",T.QueryLexer.EDIT_DISTANCE="EDIT_DISTANCE",T.QueryLexer.BOOST="BOOST",T.QueryLexer.PRESENCE="PRESENCE",T.QueryLexer.lexField=function(e){return e.backup(),e.emit(T.QueryLexer.FIELD),e.ignore(),T.QueryLexer.lexText},T.QueryLexer.lexTerm=function(e){if(e.width()>1&&(e.backup(),e.emit(T.QueryLexer.TERM)),e.ignore(),e.more())return T.QueryLexer.lexText},T.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(T.QueryLexer.EDIT_DISTANCE),T.QueryLexer.lexText},T.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(T.QueryLexer.BOOST),T.QueryLexer.lexText},T.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(T.QueryLexer.TERM)},T.QueryLexer.termSeparator=T.tokenizer.separator,T.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==T.QueryLexer.EOS)return T.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return T.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(T.QueryLexer.TERM),T.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(T.QueryLexer.TERM),T.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(T.QueryLexer.PRESENCE),T.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(T.QueryLexer.PRESENCE),T.QueryLexer.lexText;if(t.match(T.QueryLexer.termSeparator))return T.QueryLexer.lexTerm}else e.escapeCharacter()}},T.QueryParser=function(e,t){this.lexer=new T.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},T.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=T.QueryParser.parseClause;e;)e=e(this);return this.query},T.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},T.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},T.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},T.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(null!=t)switch(t.type){case T.QueryLexer.PRESENCE:return T.QueryParser.parsePresence;case T.QueryLexer.FIELD:return T.QueryParser.parseField;case T.QueryLexer.TERM:return T.QueryParser.parseTerm;default:var r="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(r+=" with value '"+t.str+"'"),new T.QueryParseError(r,t.start,t.end)}},T.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(null!=t){switch(t.str){case"-":e.currentClause.presence=T.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=T.Query.presence.REQUIRED;break;default:var r="unrecognised presence operator'"+t.str+"'";throw new T.QueryParseError(r,t.start,t.end)}var i=e.peekLexeme();if(null==i){r="expecting term or field, found nothing";throw new T.QueryParseError(r,t.start,t.end)}switch(i.type){case T.QueryLexer.FIELD:return T.QueryParser.parseField;case T.QueryLexer.TERM:return T.QueryParser.parseTerm;default:r="expecting term or field, found '"+i.type+"'";throw new T.QueryParseError(r,i.start,i.end)}}},T.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(null!=t){if(-1==e.query.allFields.indexOf(t.str)){var r=e.query.allFields.map(function(e){return"'"+e+"'"}).join(", "),i="unrecognised field '"+t.str+"', possible fields: "+r;throw new T.QueryParseError(i,t.start,t.end)}e.currentClause.fields=[t.str];var n=e.peekLexeme();if(null==n){i="expecting term, found nothing";throw new T.QueryParseError(i,t.start,t.end)}switch(n.type){case T.QueryLexer.TERM:return T.QueryParser.parseTerm;default:i="expecting term, found '"+n.type+"'";throw new T.QueryParseError(i,n.start,n.end)}}},T.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(null!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var r=e.peekLexeme();if(null!=r)switch(r.type){case T.QueryLexer.TERM:return e.nextClause(),T.QueryParser.parseTerm;case T.QueryLexer.FIELD:return e.nextClause(),T.QueryParser.parseField;case T.QueryLexer.EDIT_DISTANCE:return T.QueryParser.parseEditDistance;case T.QueryLexer.BOOST:return T.QueryParser.parseBoost;case T.QueryLexer.PRESENCE:return e.nextClause(),T.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+r.type+"'";throw new T.QueryParseError(i,r.start,r.end)}else e.nextClause()}},T.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(null!=t){var r=parseInt(t.str,10);if(isNaN(r)){var i="edit distance must be numeric";throw new T.QueryParseError(i,t.start,t.end)}e.currentClause.editDistance=r;var n=e.peekLexeme();if(null!=n)switch(n.type){case T.QueryLexer.TERM:return e.nextClause(),T.QueryParser.parseTerm;case T.QueryLexer.FIELD:return e.nextClause(),T.QueryParser.parseField;case T.QueryLexer.EDIT_DISTANCE:return T.QueryParser.parseEditDistance;case T.QueryLexer.BOOST:return T.QueryParser.parseBoost;case T.QueryLexer.PRESENCE:return e.nextClause(),T.QueryParser.parsePresence;default:i="Unexpected lexeme type '"+n.type+"'";throw new T.QueryParseError(i,n.start,n.end)}else e.nextClause()}},T.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(null!=t){var r=parseInt(t.str,10);if(isNaN(r)){var i="boost must be numeric";throw new T.QueryParseError(i,t.start,t.end)}e.currentClause.boost=r;var n=e.peekLexeme();if(null!=n)switch(n.type){case T.QueryLexer.TERM:return e.nextClause(),T.QueryParser.parseTerm;case T.QueryLexer.FIELD:return e.nextClause(),T.QueryParser.parseField;case T.QueryLexer.EDIT_DISTANCE:return T.QueryParser.parseEditDistance;case T.QueryLexer.BOOST:return T.QueryParser.parseBoost;case T.QueryLexer.PRESENCE:return e.nextClause(),T.QueryParser.parsePresence;default:i="Unexpected lexeme type '"+n.type+"'";throw new T.QueryParseError(i,n.start,n.end)}else e.nextClause()}},b=this,P=function(){return T},"function"==typeof define&&define.amd?define(P):"object"==typeof exports?module.exports=P():b.lunr=P()}();
|
@@ -0,0 +1,184 @@
|
|
1
|
+
/*
|
2
|
+
# -----------------------------------------------------------------------------
|
3
|
+
# ~/assets/themes/j1/modules/lunr/js/lunr.search.js
|
4
|
+
# jQuery plugin to use with J1LunrSearch
|
5
|
+
#
|
6
|
+
# Product/Info:
|
7
|
+
# https://jekyll.one
|
8
|
+
#
|
9
|
+
# Copyright (C) 2020 Juergen Adams
|
10
|
+
#
|
11
|
+
# J1 Template is licensed under the MIT License.
|
12
|
+
# See: https://github.com/jekyll-one-org/J1 Template/blob/master/LICENSE
|
13
|
+
# -----------------------------------------------------------------------------
|
14
|
+
# TODO:
|
15
|
+
# -----------------------------------------------------------------------------
|
16
|
+
*/
|
17
|
+
'use strict';
|
18
|
+
|
19
|
+
(function($) {
|
20
|
+
|
21
|
+
var debounce = function(fn) {
|
22
|
+
var timeout;
|
23
|
+
var slice = Array.prototype.slice;
|
24
|
+
|
25
|
+
return function() {
|
26
|
+
var args = slice.call(arguments),
|
27
|
+
ctx = this;
|
28
|
+
|
29
|
+
clearTimeout(timeout);
|
30
|
+
|
31
|
+
timeout = setTimeout(function () {
|
32
|
+
fn.apply(ctx, args);
|
33
|
+
}, 100);
|
34
|
+
};
|
35
|
+
};
|
36
|
+
|
37
|
+
// parse a date in yyyy-mm-dd format
|
38
|
+
var parseDate = function(input) {
|
39
|
+
var parts = input.match(/(\d+)/g);
|
40
|
+
return new Date(parts[0], parts[1]-1, parts[2]); // months are 0-based
|
41
|
+
};
|
42
|
+
|
43
|
+
var LunrSearch = (function() {
|
44
|
+
function LunrSearch(elem, options) {
|
45
|
+
this.$elem = elem;
|
46
|
+
this.$results = $(options.results);
|
47
|
+
this.indexData = options.index_file;
|
48
|
+
this.template = this.compileTemplate($(options.template));
|
49
|
+
this.titleMsg = options.titleMsg;
|
50
|
+
this.emptyMsg = options.emptyMsg;
|
51
|
+
this.onAfterResultShow = options.onAfterResultShow;
|
52
|
+
|
53
|
+
this.initialize();
|
54
|
+
}
|
55
|
+
|
56
|
+
LunrSearch.prototype.initialize = function() {
|
57
|
+
var self = this;
|
58
|
+
|
59
|
+
this.loadIndexData(function(data) {
|
60
|
+
self.docs = $.map(data.docs, self.createEntry);
|
61
|
+
self.index = lunr.Index.load(data.index);
|
62
|
+
self.populateSearchFromQuery();
|
63
|
+
self.bindKeypress();
|
64
|
+
});
|
65
|
+
};
|
66
|
+
|
67
|
+
// compile search results template
|
68
|
+
LunrSearch.prototype.compileTemplate = function($template) {
|
69
|
+
var template = $template.text();
|
70
|
+
Mustache.parse(template);
|
71
|
+
return function (view, partials) {
|
72
|
+
return Mustache.render(template, view, partials);
|
73
|
+
};
|
74
|
+
};
|
75
|
+
|
76
|
+
// load the search index data
|
77
|
+
LunrSearch.prototype.loadIndexData = function(callback) {
|
78
|
+
$.getJSON(this.indexData, callback);
|
79
|
+
};
|
80
|
+
|
81
|
+
LunrSearch.prototype.createEntry = function(raw, index) {
|
82
|
+
var entry = $.extend({
|
83
|
+
id: index + 1
|
84
|
+
}, raw);
|
85
|
+
|
86
|
+
// include pub date for posts
|
87
|
+
if (raw.date) {
|
88
|
+
$.extend(entry, {
|
89
|
+
date: parseDate(raw.date),
|
90
|
+
pubdate: function() {
|
91
|
+
// HTML5 pubdate
|
92
|
+
return dateFormat(parseDate(raw.date), 'yyyy-mm-dd');
|
93
|
+
},
|
94
|
+
displaydate: function() {
|
95
|
+
// only for posts (e.g. Oct 12, 2012)
|
96
|
+
return dateFormat(parseDate(raw.date), 'mmm dd, yyyy');
|
97
|
+
}
|
98
|
+
});
|
99
|
+
}
|
100
|
+
|
101
|
+
return entry;
|
102
|
+
};
|
103
|
+
|
104
|
+
LunrSearch.prototype.bindKeypress = function() {
|
105
|
+
var self = this;
|
106
|
+
var oldValue = this.$elem.val();
|
107
|
+
|
108
|
+
this.$elem.bind('keyup', debounce(function() {
|
109
|
+
var newValue = self.$elem.val();
|
110
|
+
if (newValue !== oldValue) {
|
111
|
+
self.search(newValue);
|
112
|
+
}
|
113
|
+
|
114
|
+
oldValue = newValue;
|
115
|
+
}));
|
116
|
+
};
|
117
|
+
|
118
|
+
LunrSearch.prototype.search = function(query) {
|
119
|
+
var docs = this.docs;
|
120
|
+
|
121
|
+
if (query.length < 3) {
|
122
|
+
this.$results.hide().empty();
|
123
|
+
} else {
|
124
|
+
var results = $.map(this.index.search(query), function(result) {
|
125
|
+
return $.grep(docs, function(entry) {
|
126
|
+
return entry.id === parseInt(result.ref, 10); })[0];
|
127
|
+
});
|
128
|
+
|
129
|
+
this.displayResults(results);
|
130
|
+
this.onAfterResultShow();
|
131
|
+
}
|
132
|
+
};
|
133
|
+
|
134
|
+
LunrSearch.prototype.displayResults = function(docs) {
|
135
|
+
var $results = this.$results;
|
136
|
+
|
137
|
+
$results.empty();
|
138
|
+
|
139
|
+
if (docs.length === 0) {
|
140
|
+
$results.append( this.emptyMsg );
|
141
|
+
} else {
|
142
|
+
if (this.titleMsg && 0 !== this.titleMsg.length) {
|
143
|
+
$results.append( this.titleMsg );
|
144
|
+
}
|
145
|
+
$results.append(this.template({docs: docs}));
|
146
|
+
}
|
147
|
+
|
148
|
+
$results.show();
|
149
|
+
};
|
150
|
+
|
151
|
+
// Populate the search input with 'q' querystring parameter if set
|
152
|
+
LunrSearch.prototype.populateSearchFromQuery = function() {
|
153
|
+
var uri = new URI(window.location.search.toString());
|
154
|
+
var queryString = uri.search(true);
|
155
|
+
|
156
|
+
if (queryString.hasOwnProperty('q')) {
|
157
|
+
this.$elem.val(queryString.q);
|
158
|
+
this.search(queryString.q.toString());
|
159
|
+
}
|
160
|
+
};
|
161
|
+
|
162
|
+
return LunrSearch;
|
163
|
+
})();
|
164
|
+
|
165
|
+
$.fn.lunrSearch = function(options) {
|
166
|
+
// apply default options
|
167
|
+
options = $.extend({}, $.fn.lunrSearch.defaults, options);
|
168
|
+
|
169
|
+
// create search object
|
170
|
+
new LunrSearch(this, options);
|
171
|
+
|
172
|
+
return this;
|
173
|
+
};
|
174
|
+
|
175
|
+
// configuration defaults
|
176
|
+
$.fn.lunrSearch.defaults = {
|
177
|
+
index_file: ' /assets/data/lunr-index.json', // url for the .json file containing search index data
|
178
|
+
results: '#search-results', // selector for containing search results element
|
179
|
+
template: '#search-results-template', // selector for Mustache.js template
|
180
|
+
titleMsg: '<h1>Search results<h1>', // message attached in front of results
|
181
|
+
emptyMsg: '<p>Nothing found.</p>', // shown message if search returns no results
|
182
|
+
onAfterResultShow: function() {} // a hook to process the page after the search results have been shown
|
183
|
+
};
|
184
|
+
})(jQuery);
|
@@ -0,0 +1,17 @@
|
|
1
|
+
/*
|
2
|
+
# -----------------------------------------------------------------------------
|
3
|
+
# ~/assets/themes/j1/modules/lunr/js/jquery.lunr.search.js
|
4
|
+
# jQuery plugin to use with J1LunrSearch
|
5
|
+
#
|
6
|
+
# Product/Info:
|
7
|
+
# https://jekyll.one
|
8
|
+
#
|
9
|
+
# Copyright (C) 2020 Juergen Adams
|
10
|
+
#
|
11
|
+
# J1 Template is licensed under the MIT License.
|
12
|
+
# See: https://github.com/jekyll-one-org/J1 Template/blob/master/LICENSE
|
13
|
+
# -----------------------------------------------------------------------------
|
14
|
+
# TODO:
|
15
|
+
# -----------------------------------------------------------------------------
|
16
|
+
*/
|
17
|
+
"use strict";!function(t){var e=function(t){var e=t.match(/(\d+)/g);return new Date(e[0],e[1]-1,e[2])},n=function(){function n(e,n){this.$elem=e,this.$results=t(n.results),this.indexDataUrl=n.indexUrl,this.template=this.compileTemplate(t(n.template)),this.titleMsg=n.titleMsg,this.emptyMsg=n.emptyMsg,this.onAfterResultShow=n.onAfterResultShow,this.initialize()}return n.prototype.initialize=function(){var e=this;this.loadIndexData(function(n){e.docs=t.map(n.docs,e.createEntry),e.index=lunr.Index.load(n.index),e.populateSearchFromQuery(),e.bindKeypress()})},n.prototype.compileTemplate=function(t){var e=t.text();return Mustache.parse(e),function(t,n){return Mustache.render(e,t,n)}},n.prototype.loadIndexData=function(e){t.getJSON(this.indexDataUrl,e)},n.prototype.createEntry=function(n,r){var s=t.extend({id:r+1},n);return n.date&&t.extend(s,{date:e(n.date),pubdate:function(){return dateFormat(e(n.date),"yyyy-mm-dd")},displaydate:function(){return dateFormat(e(n.date),"mmm dd, yyyy")}}),s},n.prototype.bindKeypress=function(){var t,e,n,r=this,s=this.$elem.val();this.$elem.bind("keyup",(t=function(){var t=r.$elem.val();t!==s&&r.search(t),s=t},n=Array.prototype.slice,function(){var r=n.call(arguments),s=this;clearTimeout(e),e=setTimeout(function(){t.apply(s,r)},100)}))},n.prototype.search=function(e){var n=this.docs;if(e.length<3)this.$results.hide().empty();else{var r=t.map(this.index.search(e),function(e){return t.grep(n,function(t){return t.id===parseInt(e.ref,10)})[0]});this.displayResults(r),this.onAfterResultShow()}},n.prototype.displayResults=function(t){var e=this.$results;e.empty(),0===t.length?e.append(this.emptyMsg):(this.titleMsg&&0!==this.titleMsg.length&&e.append(this.titleMsg),e.append(this.template({docs:t}))),e.show()},n.prototype.populateSearchFromQuery=function(){var t=new URI(window.location.search.toString()).search(!0);t.hasOwnProperty("q")&&(this.$elem.val(t.q),this.search(t.q.toString()))},n}();t.fn.lunrSearch=function(e){return e=t.extend({},t.fn.lunrSearch.defaults,e),new n(this,e),this},t.fn.lunrSearch.defaults={indexUrl:"/assets/data/lunr-index.json",results:"#search-results",template:"#search-results-template",titleMsg:"<h1>Search results<h1>",emptyMsg:"<p>Nothing found.</p>",onAfterResultShow:function(){}}}(jQuery);
|
@@ -0,0 +1,772 @@
|
|
1
|
+
/*!
|
2
|
+
* mustache.js - Logic-less {{mustache}} templates with JavaScript
|
3
|
+
* http://github.com/janl/mustache.js
|
4
|
+
*/
|
5
|
+
|
6
|
+
(function (global, factory) {
|
7
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
8
|
+
typeof define === 'function' && define.amd ? define(factory) :
|
9
|
+
(global = global || self, global.Mustache = factory());
|
10
|
+
}(this, (function () { 'use strict';
|
11
|
+
|
12
|
+
var objectToString = Object.prototype.toString;
|
13
|
+
var isArray = Array.isArray || function isArrayPolyfill (object) {
|
14
|
+
return objectToString.call(object) === '[object Array]';
|
15
|
+
};
|
16
|
+
|
17
|
+
function isFunction (object) {
|
18
|
+
return typeof object === 'function';
|
19
|
+
}
|
20
|
+
|
21
|
+
/**
|
22
|
+
* More correct typeof string handling array
|
23
|
+
* which normally returns typeof 'object'
|
24
|
+
*/
|
25
|
+
function typeStr (obj) {
|
26
|
+
return isArray(obj) ? 'array' : typeof obj;
|
27
|
+
}
|
28
|
+
|
29
|
+
function escapeRegExp (string) {
|
30
|
+
return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&');
|
31
|
+
}
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Null safe way of checking whether or not an object,
|
35
|
+
* including its prototype, has a given property
|
36
|
+
*/
|
37
|
+
function hasProperty (obj, propName) {
|
38
|
+
return obj != null && typeof obj === 'object' && (propName in obj);
|
39
|
+
}
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Safe way of detecting whether or not the given thing is a primitive and
|
43
|
+
* whether it has the given property
|
44
|
+
*/
|
45
|
+
function primitiveHasOwnProperty (primitive, propName) {
|
46
|
+
return (
|
47
|
+
primitive != null
|
48
|
+
&& typeof primitive !== 'object'
|
49
|
+
&& primitive.hasOwnProperty
|
50
|
+
&& primitive.hasOwnProperty(propName)
|
51
|
+
);
|
52
|
+
}
|
53
|
+
|
54
|
+
// Workaround for https://issues.apache.org/jira/browse/COUCHDB-577
|
55
|
+
// See https://github.com/janl/mustache.js/issues/189
|
56
|
+
var regExpTest = RegExp.prototype.test;
|
57
|
+
function testRegExp (re, string) {
|
58
|
+
return regExpTest.call(re, string);
|
59
|
+
}
|
60
|
+
|
61
|
+
var nonSpaceRe = /\S/;
|
62
|
+
function isWhitespace (string) {
|
63
|
+
return !testRegExp(nonSpaceRe, string);
|
64
|
+
}
|
65
|
+
|
66
|
+
var entityMap = {
|
67
|
+
'&': '&',
|
68
|
+
'<': '<',
|
69
|
+
'>': '>',
|
70
|
+
'"': '"',
|
71
|
+
"'": ''',
|
72
|
+
'/': '/',
|
73
|
+
'`': '`',
|
74
|
+
'=': '='
|
75
|
+
};
|
76
|
+
|
77
|
+
function escapeHtml (string) {
|
78
|
+
return String(string).replace(/[&<>"'`=\/]/g, function fromEntityMap (s) {
|
79
|
+
return entityMap[s];
|
80
|
+
});
|
81
|
+
}
|
82
|
+
|
83
|
+
var whiteRe = /\s*/;
|
84
|
+
var spaceRe = /\s+/;
|
85
|
+
var equalsRe = /\s*=/;
|
86
|
+
var curlyRe = /\s*\}/;
|
87
|
+
var tagRe = /#|\^|\/|>|\{|&|=|!/;
|
88
|
+
|
89
|
+
/**
|
90
|
+
* Breaks up the given `template` string into a tree of tokens. If the `tags`
|
91
|
+
* argument is given here it must be an array with two string values: the
|
92
|
+
* opening and closing tags used in the template (e.g. [ "<%", "%>" ]). Of
|
93
|
+
* course, the default is to use mustaches (i.e. mustache.tags).
|
94
|
+
*
|
95
|
+
* A token is an array with at least 4 elements. The first element is the
|
96
|
+
* mustache symbol that was used inside the tag, e.g. "#" or "&". If the tag
|
97
|
+
* did not contain a symbol (i.e. {{myValue}}) this element is "name". For
|
98
|
+
* all text that appears outside a symbol this element is "text".
|
99
|
+
*
|
100
|
+
* The second element of a token is its "value". For mustache tags this is
|
101
|
+
* whatever else was inside the tag besides the opening symbol. For text tokens
|
102
|
+
* this is the text itself.
|
103
|
+
*
|
104
|
+
* The third and fourth elements of the token are the start and end indices,
|
105
|
+
* respectively, of the token in the original template.
|
106
|
+
*
|
107
|
+
* Tokens that are the root node of a subtree contain two more elements: 1) an
|
108
|
+
* array of tokens in the subtree and 2) the index in the original template at
|
109
|
+
* which the closing tag for that section begins.
|
110
|
+
*
|
111
|
+
* Tokens for partials also contain two more elements: 1) a string value of
|
112
|
+
* indendation prior to that tag and 2) the index of that tag on that line -
|
113
|
+
* eg a value of 2 indicates the partial is the third tag on this line.
|
114
|
+
*/
|
115
|
+
function parseTemplate (template, tags) {
|
116
|
+
if (!template)
|
117
|
+
return [];
|
118
|
+
var lineHasNonSpace = false;
|
119
|
+
var sections = []; // Stack to hold section tokens
|
120
|
+
var tokens = []; // Buffer to hold the tokens
|
121
|
+
var spaces = []; // Indices of whitespace tokens on the current line
|
122
|
+
var hasTag = false; // Is there a {{tag}} on the current line?
|
123
|
+
var nonSpace = false; // Is there a non-space char on the current line?
|
124
|
+
var indentation = ''; // Tracks indentation for tags that use it
|
125
|
+
var tagIndex = 0; // Stores a count of number of tags encountered on a line
|
126
|
+
|
127
|
+
// Strips all whitespace tokens array for the current line
|
128
|
+
// if there was a {{#tag}} on it and otherwise only space.
|
129
|
+
function stripSpace () {
|
130
|
+
if (hasTag && !nonSpace) {
|
131
|
+
while (spaces.length)
|
132
|
+
delete tokens[spaces.pop()];
|
133
|
+
} else {
|
134
|
+
spaces = [];
|
135
|
+
}
|
136
|
+
|
137
|
+
hasTag = false;
|
138
|
+
nonSpace = false;
|
139
|
+
}
|
140
|
+
|
141
|
+
var openingTagRe, closingTagRe, closingCurlyRe;
|
142
|
+
function compileTags (tagsToCompile) {
|
143
|
+
if (typeof tagsToCompile === 'string')
|
144
|
+
tagsToCompile = tagsToCompile.split(spaceRe, 2);
|
145
|
+
|
146
|
+
if (!isArray(tagsToCompile) || tagsToCompile.length !== 2)
|
147
|
+
throw new Error('Invalid tags: ' + tagsToCompile);
|
148
|
+
|
149
|
+
openingTagRe = new RegExp(escapeRegExp(tagsToCompile[0]) + '\\s*');
|
150
|
+
closingTagRe = new RegExp('\\s*' + escapeRegExp(tagsToCompile[1]));
|
151
|
+
closingCurlyRe = new RegExp('\\s*' + escapeRegExp('}' + tagsToCompile[1]));
|
152
|
+
}
|
153
|
+
|
154
|
+
compileTags(tags || mustache.tags);
|
155
|
+
|
156
|
+
var scanner = new Scanner(template);
|
157
|
+
|
158
|
+
var start, type, value, chr, token, openSection;
|
159
|
+
while (!scanner.eos()) {
|
160
|
+
start = scanner.pos;
|
161
|
+
|
162
|
+
// Match any text between tags.
|
163
|
+
value = scanner.scanUntil(openingTagRe);
|
164
|
+
|
165
|
+
if (value) {
|
166
|
+
for (var i = 0, valueLength = value.length; i < valueLength; ++i) {
|
167
|
+
chr = value.charAt(i);
|
168
|
+
|
169
|
+
if (isWhitespace(chr)) {
|
170
|
+
spaces.push(tokens.length);
|
171
|
+
indentation += chr;
|
172
|
+
} else {
|
173
|
+
nonSpace = true;
|
174
|
+
lineHasNonSpace = true;
|
175
|
+
indentation += ' ';
|
176
|
+
}
|
177
|
+
|
178
|
+
tokens.push([ 'text', chr, start, start + 1 ]);
|
179
|
+
start += 1;
|
180
|
+
|
181
|
+
// Check for whitespace on the current line.
|
182
|
+
if (chr === '\n') {
|
183
|
+
stripSpace();
|
184
|
+
indentation = '';
|
185
|
+
tagIndex = 0;
|
186
|
+
lineHasNonSpace = false;
|
187
|
+
}
|
188
|
+
}
|
189
|
+
}
|
190
|
+
|
191
|
+
// Match the opening tag.
|
192
|
+
if (!scanner.scan(openingTagRe))
|
193
|
+
break;
|
194
|
+
|
195
|
+
hasTag = true;
|
196
|
+
|
197
|
+
// Get the tag type.
|
198
|
+
type = scanner.scan(tagRe) || 'name';
|
199
|
+
scanner.scan(whiteRe);
|
200
|
+
|
201
|
+
// Get the tag value.
|
202
|
+
if (type === '=') {
|
203
|
+
value = scanner.scanUntil(equalsRe);
|
204
|
+
scanner.scan(equalsRe);
|
205
|
+
scanner.scanUntil(closingTagRe);
|
206
|
+
} else if (type === '{') {
|
207
|
+
value = scanner.scanUntil(closingCurlyRe);
|
208
|
+
scanner.scan(curlyRe);
|
209
|
+
scanner.scanUntil(closingTagRe);
|
210
|
+
type = '&';
|
211
|
+
} else {
|
212
|
+
value = scanner.scanUntil(closingTagRe);
|
213
|
+
}
|
214
|
+
|
215
|
+
// Match the closing tag.
|
216
|
+
if (!scanner.scan(closingTagRe))
|
217
|
+
throw new Error('Unclosed tag at ' + scanner.pos);
|
218
|
+
|
219
|
+
if (type == '>') {
|
220
|
+
token = [ type, value, start, scanner.pos, indentation, tagIndex, lineHasNonSpace ];
|
221
|
+
} else {
|
222
|
+
token = [ type, value, start, scanner.pos ];
|
223
|
+
}
|
224
|
+
tagIndex++;
|
225
|
+
tokens.push(token);
|
226
|
+
|
227
|
+
if (type === '#' || type === '^') {
|
228
|
+
sections.push(token);
|
229
|
+
} else if (type === '/') {
|
230
|
+
// Check section nesting.
|
231
|
+
openSection = sections.pop();
|
232
|
+
|
233
|
+
if (!openSection)
|
234
|
+
throw new Error('Unopened section "' + value + '" at ' + start);
|
235
|
+
|
236
|
+
if (openSection[1] !== value)
|
237
|
+
throw new Error('Unclosed section "' + openSection[1] + '" at ' + start);
|
238
|
+
} else if (type === 'name' || type === '{' || type === '&') {
|
239
|
+
nonSpace = true;
|
240
|
+
} else if (type === '=') {
|
241
|
+
// Set the tags for the next time around.
|
242
|
+
compileTags(value);
|
243
|
+
}
|
244
|
+
}
|
245
|
+
|
246
|
+
stripSpace();
|
247
|
+
|
248
|
+
// Make sure there are no open sections when we're done.
|
249
|
+
openSection = sections.pop();
|
250
|
+
|
251
|
+
if (openSection)
|
252
|
+
throw new Error('Unclosed section "' + openSection[1] + '" at ' + scanner.pos);
|
253
|
+
|
254
|
+
return nestTokens(squashTokens(tokens));
|
255
|
+
}
|
256
|
+
|
257
|
+
/**
|
258
|
+
* Combines the values of consecutive text tokens in the given `tokens` array
|
259
|
+
* to a single token.
|
260
|
+
*/
|
261
|
+
function squashTokens (tokens) {
|
262
|
+
var squashedTokens = [];
|
263
|
+
|
264
|
+
var token, lastToken;
|
265
|
+
for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {
|
266
|
+
token = tokens[i];
|
267
|
+
|
268
|
+
if (token) {
|
269
|
+
if (token[0] === 'text' && lastToken && lastToken[0] === 'text') {
|
270
|
+
lastToken[1] += token[1];
|
271
|
+
lastToken[3] = token[3];
|
272
|
+
} else {
|
273
|
+
squashedTokens.push(token);
|
274
|
+
lastToken = token;
|
275
|
+
}
|
276
|
+
}
|
277
|
+
}
|
278
|
+
|
279
|
+
return squashedTokens;
|
280
|
+
}
|
281
|
+
|
282
|
+
/**
|
283
|
+
* Forms the given array of `tokens` into a nested tree structure where
|
284
|
+
* tokens that represent a section have two additional items: 1) an array of
|
285
|
+
* all tokens that appear in that section and 2) the index in the original
|
286
|
+
* template that represents the end of that section.
|
287
|
+
*/
|
288
|
+
function nestTokens (tokens) {
|
289
|
+
var nestedTokens = [];
|
290
|
+
var collector = nestedTokens;
|
291
|
+
var sections = [];
|
292
|
+
|
293
|
+
var token, section;
|
294
|
+
for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {
|
295
|
+
token = tokens[i];
|
296
|
+
|
297
|
+
switch (token[0]) {
|
298
|
+
case '#':
|
299
|
+
case '^':
|
300
|
+
collector.push(token);
|
301
|
+
sections.push(token);
|
302
|
+
collector = token[4] = [];
|
303
|
+
break;
|
304
|
+
case '/':
|
305
|
+
section = sections.pop();
|
306
|
+
section[5] = token[2];
|
307
|
+
collector = sections.length > 0 ? sections[sections.length - 1][4] : nestedTokens;
|
308
|
+
break;
|
309
|
+
default:
|
310
|
+
collector.push(token);
|
311
|
+
}
|
312
|
+
}
|
313
|
+
|
314
|
+
return nestedTokens;
|
315
|
+
}
|
316
|
+
|
317
|
+
/**
|
318
|
+
* A simple string scanner that is used by the template parser to find
|
319
|
+
* tokens in template strings.
|
320
|
+
*/
|
321
|
+
function Scanner (string) {
|
322
|
+
this.string = string;
|
323
|
+
this.tail = string;
|
324
|
+
this.pos = 0;
|
325
|
+
}
|
326
|
+
|
327
|
+
/**
|
328
|
+
* Returns `true` if the tail is empty (end of string).
|
329
|
+
*/
|
330
|
+
Scanner.prototype.eos = function eos () {
|
331
|
+
return this.tail === '';
|
332
|
+
};
|
333
|
+
|
334
|
+
/**
|
335
|
+
* Tries to match the given regular expression at the current position.
|
336
|
+
* Returns the matched text if it can match, the empty string otherwise.
|
337
|
+
*/
|
338
|
+
Scanner.prototype.scan = function scan (re) {
|
339
|
+
var match = this.tail.match(re);
|
340
|
+
|
341
|
+
if (!match || match.index !== 0)
|
342
|
+
return '';
|
343
|
+
|
344
|
+
var string = match[0];
|
345
|
+
|
346
|
+
this.tail = this.tail.substring(string.length);
|
347
|
+
this.pos += string.length;
|
348
|
+
|
349
|
+
return string;
|
350
|
+
};
|
351
|
+
|
352
|
+
/**
|
353
|
+
* Skips all text until the given regular expression can be matched. Returns
|
354
|
+
* the skipped string, which is the entire tail if no match can be made.
|
355
|
+
*/
|
356
|
+
Scanner.prototype.scanUntil = function scanUntil (re) {
|
357
|
+
var index = this.tail.search(re), match;
|
358
|
+
|
359
|
+
switch (index) {
|
360
|
+
case -1:
|
361
|
+
match = this.tail;
|
362
|
+
this.tail = '';
|
363
|
+
break;
|
364
|
+
case 0:
|
365
|
+
match = '';
|
366
|
+
break;
|
367
|
+
default:
|
368
|
+
match = this.tail.substring(0, index);
|
369
|
+
this.tail = this.tail.substring(index);
|
370
|
+
}
|
371
|
+
|
372
|
+
this.pos += match.length;
|
373
|
+
|
374
|
+
return match;
|
375
|
+
};
|
376
|
+
|
377
|
+
/**
|
378
|
+
* Represents a rendering context by wrapping a view object and
|
379
|
+
* maintaining a reference to the parent context.
|
380
|
+
*/
|
381
|
+
function Context (view, parentContext) {
|
382
|
+
this.view = view;
|
383
|
+
this.cache = { '.': this.view };
|
384
|
+
this.parent = parentContext;
|
385
|
+
}
|
386
|
+
|
387
|
+
/**
|
388
|
+
* Creates a new context using the given view with this context
|
389
|
+
* as the parent.
|
390
|
+
*/
|
391
|
+
Context.prototype.push = function push (view) {
|
392
|
+
return new Context(view, this);
|
393
|
+
};
|
394
|
+
|
395
|
+
/**
|
396
|
+
* Returns the value of the given name in this context, traversing
|
397
|
+
* up the context hierarchy if the value is absent in this context's view.
|
398
|
+
*/
|
399
|
+
Context.prototype.lookup = function lookup (name) {
|
400
|
+
var cache = this.cache;
|
401
|
+
|
402
|
+
var value;
|
403
|
+
if (cache.hasOwnProperty(name)) {
|
404
|
+
value = cache[name];
|
405
|
+
} else {
|
406
|
+
var context = this, intermediateValue, names, index, lookupHit = false;
|
407
|
+
|
408
|
+
while (context) {
|
409
|
+
if (name.indexOf('.') > 0) {
|
410
|
+
intermediateValue = context.view;
|
411
|
+
names = name.split('.');
|
412
|
+
index = 0;
|
413
|
+
|
414
|
+
/**
|
415
|
+
* Using the dot notion path in `name`, we descend through the
|
416
|
+
* nested objects.
|
417
|
+
*
|
418
|
+
* To be certain that the lookup has been successful, we have to
|
419
|
+
* check if the last object in the path actually has the property
|
420
|
+
* we are looking for. We store the result in `lookupHit`.
|
421
|
+
*
|
422
|
+
* This is specially necessary for when the value has been set to
|
423
|
+
* `undefined` and we want to avoid looking up parent contexts.
|
424
|
+
*
|
425
|
+
* In the case where dot notation is used, we consider the lookup
|
426
|
+
* to be successful even if the last "object" in the path is
|
427
|
+
* not actually an object but a primitive (e.g., a string, or an
|
428
|
+
* integer), because it is sometimes useful to access a property
|
429
|
+
* of an autoboxed primitive, such as the length of a string.
|
430
|
+
**/
|
431
|
+
while (intermediateValue != null && index < names.length) {
|
432
|
+
if (index === names.length - 1)
|
433
|
+
lookupHit = (
|
434
|
+
hasProperty(intermediateValue, names[index])
|
435
|
+
|| primitiveHasOwnProperty(intermediateValue, names[index])
|
436
|
+
);
|
437
|
+
|
438
|
+
intermediateValue = intermediateValue[names[index++]];
|
439
|
+
}
|
440
|
+
} else {
|
441
|
+
intermediateValue = context.view[name];
|
442
|
+
|
443
|
+
/**
|
444
|
+
* Only checking against `hasProperty`, which always returns `false` if
|
445
|
+
* `context.view` is not an object. Deliberately omitting the check
|
446
|
+
* against `primitiveHasOwnProperty` if dot notation is not used.
|
447
|
+
*
|
448
|
+
* Consider this example:
|
449
|
+
* ```
|
450
|
+
* Mustache.render("The length of a football field is {{#length}}{{length}}{{/length}}.", {length: "100 yards"})
|
451
|
+
* ```
|
452
|
+
*
|
453
|
+
* If we were to check also against `primitiveHasOwnProperty`, as we do
|
454
|
+
* in the dot notation case, then render call would return:
|
455
|
+
*
|
456
|
+
* "The length of a football field is 9."
|
457
|
+
*
|
458
|
+
* rather than the expected:
|
459
|
+
*
|
460
|
+
* "The length of a football field is 100 yards."
|
461
|
+
**/
|
462
|
+
lookupHit = hasProperty(context.view, name);
|
463
|
+
}
|
464
|
+
|
465
|
+
if (lookupHit) {
|
466
|
+
value = intermediateValue;
|
467
|
+
break;
|
468
|
+
}
|
469
|
+
|
470
|
+
context = context.parent;
|
471
|
+
}
|
472
|
+
|
473
|
+
cache[name] = value;
|
474
|
+
}
|
475
|
+
|
476
|
+
if (isFunction(value))
|
477
|
+
value = value.call(this.view);
|
478
|
+
|
479
|
+
return value;
|
480
|
+
};
|
481
|
+
|
482
|
+
/**
|
483
|
+
* A Writer knows how to take a stream of tokens and render them to a
|
484
|
+
* string, given a context. It also maintains a cache of templates to
|
485
|
+
* avoid the need to parse the same template twice.
|
486
|
+
*/
|
487
|
+
function Writer () {
|
488
|
+
this.templateCache = {
|
489
|
+
_cache: {},
|
490
|
+
set: function set (key, value) {
|
491
|
+
this._cache[key] = value;
|
492
|
+
},
|
493
|
+
get: function get (key) {
|
494
|
+
return this._cache[key];
|
495
|
+
},
|
496
|
+
clear: function clear () {
|
497
|
+
this._cache = {};
|
498
|
+
}
|
499
|
+
};
|
500
|
+
}
|
501
|
+
|
502
|
+
/**
|
503
|
+
* Clears all cached templates in this writer.
|
504
|
+
*/
|
505
|
+
Writer.prototype.clearCache = function clearCache () {
|
506
|
+
if (typeof this.templateCache !== 'undefined') {
|
507
|
+
this.templateCache.clear();
|
508
|
+
}
|
509
|
+
};
|
510
|
+
|
511
|
+
/**
|
512
|
+
* Parses and caches the given `template` according to the given `tags` or
|
513
|
+
* `mustache.tags` if `tags` is omitted, and returns the array of tokens
|
514
|
+
* that is generated from the parse.
|
515
|
+
*/
|
516
|
+
Writer.prototype.parse = function parse (template, tags) {
|
517
|
+
var cache = this.templateCache;
|
518
|
+
var cacheKey = template + ':' + (tags || mustache.tags).join(':');
|
519
|
+
var isCacheEnabled = typeof cache !== 'undefined';
|
520
|
+
var tokens = isCacheEnabled ? cache.get(cacheKey) : undefined;
|
521
|
+
|
522
|
+
if (tokens == undefined) {
|
523
|
+
tokens = parseTemplate(template, tags);
|
524
|
+
isCacheEnabled && cache.set(cacheKey, tokens);
|
525
|
+
}
|
526
|
+
return tokens;
|
527
|
+
};
|
528
|
+
|
529
|
+
/**
|
530
|
+
* High-level method that is used to render the given `template` with
|
531
|
+
* the given `view`.
|
532
|
+
*
|
533
|
+
* The optional `partials` argument may be an object that contains the
|
534
|
+
* names and templates of partials that are used in the template. It may
|
535
|
+
* also be a function that is used to load partial templates on the fly
|
536
|
+
* that takes a single argument: the name of the partial.
|
537
|
+
*
|
538
|
+
* If the optional `config` argument is given here, then it should be an
|
539
|
+
* object with a `tags` attribute or an `escape` attribute or both.
|
540
|
+
* If an array is passed, then it will be interpreted the same way as
|
541
|
+
* a `tags` attribute on a `config` object.
|
542
|
+
*
|
543
|
+
* The `tags` attribute of a `config` object must be an array with two
|
544
|
+
* string values: the opening and closing tags used in the template (e.g.
|
545
|
+
* [ "<%", "%>" ]). The default is to mustache.tags.
|
546
|
+
*
|
547
|
+
* The `escape` attribute of a `config` object must be a function which
|
548
|
+
* accepts a string as input and outputs a safely escaped string.
|
549
|
+
* If an `escape` function is not provided, then an HTML-safe string
|
550
|
+
* escaping function is used as the default.
|
551
|
+
*/
|
552
|
+
Writer.prototype.render = function render (template, view, partials, config) {
|
553
|
+
var tags = this.getConfigTags(config);
|
554
|
+
var tokens = this.parse(template, tags);
|
555
|
+
var context = (view instanceof Context) ? view : new Context(view, undefined);
|
556
|
+
return this.renderTokens(tokens, context, partials, template, config);
|
557
|
+
};
|
558
|
+
|
559
|
+
/**
|
560
|
+
* Low-level method that renders the given array of `tokens` using
|
561
|
+
* the given `context` and `partials`.
|
562
|
+
*
|
563
|
+
* Note: The `originalTemplate` is only ever used to extract the portion
|
564
|
+
* of the original template that was contained in a higher-order section.
|
565
|
+
* If the template doesn't use higher-order sections, this argument may
|
566
|
+
* be omitted.
|
567
|
+
*/
|
568
|
+
Writer.prototype.renderTokens = function renderTokens (tokens, context, partials, originalTemplate, config) {
|
569
|
+
var buffer = '';
|
570
|
+
|
571
|
+
var token, symbol, value;
|
572
|
+
for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {
|
573
|
+
value = undefined;
|
574
|
+
token = tokens[i];
|
575
|
+
symbol = token[0];
|
576
|
+
|
577
|
+
if (symbol === '#') value = this.renderSection(token, context, partials, originalTemplate, config);
|
578
|
+
else if (symbol === '^') value = this.renderInverted(token, context, partials, originalTemplate, config);
|
579
|
+
else if (symbol === '>') value = this.renderPartial(token, context, partials, config);
|
580
|
+
else if (symbol === '&') value = this.unescapedValue(token, context);
|
581
|
+
else if (symbol === 'name') value = this.escapedValue(token, context, config);
|
582
|
+
else if (symbol === 'text') value = this.rawValue(token);
|
583
|
+
|
584
|
+
if (value !== undefined)
|
585
|
+
buffer += value;
|
586
|
+
}
|
587
|
+
|
588
|
+
return buffer;
|
589
|
+
};
|
590
|
+
|
591
|
+
Writer.prototype.renderSection = function renderSection (token, context, partials, originalTemplate, config) {
|
592
|
+
var self = this;
|
593
|
+
var buffer = '';
|
594
|
+
var value = context.lookup(token[1]);
|
595
|
+
|
596
|
+
// This function is used to render an arbitrary template
|
597
|
+
// in the current context by higher-order sections.
|
598
|
+
function subRender (template) {
|
599
|
+
return self.render(template, context, partials, config);
|
600
|
+
}
|
601
|
+
|
602
|
+
if (!value) return;
|
603
|
+
|
604
|
+
if (isArray(value)) {
|
605
|
+
for (var j = 0, valueLength = value.length; j < valueLength; ++j) {
|
606
|
+
buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate, config);
|
607
|
+
}
|
608
|
+
} else if (typeof value === 'object' || typeof value === 'string' || typeof value === 'number') {
|
609
|
+
buffer += this.renderTokens(token[4], context.push(value), partials, originalTemplate, config);
|
610
|
+
} else if (isFunction(value)) {
|
611
|
+
if (typeof originalTemplate !== 'string')
|
612
|
+
throw new Error('Cannot use higher-order sections without the original template');
|
613
|
+
|
614
|
+
// Extract the portion of the original template that the section contains.
|
615
|
+
value = value.call(context.view, originalTemplate.slice(token[3], token[5]), subRender);
|
616
|
+
|
617
|
+
if (value != null)
|
618
|
+
buffer += value;
|
619
|
+
} else {
|
620
|
+
buffer += this.renderTokens(token[4], context, partials, originalTemplate, config);
|
621
|
+
}
|
622
|
+
return buffer;
|
623
|
+
};
|
624
|
+
|
625
|
+
Writer.prototype.renderInverted = function renderInverted (token, context, partials, originalTemplate, config) {
|
626
|
+
var value = context.lookup(token[1]);
|
627
|
+
|
628
|
+
// Use JavaScript's definition of falsy. Include empty arrays.
|
629
|
+
// See https://github.com/janl/mustache.js/issues/186
|
630
|
+
if (!value || (isArray(value) && value.length === 0))
|
631
|
+
return this.renderTokens(token[4], context, partials, originalTemplate, config);
|
632
|
+
};
|
633
|
+
|
634
|
+
Writer.prototype.indentPartial = function indentPartial (partial, indentation, lineHasNonSpace) {
|
635
|
+
var filteredIndentation = indentation.replace(/[^ \t]/g, '');
|
636
|
+
var partialByNl = partial.split('\n');
|
637
|
+
for (var i = 0; i < partialByNl.length; i++) {
|
638
|
+
if (partialByNl[i].length && (i > 0 || !lineHasNonSpace)) {
|
639
|
+
partialByNl[i] = filteredIndentation + partialByNl[i];
|
640
|
+
}
|
641
|
+
}
|
642
|
+
return partialByNl.join('\n');
|
643
|
+
};
|
644
|
+
|
645
|
+
Writer.prototype.renderPartial = function renderPartial (token, context, partials, config) {
|
646
|
+
if (!partials) return;
|
647
|
+
var tags = this.getConfigTags(config);
|
648
|
+
|
649
|
+
var value = isFunction(partials) ? partials(token[1]) : partials[token[1]];
|
650
|
+
if (value != null) {
|
651
|
+
var lineHasNonSpace = token[6];
|
652
|
+
var tagIndex = token[5];
|
653
|
+
var indentation = token[4];
|
654
|
+
var indentedValue = value;
|
655
|
+
if (tagIndex == 0 && indentation) {
|
656
|
+
indentedValue = this.indentPartial(value, indentation, lineHasNonSpace);
|
657
|
+
}
|
658
|
+
var tokens = this.parse(indentedValue, tags);
|
659
|
+
return this.renderTokens(tokens, context, partials, indentedValue, config);
|
660
|
+
}
|
661
|
+
};
|
662
|
+
|
663
|
+
Writer.prototype.unescapedValue = function unescapedValue (token, context) {
|
664
|
+
var value = context.lookup(token[1]);
|
665
|
+
if (value != null)
|
666
|
+
return value;
|
667
|
+
};
|
668
|
+
|
669
|
+
Writer.prototype.escapedValue = function escapedValue (token, context, config) {
|
670
|
+
var escape = this.getConfigEscape(config) || mustache.escape;
|
671
|
+
var value = context.lookup(token[1]);
|
672
|
+
if (value != null)
|
673
|
+
return (typeof value === 'number' && escape === mustache.escape) ? String(value) : escape(value);
|
674
|
+
};
|
675
|
+
|
676
|
+
Writer.prototype.rawValue = function rawValue (token) {
|
677
|
+
return token[1];
|
678
|
+
};
|
679
|
+
|
680
|
+
Writer.prototype.getConfigTags = function getConfigTags (config) {
|
681
|
+
if (isArray(config)) {
|
682
|
+
return config;
|
683
|
+
}
|
684
|
+
else if (config && typeof config === 'object') {
|
685
|
+
return config.tags;
|
686
|
+
}
|
687
|
+
else {
|
688
|
+
return undefined;
|
689
|
+
}
|
690
|
+
};
|
691
|
+
|
692
|
+
Writer.prototype.getConfigEscape = function getConfigEscape (config) {
|
693
|
+
if (config && typeof config === 'object' && !isArray(config)) {
|
694
|
+
return config.escape;
|
695
|
+
}
|
696
|
+
else {
|
697
|
+
return undefined;
|
698
|
+
}
|
699
|
+
};
|
700
|
+
|
701
|
+
var mustache = {
|
702
|
+
name: 'mustache.js',
|
703
|
+
version: '4.0.1',
|
704
|
+
tags: [ '{{', '}}' ],
|
705
|
+
clearCache: undefined,
|
706
|
+
escape: undefined,
|
707
|
+
parse: undefined,
|
708
|
+
render: undefined,
|
709
|
+
Scanner: undefined,
|
710
|
+
Context: undefined,
|
711
|
+
Writer: undefined,
|
712
|
+
/**
|
713
|
+
* Allows a user to override the default caching strategy, by providing an
|
714
|
+
* object with set, get and clear methods. This can also be used to disable
|
715
|
+
* the cache by setting it to the literal `undefined`.
|
716
|
+
*/
|
717
|
+
set templateCache (cache) {
|
718
|
+
defaultWriter.templateCache = cache;
|
719
|
+
},
|
720
|
+
/**
|
721
|
+
* Gets the default or overridden caching object from the default writer.
|
722
|
+
*/
|
723
|
+
get templateCache () {
|
724
|
+
return defaultWriter.templateCache;
|
725
|
+
}
|
726
|
+
};
|
727
|
+
|
728
|
+
// All high-level mustache.* functions use this writer.
|
729
|
+
var defaultWriter = new Writer();
|
730
|
+
|
731
|
+
/**
|
732
|
+
* Clears all cached templates in the default writer.
|
733
|
+
*/
|
734
|
+
mustache.clearCache = function clearCache () {
|
735
|
+
return defaultWriter.clearCache();
|
736
|
+
};
|
737
|
+
|
738
|
+
/**
|
739
|
+
* Parses and caches the given template in the default writer and returns the
|
740
|
+
* array of tokens it contains. Doing this ahead of time avoids the need to
|
741
|
+
* parse templates on the fly as they are rendered.
|
742
|
+
*/
|
743
|
+
mustache.parse = function parse (template, tags) {
|
744
|
+
return defaultWriter.parse(template, tags);
|
745
|
+
};
|
746
|
+
|
747
|
+
/**
|
748
|
+
* Renders the `template` with the given `view`, `partials`, and `config`
|
749
|
+
* using the default writer.
|
750
|
+
*/
|
751
|
+
mustache.render = function render (template, view, partials, config) {
|
752
|
+
if (typeof template !== 'string') {
|
753
|
+
throw new TypeError('Invalid template! Template should be a "string" ' +
|
754
|
+
'but "' + typeStr(template) + '" was given as the first ' +
|
755
|
+
'argument for mustache#render(template, view, partials)');
|
756
|
+
}
|
757
|
+
|
758
|
+
return defaultWriter.render(template, view, partials, config);
|
759
|
+
};
|
760
|
+
|
761
|
+
// Export the escaping function so that the user may override it.
|
762
|
+
// See https://github.com/janl/mustache.js/issues/244
|
763
|
+
mustache.escape = escapeHtml;
|
764
|
+
|
765
|
+
// Export these mainly for testing, but also for advanced usage.
|
766
|
+
mustache.Scanner = Scanner;
|
767
|
+
mustache.Context = Context;
|
768
|
+
mustache.Writer = Writer;
|
769
|
+
|
770
|
+
return mustache;
|
771
|
+
|
772
|
+
})));
|