From 611e4b735b557384541060c4b67e455734326638 Mon Sep 17 00:00:00 2001 From: purkayasta Date: Sat, 17 Jun 2023 01:31:58 +0600 Subject: [PATCH 01/17] added documentation (docfx project) experimental --- documentation/docfx_project/.gitignore | 9 + documentation/docfx_project/articles/intro.md | 1 + documentation/docfx_project/articles/toc.yml | 2 + documentation/docfx_project/docfx.json | 54 ++ documentation/docfx_project/index.md | 4 + .../templates/singulinkfx/layout/_master.tmpl | 72 ++ .../singulinkfx/partials/footer.tmpl.partial | 4 + .../singulinkfx/partials/head.tmpl.partial | 24 + .../singulinkfx/partials/li.tmpl.partial | 31 + .../singulinkfx/partials/logo.tmpl.partial | 6 + .../partials/namespace.tmpl.partial | 13 + .../singulinkfx/partials/navbar.tmpl.partial | 19 + .../singulinkfx/partials/scripts.tmpl.partial | 13 + .../partials/searchResults.tmpl.partial | 9 + .../singulinkfx/partials/toc.tmpl.partial | 5 + .../templates/singulinkfx/styles/config.css | 124 ++++ .../templates/singulinkfx/styles/discord.css | 680 ++++++++++++++++++ .../singulinkfx/styles/down-arrow.svg | 44 ++ .../styles/jquery.twbsPagination.js | 317 ++++++++ .../styles/jquery.twbsPagination.min.js | 8 + .../templates/singulinkfx/styles/main.css | 0 .../templates/singulinkfx/styles/main.js | 0 .../singulinkfx/styles/singulink.css | 572 +++++++++++++++ .../templates/singulinkfx/styles/singulink.js | 51 ++ .../templates/singulinkfx/styles/url.min.js | 1 + .../templates/singulinkfx/toc.html.tmpl | 22 + documentation/docfx_project/toc.yml | 5 + 27 files changed, 2090 insertions(+) create mode 100644 documentation/docfx_project/.gitignore create mode 100644 documentation/docfx_project/articles/intro.md create mode 100644 documentation/docfx_project/articles/toc.yml create mode 100644 documentation/docfx_project/docfx.json create mode 100644 documentation/docfx_project/index.md create mode 100644 documentation/docfx_project/templates/singulinkfx/layout/_master.tmpl create mode 100644 documentation/docfx_project/templates/singulinkfx/partials/footer.tmpl.partial create mode 100644 documentation/docfx_project/templates/singulinkfx/partials/head.tmpl.partial create mode 100644 documentation/docfx_project/templates/singulinkfx/partials/li.tmpl.partial create mode 100644 documentation/docfx_project/templates/singulinkfx/partials/logo.tmpl.partial create mode 100644 documentation/docfx_project/templates/singulinkfx/partials/namespace.tmpl.partial create mode 100644 documentation/docfx_project/templates/singulinkfx/partials/navbar.tmpl.partial create mode 100644 documentation/docfx_project/templates/singulinkfx/partials/scripts.tmpl.partial create mode 100644 documentation/docfx_project/templates/singulinkfx/partials/searchResults.tmpl.partial create mode 100644 documentation/docfx_project/templates/singulinkfx/partials/toc.tmpl.partial create mode 100644 documentation/docfx_project/templates/singulinkfx/styles/config.css create mode 100644 documentation/docfx_project/templates/singulinkfx/styles/discord.css create mode 100644 documentation/docfx_project/templates/singulinkfx/styles/down-arrow.svg create mode 100644 documentation/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.js create mode 100644 documentation/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.min.js create mode 100644 documentation/docfx_project/templates/singulinkfx/styles/main.css create mode 100644 documentation/docfx_project/templates/singulinkfx/styles/main.js create mode 100644 documentation/docfx_project/templates/singulinkfx/styles/singulink.css create mode 100644 documentation/docfx_project/templates/singulinkfx/styles/singulink.js create mode 100644 documentation/docfx_project/templates/singulinkfx/styles/url.min.js create mode 100644 documentation/docfx_project/templates/singulinkfx/toc.html.tmpl create mode 100644 documentation/docfx_project/toc.yml diff --git a/documentation/docfx_project/.gitignore b/documentation/docfx_project/.gitignore new file mode 100644 index 0000000..b6af25f --- /dev/null +++ b/documentation/docfx_project/.gitignore @@ -0,0 +1,9 @@ +############### +# folder # +############### +/**/DROP/ +/**/TEMP/ +/**/packages/ +/**/bin/ +/**/obj/ + diff --git a/documentation/docfx_project/articles/intro.md b/documentation/docfx_project/articles/intro.md new file mode 100644 index 0000000..c0478ce --- /dev/null +++ b/documentation/docfx_project/articles/intro.md @@ -0,0 +1 @@ +# Add your introductions here! diff --git a/documentation/docfx_project/articles/toc.yml b/documentation/docfx_project/articles/toc.yml new file mode 100644 index 0000000..ff89ef1 --- /dev/null +++ b/documentation/docfx_project/articles/toc.yml @@ -0,0 +1,2 @@ +- name: Introduction + href: intro.md diff --git a/documentation/docfx_project/docfx.json b/documentation/docfx_project/docfx.json new file mode 100644 index 0000000..d8fb536 --- /dev/null +++ b/documentation/docfx_project/docfx.json @@ -0,0 +1,54 @@ +{ + "metadata": [ + { + "src": [ + { + "files": [ + "**.csproj" + ], + "src": "C:\\Users\\pritom\\source\\repos\\TheUtilityVerse\\src" + } + ], + "dest": "api", + "includePrivateMembers": false, + "disableGitFeatures": false, + "disableDefaultFilter": false, + "noRestore": false, + "namespaceLayout": "flattened", + "memberLayout": "samePage", + "allowCompilationErrors": false + } + ], + "build": { + "content": [ + { + "files": [ + "api/**.yml", + "api/index.md" + ] + }, + { + "files": [ + "articles/**.md", + "articles/**/toc.yml", + "toc.yml", + "*.md" + ] + } + ], + "resource": [ + { + "files": [ + "images/**" + ] + } + ], + "output": "_site", + "globalMetadataFiles": [], + "fileMetadataFiles": [], + "template": ["default", "templates/singulinkfx"], + "postProcessors": [], + "keepFileLink": false, + "disableGitFeatures": false + } +} \ No newline at end of file diff --git a/documentation/docfx_project/index.md b/documentation/docfx_project/index.md new file mode 100644 index 0000000..3ae2506 --- /dev/null +++ b/documentation/docfx_project/index.md @@ -0,0 +1,4 @@ +# This is the **HOMEPAGE**. +Refer to [Markdown](http://daringfireball.net/projects/markdown/) for how to write markdown files. +## Quick Start Notes: +1. Add images to the *images* folder if the file is referencing an image. diff --git a/documentation/docfx_project/templates/singulinkfx/layout/_master.tmpl b/documentation/docfx_project/templates/singulinkfx/layout/_master.tmpl new file mode 100644 index 0000000..8e43309 --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/layout/_master.tmpl @@ -0,0 +1,72 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} +{{!include(/^styles/.*/)}} +{{!include(/^fonts/.*/)}} +{{!include(favicon.ico)}} +{{!include(logo.svg)}} +{{!include(search-stopwords.json)}} + + + + {{>partials/head}} + + +
+ + + + + {{>partials/logo}} +
+ +
+
+ + + +
+ {{#_enableSearch}} + {{>partials/searchResults}} + {{/_enableSearch}} + + + + + + {{#_copyrightFooter}} + + {{/_copyrightFooter}} +
+
+ + {{>partials/scripts}} + + diff --git a/documentation/docfx_project/templates/singulinkfx/partials/footer.tmpl.partial b/documentation/docfx_project/templates/singulinkfx/partials/footer.tmpl.partial new file mode 100644 index 0000000..dd601a9 --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/partials/footer.tmpl.partial @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/partials/head.tmpl.partial b/documentation/docfx_project/templates/singulinkfx/partials/head.tmpl.partial new file mode 100644 index 0000000..2034340 --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/partials/head.tmpl.partial @@ -0,0 +1,24 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + + + + + {{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}} + + + + {{#_description}}{{/_description}} + + + + + + + + + + + {{#_noindex}}{{/_noindex}} + {{#_enableSearch}}{{/_enableSearch}} + {{#_enableNewTab}}{{/_enableNewTab}} + \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/partials/li.tmpl.partial b/documentation/docfx_project/templates/singulinkfx/partials/li.tmpl.partial new file mode 100644 index 0000000..2c8a3d0 --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/partials/li.tmpl.partial @@ -0,0 +1,31 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + + diff --git a/documentation/docfx_project/templates/singulinkfx/partials/logo.tmpl.partial b/documentation/docfx_project/templates/singulinkfx/partials/logo.tmpl.partial new file mode 100644 index 0000000..738ab5b --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/partials/logo.tmpl.partial @@ -0,0 +1,6 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + + + {{_appName}} + {{_appName}} + \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/partials/namespace.tmpl.partial b/documentation/docfx_project/templates/singulinkfx/partials/namespace.tmpl.partial new file mode 100644 index 0000000..42d64e6 --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/partials/namespace.tmpl.partial @@ -0,0 +1,13 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + +

{{>partials/title}}

+
{{{summary}}}
+
{{{conceptual}}}
+
{{{remarks}}}
+{{#children}} +

{{>partials/namespaceSubtitle}}

+ {{#children}} +
+
{{{summary}}}
+ {{/children}} +{{/children}} diff --git a/documentation/docfx_project/templates/singulinkfx/partials/navbar.tmpl.partial b/documentation/docfx_project/templates/singulinkfx/partials/navbar.tmpl.partial new file mode 100644 index 0000000..cfddfd8 --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/partials/navbar.tmpl.partial @@ -0,0 +1,19 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + +
+
+ {{>partials/logo}} +
+ + {{#_enableSearch}} +
+ +
+ {{/_enableSearch}} + + +
\ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/partials/scripts.tmpl.partial b/documentation/docfx_project/templates/singulinkfx/partials/scripts.tmpl.partial new file mode 100644 index 0000000..8ef7f26 --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/partials/scripts.tmpl.partial @@ -0,0 +1,13 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/partials/searchResults.tmpl.partial b/documentation/docfx_project/templates/singulinkfx/partials/searchResults.tmpl.partial new file mode 100644 index 0000000..9f08c90 --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/partials/searchResults.tmpl.partial @@ -0,0 +1,9 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + + \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/partials/toc.tmpl.partial b/documentation/docfx_project/templates/singulinkfx/partials/toc.tmpl.partial new file mode 100644 index 0000000..c660966 --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/partials/toc.tmpl.partial @@ -0,0 +1,5 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + +
+
+
diff --git a/documentation/docfx_project/templates/singulinkfx/styles/config.css b/documentation/docfx_project/templates/singulinkfx/styles/config.css new file mode 100644 index 0000000..cb39b51 --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/styles/config.css @@ -0,0 +1,124 @@ +/* Theme Configuration Options */ + +:root +{ + /* General */ + + --base-font-size: 16px; + --smalldevice-base-font-size: 14px; /* Base font size for devices < 1024px */ + + --main-bg-color: #1f1f23; + --footer-bg-color: rgba(0,0,0,.4); + --separator-color: #42474f; + + --table-strip-bg-color: #151515; + --table-header-bg-color: black; + --table-header-color: hsla(0,0%,100%,.8); + --table-header-border-color: #040405; + + /* Text */ + + --appname-color: white; + + --h1-color: white; + --h2-color: #f2f2f2; + --h3-color: #e3e3e3; + --h4-color: #ffffff; + --h5-color: #e0e0e0; + + --text-color: #e1e1e1; + --link-color: #00b0f4; + --link-hover-color: #2ec4ff; + + /* Mobile Topbar */ + + --topbar-bg-color: #18191c; + + /* Button */ + + --button-color: #747f8d; + + /* Sidebar */ + + --sidebar-width: 400px; + --sidebar-bg-color: #292B30; + + --search-color: #bdbdbd; + --search-bg-color: #1b1e21; + --search-searchicon-color: #e3e3e3; + --search-border-color: black; + + --sidebar-item-color: white; + --sidebar-active-item-color: #00b0f4; + --sidebar-level1-item-bg-color: #222429; + --sidebar-level1-item-hover-bg-color: #1D1F22; + + --toc-filter-color: #bdbdbd; + --toc-filter-bg-color: #1b1e21; + --toc-filter-filtericon-color: #e3e3e3; + --toc-filter-clearicon-color: #e68585; + --toc-filter-border-color: black; + + /* Scrollbars */ + + --scrollbar-bg-color: transparent; + --scrollbar-thumb-bg-color: rgba(0,0,0,.4); + --scrollbar-thumb-border-color: transparent; + + /* Alerts and Blocks */ + + --alert-info-border-color: rgba(114,137,218,.5); + --alert-info-bg-color: rgba(114,137,218,.1); + + --alert-warning-border-color: rgba(250,166,26,.5); + --alert-warning-bg-color: rgba(250,166,26,.1); + + --alert-danger-border-color: rgba(240,71,71,.5); + --alert-danger-bg-color: rgba(240,71,71,.1); + + --alert-tip-border-color: rgba(255,255,255,.5); + --alert-tip-bg-color: rgba(255,255,255,.1); + + --blockquote-border-color: rgba(255,255,255,.5); + --blockquote-bg-color: rgba(255,255,255,.1); + + --breadcrumb-bg-color: #2f3136; + + /* Tabs */ + + --nav-tabs-border-width: 1px; + --nav-tabs-border-color: #495057; + --nav-tabs-border-radius: .375rem; + --nav-tabs-link-hover-border-color: #303336 #303336 transparent; + --nav-tabs-link-active-color: white; + --nav-tabs-link-active-bg: var(--main-bg-color); + --nav-tabs-link-active-border-color: var(--nav-tabs-border-color) var(--nav-tabs-border-color) var(--main-bg-color); + + /* Inline Code */ + + --ref-bg-color: black; + --ref-color: #89d4f1; + + /* Code Blocks */ + + --code-bg-color: #151515; + --code-color: #d6deeb; + --code-keyword-color: #569cd6; + --code-comment-color: #57a64a; + --code-macro-color: #beb7ff; + --code-string-color: #d69d85; + --code-string-escape-color: #ffd68f; + --code-field-color: #c8c8c8; + --code-function-color: #dcdcaa; + --code-control-color: #d8a0df; + --code-class-color: #4ec9b0; + --code-number-color: #b5cea8; + --code-params-color: #9a9a9a; + --code-breakpoint-color: #8c2f2f; +} + +/* Code Block Overrides */ + +pre, legend { + --scrollbar-thumb-bg-color: #333; +} \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/styles/discord.css b/documentation/docfx_project/templates/singulinkfx/styles/discord.css new file mode 100644 index 0000000..fd53fc7 --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/styles/discord.css @@ -0,0 +1,680 @@ +/* Discord Style */ + +::-webkit-scrollbar { + width: 10px; +} + +::-webkit-scrollbar-track { + background: var(--scrollbar-bg-color); +} + +::-webkit-scrollbar-thumb { + background: var(--scrollbar-thumb-bg-color); + border-color: var(--scrollbar-thumb-border-color); + border-radius: 5px; +} + +::marker { + unicode-bidi: isolate; + font-variant-numeric: tabular-nums; + text-transform: none; + text-indent: 0px !important; + text-align: start !important; + text-align-last: start !important; +} + +*, :after, :before +{ + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +html, body +{ + padding: 0; + margin: 0; + font: 15px/150% 'Roboto', sans-serif; + overflow: hidden; + color: var(--text-color); + background-color: var(--main-bg-color); + + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; +} + +img { + max-width: 100%; +} + +ul > li, ol > li { + display: list-item; +} + +h1,h2,h3,h4,h5 +{ + color: var(--link-active-color); + position: relative; +} + +h1, h2 +{ + margin-block-start: 2em; +} + +h3 +{ + margin-block-start: 1em; + font-weight: 300; + font-size: 1.5em; + color: var(--h3-color); + margin-block-start: 3em; +} + +h4 +{ + opacity: 1; + color: var(--h4-color); + font-size: large; + border-bottom: 2px solid var(--separator-color); + margin: 20px 0 0 0; +} + + +h5 { + margin-block-end: .8em; + margin-block-start: 1em; + font-size: .85em; + font-weight: 500; + color: var(--h5-color); +} + +h6 { + font-size: .75em; + margin: 0; +} + +p +{ + font-weight: 400; +} + +ul +{ + position: relative; +} + +ul, ol +{ + padding-inline-start: 3em; +} + +ul.level1 +{ + list-style-type: none; + padding-inline-start: 0; +} + +ul.level2, ul.level3 +{ + padding-inline-start: 1em; + list-style-type: none; + font-size: .9em; +} + +a +{ + color: var(--link-color); + text-decoration: none; + transition: color .25s; +} + +a:focus, a:hover +{ + color: var(--link-hover-color); + text-decoration: underline; +} + +a.anchorjs-link:hover { + text-decoration: none; +} + +a.active, a:active +{ + color: var(--link-active-color); +} + +.body-content +{ + display: flex; + flex-direction: row; + height: 100%; + overflow-x: hidden; + overflow-y: hidden; +} + +.page-title +{ + margin-block-start: 0; +} + +nav +{ + width: 300px; + transition: left .5s ease-out; + position: fixed; + left: -350px; + top: 40px; + bottom: 0; + background-color: var(--sidebar-bg-color); + overflow-y: auto; + + display: flex; + flex-direction: column; + + z-index: 1000; +} + +h1:first-child +{ + margin-block-start: 1.1em; + margin-top: 1.1em; +} + +.sidebar +{ + padding: 32px 17px 32px 32px; + flex: 1; +} + +.sidebar-item +{ + font-size: 1em; + font-weight: 400; + display: block; + padding: 4px 16px; + color: var(--sidebar-item-color); +} + +.sidebar-item.large, #navbar .sidebar-item +{ + padding: 8px 16px; +} + +a.sidebar-item:hover, a.sidebar-item:focus +{ + color: var(--link-active-color); + text-decoration: none; +} + +a.sidebar-item.active +{ + color: var(--link-active-color); +} + +ul.level1 > li > a.sidebar-item +{ + background-color: transparent; + border-radius: 4px; +} + +#toc ul.level1 > li > a.sidebar-item.active +{ + background-color: var(--link-active-bg-color); +} + +.sidebar-item-separator +{ + height: 2px; + width: 100%; + background-color: var(--separator-color); + margin: 2em 0; + opacity: .8; +} + +span.sidebar-item +{ + font-weight: 700; + text-transform: uppercase; + font-size: .8em; + color: var(--text-color); + margin-block-start: 1.25em; +} + +.main-panel +{ + background-color: var(--main-bg-color); + flex: 1; + overflow-y: auto; + padding: 20px 40px; +} + +.top-navbar +{ + display: flex; + flex-direction: row; + align-items: center; + padding: 0 40px; + height: 40px; + background-color: var(--topbar-bg-color); +} + +.burger-icon +{ + margin-right: 1em; + color: var(--button-color); +} + +.burger-icon:hover, .burger-icon:focus +{ + color: var(--link-active-color); +} + +.burger-icon.active, .burger-icon:active +{ + color: var(--link-active-color); +} + +.brand +{ + display: flex; + align-items: center; + justify-content: start; +} + +.logomark +{ + height: 28px; +} + +.brand-title +{ + padding: 0 .5em; + font-size: .9em; + color: var(--link-active-color); +} + +.footer +{ + background-color: var(--footer-bg-color); + padding: 20px; + margin: 0 20px 20px 20px; + border-radius: 8px; + color: var(--link-active-color); +} + +.footer > h4 +{ + margin-block-start: 0; +} + +.blackout +{ + display: block; + visibility: hidden; + position: absolute; + z-index: 100; + top: 40px; + bottom: 0; + left: 0; + right: 0; + background-color: var(--footer-bg-color); +} + +@keyframes showThat { + 0% { opacity: 0; visibility: hidden; } + 1% { opacity: 0; visibility: visible; } + 100% { opacity: 1; visibility: visible;} +} + +@keyframes hideThat { + 0% { opacity: 1; visibility: visible; } + 99% { opacity: 0; visibility: visible; } + 100% { opacity: 0; visibility: hidden;} +} + +.showThat +{ + animation: showThat .5s forwards; +} + +.hideThat +{ + animation: hideThat .5s forwards; +} + + + +@media (min-width: 1024px) +{ + nav + { + position: relative; + left: 0!important; + top: 0; + bottom: 0; + } + + .top-navbar + { + display: none; + } + + .blackout + { + display: none; + } +} + +/* Table */ + +.table-responsive +{ + overflow-x: auto; + margin-bottom: 64px; +} + +table +{ + background-color: var(--code-bg-color); + border-collapse: collapse; + width: 100%; + table-layout: auto; +} + +table.table-striped tbody tr:nth-child(2n) +{ + background-color: var(--table-strip-bg-color); +} + +table thead +{ + background: var(--table-header-bg-color); +} + +table th +{ + color: var(--table-header-color); + text-transform: uppercase; + font-size: 12px; + line-height: 15px; + border-bottom: 1px solid var(--table-header-border-color); + padding: 8px; +} + +.table-condensed th { + text-align: left; +} + +table td +{ + padding: 8px; + font-weight: 300; +} + +table td > p +{ + margin: 0; +} + +/* Alerts */ +.alert { + border-radius: 4px; + padding: 8px; + margin: 25px 0; +} + +.alert > h5 +{ + display: none; + margin: 0; +} + +.alert > p +{ + margin: 0; + font-weight: 300; + font-size: 13px; +} + +.alert.alert-info +{ + border: 2px solid var(--alert-info-border-color); + background: var(--alert-info-bg-color); +} + +.alert.alert-warning +{ + border: 2px solid var(--alert-warning-border-color); + background: var(--alert-warning-bg-color); +} + +.alert.alert-danger +{ + border: 2px solid var(--alert-danger-border-color); + background: var(--alert-danger-bg-color); +} + +.TIP.alert.alert-info +{ + border: 2px solid var(--alert-tip-border-color); + background: var(--alert-tip-bg-color); +} + +blockquote { + margin: 8px 0; + border-left: 4px solid var(--blockquote-border-color); + padding: 8px; + background: var(--blockquote-bg-color); + border-radius: 4px; +} + +blockquote > p { + margin: 0; + font-style: italic; + font-size: 13px; +} + + +/* Breadcrumb */ + +#breadcrumb +{ + padding: 8px 16px; + background: var(--breadcrumb-bg-color); + border-radius: 4px; + margin-bottom: 30px; +} + +#breadcrumb:empty +{ + display: none; +} + +ul.breadcrumb +{ + display: flex; + flex-direction: row; + margin: 0; +} + +ul.breadcrumb > li { + margin-right: 6px; +} + +ul.breadcrumb > li::before +{ + content: "/"; + margin-right: 5px; +} + +ul.breadcrumb > li:first-child::before +{ + content: ""; + margin: 0; +} + + +/* Code */ + +legend, pre +{ + display: block; + background-color: var(--code-bg-color); + padding: 16px; + border-radius: 4px; +} + +code +{ + background-color: var(--code-bg-color); + padding: 2px 4px; + border-radius: 4px; +} + +.hljs +{ + background: transparent; +} + +/* DocFX related */ + +.small { + font-size: .9em; +} + +.pull-right +{ + float: right; +} + +.hide +{ + display: none; +} + +@media (max-width: 1023.98px) +{ + .mobile-hide + { + display: none; + } +} + +li +{ + display: block; + position: relative; +} + +.expand-stub +{ + cursor: pointer; + position: absolute; + width: 20px; + height: 20px; + left: -10px; +} + +ul.level1 > li > .expand-stub +{ + display: none; +} + +.toc .nav > li > .expand-stub::before, .toc .nav > li.active > .expand-stub::before +{ + content: " "; + position: absolute; + transform: rotate(-90deg); + width: 10px; + height: 10px; + top: 5px; + left: 5px; + background-repeat: no-repeat; + background: url(down-arrow.svg); +} + +.toc .nav > li.active > .expand-stub::before, .toc .nav > li.in > .expand-stub::before, .toc .nav > li.in.active > .expand-stub::before, .toc .nav > li.filtered > .expand-stub::before +{ + transform: none; +} + +li > ul +{ + display: none; +} + +li.in > ul +{ + display: block; +} + +ul.level2 > li > a.sidebar-item, +ul.level3 > li > a.sidebar-item +{ + font-size: .95em; + padding: 0; + margin: 2px 16px; +} + +ul.level2 > li > a.sidebar-item +{ + color: var(--sidebar-item-2nd-color); +} + +ul.level3 > li > a.sidebar-item +{ + color: var(--sidebar-item-3rd-color); +} + +ul.level2 > li > a.sidebar-item:hover, +ul.level2 > li > a.sidebar-item:focus, +ul.level3 > li > a.sidebar-item:hover, +ul.level3 > li > a.sidebar-item:focus +{ + color: var(--link-active-color); + text-decoration: underline; +} + +ul.level2 > li > a.sidebar-item.active, +ul.level3 > li > a.sidebar-item.active +{ + color: var(--link-active-color); +} + +.inheritance .level0:before, +.inheritance .level1:before, +.inheritance .level2:before, +.inheritance .level3:before, +.inheritance .level4:before, +.inheritance .level5:before { + content: '↳'; + margin-right: 5px; +} + +.inheritance .level0 { + margin-left: 0em; +} + +.inheritance .level1 { + margin-left: 1em; +} + +.inheritance .level2 { + margin-left: 2em; +} + +.inheritance .level3 { + margin-left: 3em; +} + +.inheritance .level4 { + margin-left: 4em; +} + +.inheritance .level5 { + margin-left: 5em; +} \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/styles/down-arrow.svg b/documentation/docfx_project/templates/singulinkfx/styles/down-arrow.svg new file mode 100644 index 0000000..e086126 --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/styles/down-arrow.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/documentation/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.js b/documentation/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.js new file mode 100644 index 0000000..332c01c --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.js @@ -0,0 +1,317 @@ +/*! + * jQuery pagination plugin v1.4.1 + * http://esimakin.github.io/twbs-pagination/ + * + * Copyright 2014-2016, Eugene Simakin + * Released under Apache 2.0 license + * http://apache.org/licenses/LICENSE-2.0.html + */ +(function ($, window, document, undefined) { + + 'use strict'; + + var old = $.fn.twbsPagination; + + // PROTOTYPE AND CONSTRUCTOR + + var TwbsPagination = function (element, options) { + this.$element = $(element); + this.options = $.extend({}, $.fn.twbsPagination.defaults, options); + + if (this.options.startPage < 1 || this.options.startPage > this.options.totalPages) { + throw new Error('Start page option is incorrect'); + } + + this.options.totalPages = parseInt(this.options.totalPages); + if (isNaN(this.options.totalPages)) { + throw new Error('Total pages option is not correct!'); + } + + this.options.visiblePages = parseInt(this.options.visiblePages); + if (isNaN(this.options.visiblePages)) { + throw new Error('Visible pages option is not correct!'); + } + + if (this.options.onPageClick instanceof Function) { + this.$element.first().on('page', this.options.onPageClick); + } + + // hide if only one page exists + if (this.options.hideOnlyOnePage && this.options.totalPages == 1) { + this.$element.trigger('page', 1); + return this; + } + + if (this.options.totalPages < this.options.visiblePages) { + this.options.visiblePages = this.options.totalPages; + } + + if (this.options.href) { + this.options.startPage = this.getPageFromQueryString(); + if (!this.options.startPage) { + this.options.startPage = 1; + } + } + + var tagName = (typeof this.$element.prop === 'function') ? + this.$element.prop('tagName') : this.$element.attr('tagName'); + + if (tagName === 'UL') { + this.$listContainer = this.$element; + } else { + this.$listContainer = $(''); + } + + this.$listContainer.addClass(this.options.paginationClass); + + if (tagName !== 'UL') { + this.$element.append(this.$listContainer); + } + + if (this.options.initiateStartPageClick) { + this.show(this.options.startPage); + } else { + this.render(this.getPages(this.options.startPage)); + this.setupEvents(); + } + + return this; + }; + + TwbsPagination.prototype = { + + constructor: TwbsPagination, + + destroy: function () { + this.$element.empty(); + this.$element.removeData('twbs-pagination'); + this.$element.off('page'); + + return this; + }, + + show: function (page) { + if (page < 1 || page > this.options.totalPages) { + throw new Error('Page is incorrect.'); + } + this.currentPage = page; + + this.render(this.getPages(page)); + this.setupEvents(); + + this.$element.trigger('page', page); + + return this; + }, + + buildListItems: function (pages) { + var listItems = []; + + if (this.options.first) { + listItems.push(this.buildItem('first', 1)); + } + + if (this.options.prev) { + var prev = pages.currentPage > 1 ? pages.currentPage - 1 : this.options.loop ? this.options.totalPages : 1; + listItems.push(this.buildItem('prev', prev)); + } + + for (var i = 0; i < pages.numeric.length; i++) { + listItems.push(this.buildItem('page', pages.numeric[i])); + } + + if (this.options.next) { + var next = pages.currentPage < this.options.totalPages ? pages.currentPage + 1 : this.options.loop ? 1 : this.options.totalPages; + listItems.push(this.buildItem('next', next)); + } + + if (this.options.last) { + listItems.push(this.buildItem('last', this.options.totalPages)); + } + + return listItems; + }, + + buildItem: function (type, page) { + var $itemContainer = $('
  • '), + $itemContent = $(''), + itemText = this.options[type] ? this.makeText(this.options[type], page) : page; + + $itemContainer.addClass(this.options[type + 'Class']); + $itemContainer.data('page', page); + $itemContainer.data('page-type', type); + $itemContainer.append($itemContent.attr('href', this.makeHref(page)).addClass(this.options.anchorClass).html(itemText)); + + return $itemContainer; + }, + + getPages: function (currentPage) { + var pages = []; + + var half = Math.floor(this.options.visiblePages / 2); + var start = currentPage - half + 1 - this.options.visiblePages % 2; + var end = currentPage + half; + + // handle boundary case + if (start <= 0) { + start = 1; + end = this.options.visiblePages; + } + if (end > this.options.totalPages) { + start = this.options.totalPages - this.options.visiblePages + 1; + end = this.options.totalPages; + } + + var itPage = start; + while (itPage <= end) { + pages.push(itPage); + itPage++; + } + + return {"currentPage": currentPage, "numeric": pages}; + }, + + render: function (pages) { + var _this = this; + this.$listContainer.children().remove(); + var items = this.buildListItems(pages); + jQuery.each(items, function(key, item){ + _this.$listContainer.append(item); + }); + + this.$listContainer.children().each(function () { + var $this = $(this), + pageType = $this.data('page-type'); + + switch (pageType) { + case 'page': + if ($this.data('page') === pages.currentPage) { + $this.addClass(_this.options.activeClass); + } + break; + case 'first': + $this.toggleClass(_this.options.disabledClass, pages.currentPage === 1); + break; + case 'last': + $this.toggleClass(_this.options.disabledClass, pages.currentPage === _this.options.totalPages); + break; + case 'prev': + $this.toggleClass(_this.options.disabledClass, !_this.options.loop && pages.currentPage === 1); + break; + case 'next': + $this.toggleClass(_this.options.disabledClass, + !_this.options.loop && pages.currentPage === _this.options.totalPages); + break; + default: + break; + } + + }); + }, + + setupEvents: function () { + var _this = this; + this.$listContainer.off('click').on('click', 'li', function (evt) { + var $this = $(this); + if ($this.hasClass(_this.options.disabledClass) || $this.hasClass(_this.options.activeClass)) { + return false; + } + // Prevent click event if href is not set. + !_this.options.href && evt.preventDefault(); + _this.show(parseInt($this.data('page'))); + }); + }, + + makeHref: function (page) { + return this.options.href ? this.generateQueryString(page) : "#"; + }, + + makeText: function (text, page) { + return text.replace(this.options.pageVariable, page) + .replace(this.options.totalPagesVariable, this.options.totalPages) + }, + getPageFromQueryString: function (searchStr) { + var search = this.getSearchString(searchStr), + regex = new RegExp(this.options.pageVariable + '(=([^&#]*)|&|#|$)'), + page = regex.exec(search); + if (!page || !page[2]) { + return null; + } + page = decodeURIComponent(page[2]); + page = parseInt(page); + if (isNaN(page)) { + return null; + } + return page; + }, + generateQueryString: function (pageNumber, searchStr) { + var search = this.getSearchString(searchStr), + regex = new RegExp(this.options.pageVariable + '=*[^&#]*'); + if (!search) return ''; + return '?' + search.replace(regex, this.options.pageVariable + '=' + pageNumber); + + }, + getSearchString: function (searchStr) { + var search = searchStr || window.location.search; + if (search === '') { + return null; + } + if (search.indexOf('?') === 0) search = search.substr(1); + return search; + } + + }; + + // PLUGIN DEFINITION + + $.fn.twbsPagination = function (option) { + var args = Array.prototype.slice.call(arguments, 1); + var methodReturn; + + var $this = $(this); + var data = $this.data('twbs-pagination'); + var options = typeof option === 'object' ? option : {}; + + if (!data) $this.data('twbs-pagination', (data = new TwbsPagination(this, options) )); + if (typeof option === 'string') methodReturn = data[ option ].apply(data, args); + + return ( methodReturn === undefined ) ? $this : methodReturn; + }; + + $.fn.twbsPagination.defaults = { + totalPages: 1, + startPage: 1, + visiblePages: 5, + initiateStartPageClick: true, + hideOnlyOnePage: false, + href: false, + pageVariable: '{{page}}', + totalPagesVariable: '{{total_pages}}', + page: null, + first: 'First', + prev: 'Previous', + next: 'Next', + last: 'Last', + loop: false, + onPageClick: null, + paginationClass: 'pagination', + nextClass: 'page-item next', + prevClass: 'page-item prev', + lastClass: 'page-item last', + firstClass: 'page-item first', + pageClass: 'page-item', + activeClass: 'active', + disabledClass: 'disabled', + anchorClass: 'page-link' + }; + + $.fn.twbsPagination.Constructor = TwbsPagination; + + $.fn.twbsPagination.noConflict = function () { + $.fn.twbsPagination = old; + return this; + }; + + $.fn.twbsPagination.version = "1.4.1"; + +})(window.jQuery, window, document); diff --git a/documentation/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.min.js b/documentation/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.min.js new file mode 100644 index 0000000..a9e11c6 --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.min.js @@ -0,0 +1,8 @@ +/*! + * jQuery pagination plugin v1.4.1 + * http://esimakin.github.io/twbs-pagination/ + * + * Copyright 2014-2016, Eugene Simakin + * Released under Apache 2.0 license + * http://apache.org/licenses/LICENSE-2.0.html + */ !function(t,s,i,e){"use strict";var a=t.fn.twbsPagination,o=function(s,i){if(this.$element=t(s),this.options=t.extend({},t.fn.twbsPagination.defaults,i),this.options.startPage<1||this.options.startPage>this.options.totalPages)throw Error("Start page option is incorrect");if(this.options.totalPages=parseInt(this.options.totalPages),isNaN(this.options.totalPages))throw Error("Total pages option is not correct!");if(this.options.visiblePages=parseInt(this.options.visiblePages),isNaN(this.options.visiblePages))throw Error("Visible pages option is not correct!");if(this.options.onPageClick instanceof Function&&this.$element.first().on("page",this.options.onPageClick),this.options.hideOnlyOnePage&&1==this.options.totalPages)return this.$element.trigger("page",1),this;this.options.totalPages"),this.$listContainer.addClass(this.options.paginationClass),"UL"!==e&&this.$element.append(this.$listContainer),this.options.initiateStartPageClick?this.show(this.options.startPage):(this.render(this.getPages(this.options.startPage)),this.setupEvents()),this};o.prototype={constructor:o,destroy:function(){return this.$element.empty(),this.$element.removeData("twbs-pagination"),this.$element.off("page"),this},show:function(t){if(t<1||t>this.options.totalPages)throw Error("Page is incorrect.");return this.currentPage=t,this.render(this.getPages(t)),this.setupEvents(),this.$element.trigger("page",t),this},buildListItems:function(t){var s=[];if(this.options.first&&s.push(this.buildItem("first",1)),this.options.prev){var i=t.currentPage>1?t.currentPage-1:this.options.loop?this.options.totalPages:1;s.push(this.buildItem("prev",i))}for(var e=0;e"),a=t(""),o=this.options[s]?this.makeText(this.options[s],i):i;return e.addClass(this.options[s+"Class"]),e.data("page",i),e.data("page-type",s),e.append(a.attr("href",this.makeHref(i)).addClass(this.options.anchorClass).html(o)),e},getPages:function(t){var s=[],i=Math.floor(this.options.visiblePages/2),e=t-i+1-this.options.visiblePages%2,a=t+i;e<=0&&(e=1,a=this.options.visiblePages),a>this.options.totalPages&&(e=this.options.totalPages-this.options.visiblePages+1,a=this.options.totalPages);for(var o=e;o<=a;)s.push(o),o++;return{currentPage:t,numeric:s}},render:function(s){var i=this;this.$listContainer.children().remove();var e=this.buildListItems(s);jQuery.each(e,function(t,s){i.$listContainer.append(s)}),this.$listContainer.children().each(function(){var e=t(this),a=e.data("page-type");switch(a){case"page":e.data("page")===s.currentPage&&e.addClass(i.options.activeClass);break;case"first":e.toggleClass(i.options.disabledClass,1===s.currentPage);break;case"last":e.toggleClass(i.options.disabledClass,s.currentPage===i.options.totalPages);break;case"prev":e.toggleClass(i.options.disabledClass,!i.options.loop&&1===s.currentPage);break;case"next":e.toggleClass(i.options.disabledClass,!i.options.loop&&s.currentPage===i.options.totalPages)}})},setupEvents:function(){var s=this;this.$listContainer.off("click").on("click","li",function(i){var e=t(this);if(e.hasClass(s.options.disabledClass)||e.hasClass(s.options.activeClass))return!1;s.options.href||i.preventDefault(),s.show(parseInt(e.data("page")))})},makeHref:function(t){return this.options.href?this.generateQueryString(t):"#"},makeText:function(t,s){return t.replace(this.options.pageVariable,s).replace(this.options.totalPagesVariable,this.options.totalPages)},getPageFromQueryString:function(t){var s=this.getSearchString(t),i=RegExp(this.options.pageVariable+"(=([^&#]*)|&|#|$)").exec(s);return i&&i[2]?(i=parseInt(i=decodeURIComponent(i[2])),isNaN(i))?null:i:null},generateQueryString:function(t,s){var i=this.getSearchString(s),e=RegExp(this.options.pageVariable+"=*[^&#]*");return i?"?"+i.replace(e,this.options.pageVariable+"="+t):""},getSearchString:function(t){var i=t||s.location.search;return""===i?null:(0===i.indexOf("?")&&(i=i.substr(1)),i)}},t.fn.twbsPagination=function(s){var i,e=Array.prototype.slice.call(arguments,1),a=t(this),n=a.data("twbs-pagination");return n||a.data("twbs-pagination",n=new o(this,"object"==typeof s?s:{})),"string"==typeof s&&(i=n[s].apply(n,e)),void 0===i?a:i},t.fn.twbsPagination.defaults={totalPages:1,startPage:1,visiblePages:5,initiateStartPageClick:!0,hideOnlyOnePage:!1,href:!1,pageVariable:"{{page}}",totalPagesVariable:"{{total_pages}}",page:null,first:"First",prev:"Previous",next:"Next",last:"Last",loop:!1,onPageClick:null,paginationClass:"pagination",nextClass:"page-item next",prevClass:"page-item prev",lastClass:"page-item last",firstClass:"page-item first",pageClass:"page-item",activeClass:"active",disabledClass:"disabled",anchorClass:"page-link"},t.fn.twbsPagination.Constructor=o,t.fn.twbsPagination.noConflict=function(){return t.fn.twbsPagination=a,this},t.fn.twbsPagination.version="1.4.1"}(window.jQuery,window,document); \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/styles/main.css b/documentation/docfx_project/templates/singulinkfx/styles/main.css new file mode 100644 index 0000000..e69de29 diff --git a/documentation/docfx_project/templates/singulinkfx/styles/main.js b/documentation/docfx_project/templates/singulinkfx/styles/main.js new file mode 100644 index 0000000..e69de29 diff --git a/documentation/docfx_project/templates/singulinkfx/styles/singulink.css b/documentation/docfx_project/templates/singulinkfx/styles/singulink.css new file mode 100644 index 0000000..b478f84 --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/styles/singulink.css @@ -0,0 +1,572 @@ +body { + font-size: var(--base-font-size); +} + +@media (max-width: 1024px) { + body { + font-size: var(--smalldevice-base-font-size); + } +} + +/* Headings */ + +h1, h2, h3, h4, h5 { + line-height: initial; +} + +h1, h1:first-child { + font-size: 2.25em; + letter-spacing: 0.5px; + color: var(--h1-color); + margin-block-start: 1em; + margin-block-end: -0.05em; +} + +.article h1 { + margin-block-end: -0.2em; +} + +h2 { + font-size: 2.1em; + color: var(--h2-color); +} + +.article h2 { + margin-block-start: 1.3em; + padding-bottom: 6px; + border-bottom: 1px solid var(--separator-color); +} + +h3 { + font-size: 1.95em; + font-weight: 500; + margin-block-start: 1.7em; +} + +.article h3 { + font-size: 1.85em; + font-weight: 500; + margin-block-start: 1.2em; + margin-block-end: 0.9em; +} + +h4 { + font-size: 1.8em; + font-weight: 400; + margin-block-start: 2em; + padding-bottom: 10px; +} + +.article h4 { + font-size: 1.5em; + font-weight: 300; + margin-block-start: 1em; + margin-block-end: 1em; + padding-bottom: 0; + border-bottom: none; +} + +h5 { + font-size: 1.1em; +} + +.article h5 { + font-size: 1.13em; + font-weight: 400; + text-decoration: underline; + margin-block-start: 1.5em; + margin-block-end: 1.0em; +} + +a.brand:hover +{ + text-decoration: none; +} + +a.brand .brand-title { + font-size: 1.4em; + font-weight: 500; + letter-spacing: 0.5px; + color: var(--appname-color); + margin-top: 1px; + padding: 0 0 0 0.4em; +} + +@media (min-width: 1024px) { + a.brand .brand-title { + font-size: 1.55em; + } +} + + +a.brand .logomark { + height: 35px; +} + +/* Top bar */ + +.top-navbar { + height: 60px; + padding: 0 0 0 10px; +} + +.burger-icon { + margin-right: 10px; +} + +/* Side Bar */ + +.sidebar { + padding: 25px 17px 32px 17px; +} + +.blackout { + top: 60px; +} + +@media (max-width: 1023.98px) { + .navbar-nav { + margin-top: 0; + } +} + +nav { + width: 94%; + max-width: var(--sidebar-width); + left: calc(var(--sidebar-width) * -1); +} + +@media (max-width: 1023.98px) { + nav { + top: 60px; + } +} + +nav ul { + list-style-type: none; +} + +nav .nav a, nav .nav a:hover { + text-decoration: none; + cursor: pointer; + display: block; +} + +nav a.sidebar-item { + padding: 4px 0 4px 10px; + cursor: pointer; +} + +nav a:focus, nav a.sidebar-item:hover, nav a.sidebar-item:focus { + text-decoration: underline; +} + +nav a, nav a:hover, nav a:focus { + color: var(--sidebar-item-color) !important; +} + +nav a.active, nav a.active:hover, nav a.active:focus { + color: var(--sidebar-active-item-color) !important; +} + +.sidebar-item-separator { + margin: 20px 0; +} + +#toc ul li a { + padding: 0 0 0 10px; +} + +.search { + background: var(--search-bg-color); + border: 1px solid var(--search-border-color); + border-radius: 5px; + position: relative; + margin-block-start: 25px; +} + +@media (max-width: 1023.98px) { + .search { + margin-block-start: 0; + margin-block-end: 15px; + } +} + +.search > input { + font-size: 0.95em; + color: var(--search-color); + border: 0; + background: none; + padding: 11px 30px 10px 37px; + width: 100%; +} + +.search > input:focus { + outline: 0; +} + +.search > .search-icon { + font-size: 1.2em; + color: var(--search-searchicon-color); + position: absolute; + top: 9px; + left: 9px; +} + +.toc-filter { + background: var(--toc-filter-bg-color); + border: 1px solid var(--toc-filter-border-color); + border-radius: 5px; + position: relative; +} + +.toc-filter > input { + font-size: 0.95em; + color: var(--toc-filter-color); + border: 0; + background: none; + padding: 11px 30px 10px 37px; + width: 100%; +} + +.toc-filter > input:focus { + outline: 0; +} + +.toc-filter > .filter-icon { + font-size: 1.2em; + color: var(--toc-filter-filtericon-color); + position: absolute; + top: 9px; + left: 9px; +} + +.toc-filter > .clear-icon { + color: var(--toc-filter-clearicon-color); + position: absolute; + top: 9px; + right: 9px; + cursor: pointer; +} + +.toc .nav > li > .expand-stub::before, .toc .nav > li.active > .expand-stub::before +{ + width: 8px; + height: 8px; + top: 6px; + left: 6px; +} + +#toc ul.level2 +{ + margin-bottom: 20px; +} + +#toc ul.level1 > li > a { + font-weight: 500; + margin-bottom: 10px; + padding: 5px 10px; +} + +#toc ul.level1 > li > a, #toc ul.level1 > li > a.active { + background-color: var(--sidebar-level1-item-bg-color) !important; + border-radius: 2px; +} + +#toc ul.level1 > li > a:hover, #toc ul.level1 > li > a.active:hover, +#toc ul.level1 > li > a:focus, #toc ul.level1 > li > a.active:focus { + background-color: var(--sidebar-level1-item-hover-bg-color) !important; + text-decoration: none; +} + +ul.level2 { + padding-inline-start: 0.7em; +} + +ul.level2 .expand-stub { + top: 1px; +} + +ul.level2 > li > a, ul.level2 > li > a.sidebar-item { + font-weight: 400; + color: var(--sidebar-item-color); + margin: 4px 0 4px; +} + +ul.level3 { + padding-inline-start: 1em; +} + +ul.level3 > li > a, ul.level3 > li > a.sidebar-item { + font-size: 1.05em; + color: var(--sidebar-item-color); + margin: 4px 0; +} + +ul.level4 { + padding-inline-start: 0; + margin-bottom: 12px; +} + +ul.level4 > li > a, ul.level4 > li > a.sidebar-item { + font-size: 1.05em; + color: var(--sidebar-item-color); + margin: 5px 0 5px 10px; +} + +/* Breadcrumbs */ + +.subnav.navbar { + margin: 0 -15px; +} + +#breadcrumb { + overflow: scroll; + margin-bottom: 0; +} + +#breadcrumb::-webkit-scrollbar { + display: none; +} + +#breadcrumb a { + white-space: nowrap; +} + +#breadcrumb wbr { + display: none; +} + +/* Search Results */ + +#search-results h1 { + margin-block-start: 0.5em; +} + +#search-results .item-title { + font-size: 1.3em; + margin-top: 1.5em; +} + +#search-results .item-href { + font-size: 0.85em; +} + +#search-results .item-brief { + margin-top: 0.7em; +} + +#search-results ul.pagination { + text-align: center; + padding: 10px 0 0 0; + margin-block-start: 40px; + border-top: 1px solid var(--separator-color); +} + +#search-results ul.pagination > li { + display: inline-block; + margin: 0 10px; +} + +#search-results ul.pagination > li.disabled a, #search-results ul.pagination > li.disabled a:hover { + color: var(--text-color); + cursor: txt; + text-decoration: none; +} + +/* Content */ + +.main-panel { + margin-bottom: 60px; + padding: 20px; +} + +@media (min-width: 1024px) { + .main-panel { + margin-bottom: 0; + padding: 20px 40px; + } +} + +.pull-right { + margin-top: 70px; + /* Fix unclickable links */ + position: relative; + z-index: 1; +} + +.divider { + margin-left: 4px; +} + +article ul li, article ol li { + margin-bottom: 10px; +} + +legend, pre { + padding: 6px; +} + +.hljs { + color: var(--code-color); +} + +.hljs::-webkit-scrollbar { + height: 6px; +} + +.hljs-keyword, .hljs-title, .hljs-built_in { + font-style: normal; +} + +p .xref, code { + background-color: var(--ref-bg-color); + color: var(--ref-color); + padding: 2px 3px; + font-family: monospace; + font-size: 0.95em; + border-radius: 6px; +} + +span.parametername { + font-family: monospace; +} + +.table { + width: auto; +} + +.table-responsive { + margin-bottom: 0; +} + +table th { + font-size: 14px; + padding: 9px 10px; +} + +table td p { + font-weight: 300; +} + +table td { + padding: 6px 10px; +} + +.footer { + text-align: center; + color: var(--text-color); + padding: 10px; +} + +.footer a:hover, .footer a:focus { + text-decoration: underline; +} + +.copyright-footer { + font-size: 0.85em; + font-weight: bold; + text-align: center; + margin-block-start: 30px; +} + +#contribution { + float: right; + margin-top: 1.1em; +} + + +/* Tabs */ + +.tabGroup { + margin-top: 1rem; + margin-bottom: 1rem; +} + +.tabGroup ul[role="tablist"] { + margin: 0; + padding: 0; + list-style: none; + border-bottom: var(--nav-tabs-border-width) solid var(--nav-tabs-border-color); +} + +.tabGroup ul[role="tablist"] > li { + list-style: none; + display: inline-block; + margin-bottom: 0; +} + +.tabGroup ul[role="tablist"] .dropdown-menu { + /* Make dropdown border overlap tab border */ + margin-top: calc(-1 * var(--nav-tabs-border-width)); + /* Remove the top rounded corners here since there is a hard edge above the menu */ + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.tabGroup a[role="tab"] { + display: block; + text-decoration: none; + padding: 0.5rem 1rem; + + margin-bottom: calc(-1 * var(--nav-tabs-border-width)); + border: var(--nav-tabs-border-width) solid transparent; + border-top-left-radius: var(--nav-tabs-border-radius); + border-top-right-radius: var(--nav-tabs-border-radius); +} + +.tabGroup a[role="tab"]:hover, .tabGroup a[role="tab"]:focus { + /* Prevents active .nav-link tab overlapping focus outline of previous/next .nav-link */ + isolation: isolate; + border-color: var(--nav-tabs-link-hover-border-color); +} + +.tabGroup a[role="tab"][aria-selected="true"] { + color: var(--nav-tabs-link-active-color); + background-color: var(--nav-tabs-link-active-bg); + border-color: var(--nav-tabs-link-active-border-color); +} + +.tabGroup a[role="tab"]:disabled { + color: var(--nav-link-disabled-color); + background-color: transparent; + border-color: transparent; +} + +.tabGroup section[role="tabpanel"] { + padding: 15px; + margin: 0; + overflow: hidden; + + border: var(--nav-tabs-border-width) solid var(--nav-tabs-border-color); + border-top: none; + border-bottom-left-radius: var(--nav-tabs-border-radius); + border-bottom-right-radius: var(--nav-tabs-border-radius); +} + +.tabGroup section[role="tabpanel"] > .codeHeader, +.tabGroup section[role="tabpanel"] > pre { + margin-left: -16px; + margin-right: -16px; +} + +.tabGroup section[role="tabpanel"] > :first-child { + margin-top: 0; +} + +.tabGroup section[role="tabpanel"] > pre:last-child { + display: block; + margin-bottom: -16px; +} + +.tabGroup > section { + margin: 0; + padding: 1rem; + border-top: 0; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.mainContainer[dir='rtl'] main ul[role="tablist"] { + margin: 0; +} \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/styles/singulink.js b/documentation/docfx_project/templates/singulinkfx/styles/singulink.js new file mode 100644 index 0000000..40b0d0b --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/styles/singulink.js @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information. + +function toggleMenu() { + + var sidebar = document.getElementById("sidebar"); + var blackout = document.getElementById("blackout"); + + if (sidebar.style.left === "0px") + { + sidebar.style.left = "-" + sidebar.offsetWidth + "px"; + blackout.classList.remove("showThat"); + blackout.classList.add("hideThat"); + } + else + { + sidebar.style.left = "0px"; + blackout.classList.remove("hideThat"); + blackout.classList.add("showThat"); + } +} + +$(function() { + $('table').each(function(a, tbl) { + var currentTableRows = $(tbl).find('tbody tr').length; + $(tbl).find('th').each(function(i) { + var remove = 0; + var currentTable = $(this).parents('table'); + + var tds = currentTable.find('tr td:nth-child(' + (i + 1) + ')'); + tds.each(function(j) { if ($(this).text().trim() === '') remove++; }); + + if (remove == currentTableRows) { + $(this).hide(); + tds.hide(); + } + }); + }); + + function scrollToc() { + var activeTocItem = $('.sidebar .sidebar-item.active:last')[0] + + if (activeTocItem) { + activeTocItem.scrollIntoView({ block: "center" }); + } + else{ + setTimeout(scrollToc, 500); + } + } + + setTimeout(scrollToc, 500); +}); \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/styles/url.min.js b/documentation/docfx_project/templates/singulinkfx/styles/url.min.js new file mode 100644 index 0000000..8057e0a --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/styles/url.min.js @@ -0,0 +1 @@ +/*! url - v1.8.6 - 2013-11-22 */window.url=function(){function a(a){return!isNaN(parseFloat(a))&&isFinite(a)}return function(b,c){var d=c||window.location.toString();if(!b)return d;b=b.toString(),"//"===d.substring(0,2)?d="http:"+d:1===d.split("://").length&&(d="http://"+d),c=d.split("/");var e={auth:""},f=c[2].split("@");1===f.length?f=f[0].split(":"):(e.auth=f[0],f=f[1].split(":")),e.protocol=c[0],e.hostname=f[0],e.port=f[1]||("https"===e.protocol.split(":")[0].toLowerCase()?"443":"80"),e.pathname=(c.length>3?"/":"")+c.slice(3,c.length).join("/").split("?")[0].split("#")[0];var g=e.pathname;"/"===g.charAt(g.length-1)&&(g=g.substring(0,g.length-1));var h=e.hostname,i=h.split("."),j=g.split("/");if("hostname"===b)return h;if("domain"===b)return/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/.test(h)?h:i.slice(-2).join(".");if("sub"===b)return i.slice(0,i.length-2).join(".");if("port"===b)return e.port;if("protocol"===b)return e.protocol.split(":")[0];if("auth"===b)return e.auth;if("user"===b)return e.auth.split(":")[0];if("pass"===b)return e.auth.split(":")[1]||"";if("path"===b)return e.pathname;if("."===b.charAt(0)){if(b=b.substring(1),a(b))return b=parseInt(b,10),i[0>b?i.length+b:b-1]||""}else{if(a(b))return b=parseInt(b,10),j[0>b?j.length+b:b]||"";if("file"===b)return j.slice(-1)[0];if("filename"===b)return j.slice(-1)[0].split(".")[0];if("fileext"===b)return j.slice(-1)[0].split(".")[1]||"";if("?"===b.charAt(0)||"#"===b.charAt(0)){var k=d,l=null;if("?"===b.charAt(0)?k=(k.split("?")[1]||"").split("#")[0]:"#"===b.charAt(0)&&(k=k.split("#")[1]||""),!b.charAt(1))return k;b=b.substring(1),k=k.split("&");for(var m=0,n=k.length;n>m;m++)if(l=k[m].split("="),l[0]===b)return l[1]||"";return null}}return""}}(),"undefined"!=typeof jQuery&&jQuery.extend({url:function(a,b){return window.url(a,b)}}); \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/toc.html.tmpl b/documentation/docfx_project/templates/singulinkfx/toc.html.tmpl new file mode 100644 index 0000000..6549e62 --- /dev/null +++ b/documentation/docfx_project/templates/singulinkfx/toc.html.tmpl @@ -0,0 +1,22 @@ +{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} + +
    +
    + {{^_disableSideFilter}} +
    +
    + + + +
    +
    + {{/_disableSideFilter}} +
    +
    + {{^leaf}} + {{>partials/li}} + {{/leaf}} +
    +
    +
    +
    \ No newline at end of file diff --git a/documentation/docfx_project/toc.yml b/documentation/docfx_project/toc.yml new file mode 100644 index 0000000..59f8010 --- /dev/null +++ b/documentation/docfx_project/toc.yml @@ -0,0 +1,5 @@ +- name: Articles + href: articles/ +- name: Api Documentation + href: api/ + homepage: api/index.md From e2ade72527021e7801e0608c82fd13d088c9d4c6 Mon Sep 17 00:00:00 2001 From: purkayasta Date: Sat, 17 Jun 2023 20:39:36 +0600 Subject: [PATCH 02/17] docfx removed --- documentation/docfx_project/.gitignore | 9 - documentation/docfx_project/articles/intro.md | 1 - documentation/docfx_project/articles/toc.yml | 2 - documentation/docfx_project/docfx.json | 54 -- documentation/docfx_project/index.md | 4 - .../templates/singulinkfx/layout/_master.tmpl | 72 -- .../singulinkfx/partials/footer.tmpl.partial | 4 - .../singulinkfx/partials/head.tmpl.partial | 24 - .../singulinkfx/partials/li.tmpl.partial | 31 - .../singulinkfx/partials/logo.tmpl.partial | 6 - .../partials/namespace.tmpl.partial | 13 - .../singulinkfx/partials/navbar.tmpl.partial | 19 - .../singulinkfx/partials/scripts.tmpl.partial | 13 - .../partials/searchResults.tmpl.partial | 9 - .../singulinkfx/partials/toc.tmpl.partial | 5 - .../templates/singulinkfx/styles/config.css | 124 ---- .../templates/singulinkfx/styles/discord.css | 680 ------------------ .../singulinkfx/styles/down-arrow.svg | 44 -- .../styles/jquery.twbsPagination.js | 317 -------- .../styles/jquery.twbsPagination.min.js | 8 - .../templates/singulinkfx/styles/main.css | 0 .../templates/singulinkfx/styles/main.js | 0 .../singulinkfx/styles/singulink.css | 572 --------------- .../templates/singulinkfx/styles/singulink.js | 51 -- .../templates/singulinkfx/styles/url.min.js | 1 - .../templates/singulinkfx/toc.html.tmpl | 22 - documentation/docfx_project/toc.yml | 5 - 27 files changed, 2090 deletions(-) delete mode 100644 documentation/docfx_project/.gitignore delete mode 100644 documentation/docfx_project/articles/intro.md delete mode 100644 documentation/docfx_project/articles/toc.yml delete mode 100644 documentation/docfx_project/docfx.json delete mode 100644 documentation/docfx_project/index.md delete mode 100644 documentation/docfx_project/templates/singulinkfx/layout/_master.tmpl delete mode 100644 documentation/docfx_project/templates/singulinkfx/partials/footer.tmpl.partial delete mode 100644 documentation/docfx_project/templates/singulinkfx/partials/head.tmpl.partial delete mode 100644 documentation/docfx_project/templates/singulinkfx/partials/li.tmpl.partial delete mode 100644 documentation/docfx_project/templates/singulinkfx/partials/logo.tmpl.partial delete mode 100644 documentation/docfx_project/templates/singulinkfx/partials/namespace.tmpl.partial delete mode 100644 documentation/docfx_project/templates/singulinkfx/partials/navbar.tmpl.partial delete mode 100644 documentation/docfx_project/templates/singulinkfx/partials/scripts.tmpl.partial delete mode 100644 documentation/docfx_project/templates/singulinkfx/partials/searchResults.tmpl.partial delete mode 100644 documentation/docfx_project/templates/singulinkfx/partials/toc.tmpl.partial delete mode 100644 documentation/docfx_project/templates/singulinkfx/styles/config.css delete mode 100644 documentation/docfx_project/templates/singulinkfx/styles/discord.css delete mode 100644 documentation/docfx_project/templates/singulinkfx/styles/down-arrow.svg delete mode 100644 documentation/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.js delete mode 100644 documentation/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.min.js delete mode 100644 documentation/docfx_project/templates/singulinkfx/styles/main.css delete mode 100644 documentation/docfx_project/templates/singulinkfx/styles/main.js delete mode 100644 documentation/docfx_project/templates/singulinkfx/styles/singulink.css delete mode 100644 documentation/docfx_project/templates/singulinkfx/styles/singulink.js delete mode 100644 documentation/docfx_project/templates/singulinkfx/styles/url.min.js delete mode 100644 documentation/docfx_project/templates/singulinkfx/toc.html.tmpl delete mode 100644 documentation/docfx_project/toc.yml diff --git a/documentation/docfx_project/.gitignore b/documentation/docfx_project/.gitignore deleted file mode 100644 index b6af25f..0000000 --- a/documentation/docfx_project/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -############### -# folder # -############### -/**/DROP/ -/**/TEMP/ -/**/packages/ -/**/bin/ -/**/obj/ - diff --git a/documentation/docfx_project/articles/intro.md b/documentation/docfx_project/articles/intro.md deleted file mode 100644 index c0478ce..0000000 --- a/documentation/docfx_project/articles/intro.md +++ /dev/null @@ -1 +0,0 @@ -# Add your introductions here! diff --git a/documentation/docfx_project/articles/toc.yml b/documentation/docfx_project/articles/toc.yml deleted file mode 100644 index ff89ef1..0000000 --- a/documentation/docfx_project/articles/toc.yml +++ /dev/null @@ -1,2 +0,0 @@ -- name: Introduction - href: intro.md diff --git a/documentation/docfx_project/docfx.json b/documentation/docfx_project/docfx.json deleted file mode 100644 index d8fb536..0000000 --- a/documentation/docfx_project/docfx.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "metadata": [ - { - "src": [ - { - "files": [ - "**.csproj" - ], - "src": "C:\\Users\\pritom\\source\\repos\\TheUtilityVerse\\src" - } - ], - "dest": "api", - "includePrivateMembers": false, - "disableGitFeatures": false, - "disableDefaultFilter": false, - "noRestore": false, - "namespaceLayout": "flattened", - "memberLayout": "samePage", - "allowCompilationErrors": false - } - ], - "build": { - "content": [ - { - "files": [ - "api/**.yml", - "api/index.md" - ] - }, - { - "files": [ - "articles/**.md", - "articles/**/toc.yml", - "toc.yml", - "*.md" - ] - } - ], - "resource": [ - { - "files": [ - "images/**" - ] - } - ], - "output": "_site", - "globalMetadataFiles": [], - "fileMetadataFiles": [], - "template": ["default", "templates/singulinkfx"], - "postProcessors": [], - "keepFileLink": false, - "disableGitFeatures": false - } -} \ No newline at end of file diff --git a/documentation/docfx_project/index.md b/documentation/docfx_project/index.md deleted file mode 100644 index 3ae2506..0000000 --- a/documentation/docfx_project/index.md +++ /dev/null @@ -1,4 +0,0 @@ -# This is the **HOMEPAGE**. -Refer to [Markdown](http://daringfireball.net/projects/markdown/) for how to write markdown files. -## Quick Start Notes: -1. Add images to the *images* folder if the file is referencing an image. diff --git a/documentation/docfx_project/templates/singulinkfx/layout/_master.tmpl b/documentation/docfx_project/templates/singulinkfx/layout/_master.tmpl deleted file mode 100644 index 8e43309..0000000 --- a/documentation/docfx_project/templates/singulinkfx/layout/_master.tmpl +++ /dev/null @@ -1,72 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} -{{!include(/^styles/.*/)}} -{{!include(/^fonts/.*/)}} -{{!include(favicon.ico)}} -{{!include(logo.svg)}} -{{!include(search-stopwords.json)}} - - - - {{>partials/head}} - - -
    - - - - - {{>partials/logo}} -
    - -
    -
    - - - -
    - {{#_enableSearch}} - {{>partials/searchResults}} - {{/_enableSearch}} - - - - - - {{#_copyrightFooter}} - - {{/_copyrightFooter}} -
    -
    - - {{>partials/scripts}} - - diff --git a/documentation/docfx_project/templates/singulinkfx/partials/footer.tmpl.partial b/documentation/docfx_project/templates/singulinkfx/partials/footer.tmpl.partial deleted file mode 100644 index dd601a9..0000000 --- a/documentation/docfx_project/templates/singulinkfx/partials/footer.tmpl.partial +++ /dev/null @@ -1,4 +0,0 @@ - \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/partials/head.tmpl.partial b/documentation/docfx_project/templates/singulinkfx/partials/head.tmpl.partial deleted file mode 100644 index 2034340..0000000 --- a/documentation/docfx_project/templates/singulinkfx/partials/head.tmpl.partial +++ /dev/null @@ -1,24 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - - - - - {{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}} - - - - {{#_description}}{{/_description}} - - - - - - - - - - - {{#_noindex}}{{/_noindex}} - {{#_enableSearch}}{{/_enableSearch}} - {{#_enableNewTab}}{{/_enableNewTab}} - \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/partials/li.tmpl.partial b/documentation/docfx_project/templates/singulinkfx/partials/li.tmpl.partial deleted file mode 100644 index 2c8a3d0..0000000 --- a/documentation/docfx_project/templates/singulinkfx/partials/li.tmpl.partial +++ /dev/null @@ -1,31 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - - diff --git a/documentation/docfx_project/templates/singulinkfx/partials/logo.tmpl.partial b/documentation/docfx_project/templates/singulinkfx/partials/logo.tmpl.partial deleted file mode 100644 index 738ab5b..0000000 --- a/documentation/docfx_project/templates/singulinkfx/partials/logo.tmpl.partial +++ /dev/null @@ -1,6 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - - - {{_appName}} - {{_appName}} - \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/partials/namespace.tmpl.partial b/documentation/docfx_project/templates/singulinkfx/partials/namespace.tmpl.partial deleted file mode 100644 index 42d64e6..0000000 --- a/documentation/docfx_project/templates/singulinkfx/partials/namespace.tmpl.partial +++ /dev/null @@ -1,13 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - -

    {{>partials/title}}

    -
    {{{summary}}}
    -
    {{{conceptual}}}
    -
    {{{remarks}}}
    -{{#children}} -

    {{>partials/namespaceSubtitle}}

    - {{#children}} -
    -
    {{{summary}}}
    - {{/children}} -{{/children}} diff --git a/documentation/docfx_project/templates/singulinkfx/partials/navbar.tmpl.partial b/documentation/docfx_project/templates/singulinkfx/partials/navbar.tmpl.partial deleted file mode 100644 index cfddfd8..0000000 --- a/documentation/docfx_project/templates/singulinkfx/partials/navbar.tmpl.partial +++ /dev/null @@ -1,19 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - -
    -
    - {{>partials/logo}} -
    - - {{#_enableSearch}} -
    - -
    - {{/_enableSearch}} - - -
    \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/partials/scripts.tmpl.partial b/documentation/docfx_project/templates/singulinkfx/partials/scripts.tmpl.partial deleted file mode 100644 index 8ef7f26..0000000 --- a/documentation/docfx_project/templates/singulinkfx/partials/scripts.tmpl.partial +++ /dev/null @@ -1,13 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - - - - - - - - - - - - \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/partials/searchResults.tmpl.partial b/documentation/docfx_project/templates/singulinkfx/partials/searchResults.tmpl.partial deleted file mode 100644 index 9f08c90..0000000 --- a/documentation/docfx_project/templates/singulinkfx/partials/searchResults.tmpl.partial +++ /dev/null @@ -1,9 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - - \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/partials/toc.tmpl.partial b/documentation/docfx_project/templates/singulinkfx/partials/toc.tmpl.partial deleted file mode 100644 index c660966..0000000 --- a/documentation/docfx_project/templates/singulinkfx/partials/toc.tmpl.partial +++ /dev/null @@ -1,5 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - -
    -
    -
    diff --git a/documentation/docfx_project/templates/singulinkfx/styles/config.css b/documentation/docfx_project/templates/singulinkfx/styles/config.css deleted file mode 100644 index cb39b51..0000000 --- a/documentation/docfx_project/templates/singulinkfx/styles/config.css +++ /dev/null @@ -1,124 +0,0 @@ -/* Theme Configuration Options */ - -:root -{ - /* General */ - - --base-font-size: 16px; - --smalldevice-base-font-size: 14px; /* Base font size for devices < 1024px */ - - --main-bg-color: #1f1f23; - --footer-bg-color: rgba(0,0,0,.4); - --separator-color: #42474f; - - --table-strip-bg-color: #151515; - --table-header-bg-color: black; - --table-header-color: hsla(0,0%,100%,.8); - --table-header-border-color: #040405; - - /* Text */ - - --appname-color: white; - - --h1-color: white; - --h2-color: #f2f2f2; - --h3-color: #e3e3e3; - --h4-color: #ffffff; - --h5-color: #e0e0e0; - - --text-color: #e1e1e1; - --link-color: #00b0f4; - --link-hover-color: #2ec4ff; - - /* Mobile Topbar */ - - --topbar-bg-color: #18191c; - - /* Button */ - - --button-color: #747f8d; - - /* Sidebar */ - - --sidebar-width: 400px; - --sidebar-bg-color: #292B30; - - --search-color: #bdbdbd; - --search-bg-color: #1b1e21; - --search-searchicon-color: #e3e3e3; - --search-border-color: black; - - --sidebar-item-color: white; - --sidebar-active-item-color: #00b0f4; - --sidebar-level1-item-bg-color: #222429; - --sidebar-level1-item-hover-bg-color: #1D1F22; - - --toc-filter-color: #bdbdbd; - --toc-filter-bg-color: #1b1e21; - --toc-filter-filtericon-color: #e3e3e3; - --toc-filter-clearicon-color: #e68585; - --toc-filter-border-color: black; - - /* Scrollbars */ - - --scrollbar-bg-color: transparent; - --scrollbar-thumb-bg-color: rgba(0,0,0,.4); - --scrollbar-thumb-border-color: transparent; - - /* Alerts and Blocks */ - - --alert-info-border-color: rgba(114,137,218,.5); - --alert-info-bg-color: rgba(114,137,218,.1); - - --alert-warning-border-color: rgba(250,166,26,.5); - --alert-warning-bg-color: rgba(250,166,26,.1); - - --alert-danger-border-color: rgba(240,71,71,.5); - --alert-danger-bg-color: rgba(240,71,71,.1); - - --alert-tip-border-color: rgba(255,255,255,.5); - --alert-tip-bg-color: rgba(255,255,255,.1); - - --blockquote-border-color: rgba(255,255,255,.5); - --blockquote-bg-color: rgba(255,255,255,.1); - - --breadcrumb-bg-color: #2f3136; - - /* Tabs */ - - --nav-tabs-border-width: 1px; - --nav-tabs-border-color: #495057; - --nav-tabs-border-radius: .375rem; - --nav-tabs-link-hover-border-color: #303336 #303336 transparent; - --nav-tabs-link-active-color: white; - --nav-tabs-link-active-bg: var(--main-bg-color); - --nav-tabs-link-active-border-color: var(--nav-tabs-border-color) var(--nav-tabs-border-color) var(--main-bg-color); - - /* Inline Code */ - - --ref-bg-color: black; - --ref-color: #89d4f1; - - /* Code Blocks */ - - --code-bg-color: #151515; - --code-color: #d6deeb; - --code-keyword-color: #569cd6; - --code-comment-color: #57a64a; - --code-macro-color: #beb7ff; - --code-string-color: #d69d85; - --code-string-escape-color: #ffd68f; - --code-field-color: #c8c8c8; - --code-function-color: #dcdcaa; - --code-control-color: #d8a0df; - --code-class-color: #4ec9b0; - --code-number-color: #b5cea8; - --code-params-color: #9a9a9a; - --code-breakpoint-color: #8c2f2f; -} - -/* Code Block Overrides */ - -pre, legend { - --scrollbar-thumb-bg-color: #333; -} \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/styles/discord.css b/documentation/docfx_project/templates/singulinkfx/styles/discord.css deleted file mode 100644 index fd53fc7..0000000 --- a/documentation/docfx_project/templates/singulinkfx/styles/discord.css +++ /dev/null @@ -1,680 +0,0 @@ -/* Discord Style */ - -::-webkit-scrollbar { - width: 10px; -} - -::-webkit-scrollbar-track { - background: var(--scrollbar-bg-color); -} - -::-webkit-scrollbar-thumb { - background: var(--scrollbar-thumb-bg-color); - border-color: var(--scrollbar-thumb-border-color); - border-radius: 5px; -} - -::marker { - unicode-bidi: isolate; - font-variant-numeric: tabular-nums; - text-transform: none; - text-indent: 0px !important; - text-align: start !important; - text-align-last: start !important; -} - -*, :after, :before -{ - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -html, body -{ - padding: 0; - margin: 0; - font: 15px/150% 'Roboto', sans-serif; - overflow: hidden; - color: var(--text-color); - background-color: var(--main-bg-color); - - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; -} - -img { - max-width: 100%; -} - -ul > li, ol > li { - display: list-item; -} - -h1,h2,h3,h4,h5 -{ - color: var(--link-active-color); - position: relative; -} - -h1, h2 -{ - margin-block-start: 2em; -} - -h3 -{ - margin-block-start: 1em; - font-weight: 300; - font-size: 1.5em; - color: var(--h3-color); - margin-block-start: 3em; -} - -h4 -{ - opacity: 1; - color: var(--h4-color); - font-size: large; - border-bottom: 2px solid var(--separator-color); - margin: 20px 0 0 0; -} - - -h5 { - margin-block-end: .8em; - margin-block-start: 1em; - font-size: .85em; - font-weight: 500; - color: var(--h5-color); -} - -h6 { - font-size: .75em; - margin: 0; -} - -p -{ - font-weight: 400; -} - -ul -{ - position: relative; -} - -ul, ol -{ - padding-inline-start: 3em; -} - -ul.level1 -{ - list-style-type: none; - padding-inline-start: 0; -} - -ul.level2, ul.level3 -{ - padding-inline-start: 1em; - list-style-type: none; - font-size: .9em; -} - -a -{ - color: var(--link-color); - text-decoration: none; - transition: color .25s; -} - -a:focus, a:hover -{ - color: var(--link-hover-color); - text-decoration: underline; -} - -a.anchorjs-link:hover { - text-decoration: none; -} - -a.active, a:active -{ - color: var(--link-active-color); -} - -.body-content -{ - display: flex; - flex-direction: row; - height: 100%; - overflow-x: hidden; - overflow-y: hidden; -} - -.page-title -{ - margin-block-start: 0; -} - -nav -{ - width: 300px; - transition: left .5s ease-out; - position: fixed; - left: -350px; - top: 40px; - bottom: 0; - background-color: var(--sidebar-bg-color); - overflow-y: auto; - - display: flex; - flex-direction: column; - - z-index: 1000; -} - -h1:first-child -{ - margin-block-start: 1.1em; - margin-top: 1.1em; -} - -.sidebar -{ - padding: 32px 17px 32px 32px; - flex: 1; -} - -.sidebar-item -{ - font-size: 1em; - font-weight: 400; - display: block; - padding: 4px 16px; - color: var(--sidebar-item-color); -} - -.sidebar-item.large, #navbar .sidebar-item -{ - padding: 8px 16px; -} - -a.sidebar-item:hover, a.sidebar-item:focus -{ - color: var(--link-active-color); - text-decoration: none; -} - -a.sidebar-item.active -{ - color: var(--link-active-color); -} - -ul.level1 > li > a.sidebar-item -{ - background-color: transparent; - border-radius: 4px; -} - -#toc ul.level1 > li > a.sidebar-item.active -{ - background-color: var(--link-active-bg-color); -} - -.sidebar-item-separator -{ - height: 2px; - width: 100%; - background-color: var(--separator-color); - margin: 2em 0; - opacity: .8; -} - -span.sidebar-item -{ - font-weight: 700; - text-transform: uppercase; - font-size: .8em; - color: var(--text-color); - margin-block-start: 1.25em; -} - -.main-panel -{ - background-color: var(--main-bg-color); - flex: 1; - overflow-y: auto; - padding: 20px 40px; -} - -.top-navbar -{ - display: flex; - flex-direction: row; - align-items: center; - padding: 0 40px; - height: 40px; - background-color: var(--topbar-bg-color); -} - -.burger-icon -{ - margin-right: 1em; - color: var(--button-color); -} - -.burger-icon:hover, .burger-icon:focus -{ - color: var(--link-active-color); -} - -.burger-icon.active, .burger-icon:active -{ - color: var(--link-active-color); -} - -.brand -{ - display: flex; - align-items: center; - justify-content: start; -} - -.logomark -{ - height: 28px; -} - -.brand-title -{ - padding: 0 .5em; - font-size: .9em; - color: var(--link-active-color); -} - -.footer -{ - background-color: var(--footer-bg-color); - padding: 20px; - margin: 0 20px 20px 20px; - border-radius: 8px; - color: var(--link-active-color); -} - -.footer > h4 -{ - margin-block-start: 0; -} - -.blackout -{ - display: block; - visibility: hidden; - position: absolute; - z-index: 100; - top: 40px; - bottom: 0; - left: 0; - right: 0; - background-color: var(--footer-bg-color); -} - -@keyframes showThat { - 0% { opacity: 0; visibility: hidden; } - 1% { opacity: 0; visibility: visible; } - 100% { opacity: 1; visibility: visible;} -} - -@keyframes hideThat { - 0% { opacity: 1; visibility: visible; } - 99% { opacity: 0; visibility: visible; } - 100% { opacity: 0; visibility: hidden;} -} - -.showThat -{ - animation: showThat .5s forwards; -} - -.hideThat -{ - animation: hideThat .5s forwards; -} - - - -@media (min-width: 1024px) -{ - nav - { - position: relative; - left: 0!important; - top: 0; - bottom: 0; - } - - .top-navbar - { - display: none; - } - - .blackout - { - display: none; - } -} - -/* Table */ - -.table-responsive -{ - overflow-x: auto; - margin-bottom: 64px; -} - -table -{ - background-color: var(--code-bg-color); - border-collapse: collapse; - width: 100%; - table-layout: auto; -} - -table.table-striped tbody tr:nth-child(2n) -{ - background-color: var(--table-strip-bg-color); -} - -table thead -{ - background: var(--table-header-bg-color); -} - -table th -{ - color: var(--table-header-color); - text-transform: uppercase; - font-size: 12px; - line-height: 15px; - border-bottom: 1px solid var(--table-header-border-color); - padding: 8px; -} - -.table-condensed th { - text-align: left; -} - -table td -{ - padding: 8px; - font-weight: 300; -} - -table td > p -{ - margin: 0; -} - -/* Alerts */ -.alert { - border-radius: 4px; - padding: 8px; - margin: 25px 0; -} - -.alert > h5 -{ - display: none; - margin: 0; -} - -.alert > p -{ - margin: 0; - font-weight: 300; - font-size: 13px; -} - -.alert.alert-info -{ - border: 2px solid var(--alert-info-border-color); - background: var(--alert-info-bg-color); -} - -.alert.alert-warning -{ - border: 2px solid var(--alert-warning-border-color); - background: var(--alert-warning-bg-color); -} - -.alert.alert-danger -{ - border: 2px solid var(--alert-danger-border-color); - background: var(--alert-danger-bg-color); -} - -.TIP.alert.alert-info -{ - border: 2px solid var(--alert-tip-border-color); - background: var(--alert-tip-bg-color); -} - -blockquote { - margin: 8px 0; - border-left: 4px solid var(--blockquote-border-color); - padding: 8px; - background: var(--blockquote-bg-color); - border-radius: 4px; -} - -blockquote > p { - margin: 0; - font-style: italic; - font-size: 13px; -} - - -/* Breadcrumb */ - -#breadcrumb -{ - padding: 8px 16px; - background: var(--breadcrumb-bg-color); - border-radius: 4px; - margin-bottom: 30px; -} - -#breadcrumb:empty -{ - display: none; -} - -ul.breadcrumb -{ - display: flex; - flex-direction: row; - margin: 0; -} - -ul.breadcrumb > li { - margin-right: 6px; -} - -ul.breadcrumb > li::before -{ - content: "/"; - margin-right: 5px; -} - -ul.breadcrumb > li:first-child::before -{ - content: ""; - margin: 0; -} - - -/* Code */ - -legend, pre -{ - display: block; - background-color: var(--code-bg-color); - padding: 16px; - border-radius: 4px; -} - -code -{ - background-color: var(--code-bg-color); - padding: 2px 4px; - border-radius: 4px; -} - -.hljs -{ - background: transparent; -} - -/* DocFX related */ - -.small { - font-size: .9em; -} - -.pull-right -{ - float: right; -} - -.hide -{ - display: none; -} - -@media (max-width: 1023.98px) -{ - .mobile-hide - { - display: none; - } -} - -li -{ - display: block; - position: relative; -} - -.expand-stub -{ - cursor: pointer; - position: absolute; - width: 20px; - height: 20px; - left: -10px; -} - -ul.level1 > li > .expand-stub -{ - display: none; -} - -.toc .nav > li > .expand-stub::before, .toc .nav > li.active > .expand-stub::before -{ - content: " "; - position: absolute; - transform: rotate(-90deg); - width: 10px; - height: 10px; - top: 5px; - left: 5px; - background-repeat: no-repeat; - background: url(down-arrow.svg); -} - -.toc .nav > li.active > .expand-stub::before, .toc .nav > li.in > .expand-stub::before, .toc .nav > li.in.active > .expand-stub::before, .toc .nav > li.filtered > .expand-stub::before -{ - transform: none; -} - -li > ul -{ - display: none; -} - -li.in > ul -{ - display: block; -} - -ul.level2 > li > a.sidebar-item, -ul.level3 > li > a.sidebar-item -{ - font-size: .95em; - padding: 0; - margin: 2px 16px; -} - -ul.level2 > li > a.sidebar-item -{ - color: var(--sidebar-item-2nd-color); -} - -ul.level3 > li > a.sidebar-item -{ - color: var(--sidebar-item-3rd-color); -} - -ul.level2 > li > a.sidebar-item:hover, -ul.level2 > li > a.sidebar-item:focus, -ul.level3 > li > a.sidebar-item:hover, -ul.level3 > li > a.sidebar-item:focus -{ - color: var(--link-active-color); - text-decoration: underline; -} - -ul.level2 > li > a.sidebar-item.active, -ul.level3 > li > a.sidebar-item.active -{ - color: var(--link-active-color); -} - -.inheritance .level0:before, -.inheritance .level1:before, -.inheritance .level2:before, -.inheritance .level3:before, -.inheritance .level4:before, -.inheritance .level5:before { - content: '↳'; - margin-right: 5px; -} - -.inheritance .level0 { - margin-left: 0em; -} - -.inheritance .level1 { - margin-left: 1em; -} - -.inheritance .level2 { - margin-left: 2em; -} - -.inheritance .level3 { - margin-left: 3em; -} - -.inheritance .level4 { - margin-left: 4em; -} - -.inheritance .level5 { - margin-left: 5em; -} \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/styles/down-arrow.svg b/documentation/docfx_project/templates/singulinkfx/styles/down-arrow.svg deleted file mode 100644 index e086126..0000000 --- a/documentation/docfx_project/templates/singulinkfx/styles/down-arrow.svg +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/documentation/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.js b/documentation/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.js deleted file mode 100644 index 332c01c..0000000 --- a/documentation/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.js +++ /dev/null @@ -1,317 +0,0 @@ -/*! - * jQuery pagination plugin v1.4.1 - * http://esimakin.github.io/twbs-pagination/ - * - * Copyright 2014-2016, Eugene Simakin - * Released under Apache 2.0 license - * http://apache.org/licenses/LICENSE-2.0.html - */ -(function ($, window, document, undefined) { - - 'use strict'; - - var old = $.fn.twbsPagination; - - // PROTOTYPE AND CONSTRUCTOR - - var TwbsPagination = function (element, options) { - this.$element = $(element); - this.options = $.extend({}, $.fn.twbsPagination.defaults, options); - - if (this.options.startPage < 1 || this.options.startPage > this.options.totalPages) { - throw new Error('Start page option is incorrect'); - } - - this.options.totalPages = parseInt(this.options.totalPages); - if (isNaN(this.options.totalPages)) { - throw new Error('Total pages option is not correct!'); - } - - this.options.visiblePages = parseInt(this.options.visiblePages); - if (isNaN(this.options.visiblePages)) { - throw new Error('Visible pages option is not correct!'); - } - - if (this.options.onPageClick instanceof Function) { - this.$element.first().on('page', this.options.onPageClick); - } - - // hide if only one page exists - if (this.options.hideOnlyOnePage && this.options.totalPages == 1) { - this.$element.trigger('page', 1); - return this; - } - - if (this.options.totalPages < this.options.visiblePages) { - this.options.visiblePages = this.options.totalPages; - } - - if (this.options.href) { - this.options.startPage = this.getPageFromQueryString(); - if (!this.options.startPage) { - this.options.startPage = 1; - } - } - - var tagName = (typeof this.$element.prop === 'function') ? - this.$element.prop('tagName') : this.$element.attr('tagName'); - - if (tagName === 'UL') { - this.$listContainer = this.$element; - } else { - this.$listContainer = $('
      '); - } - - this.$listContainer.addClass(this.options.paginationClass); - - if (tagName !== 'UL') { - this.$element.append(this.$listContainer); - } - - if (this.options.initiateStartPageClick) { - this.show(this.options.startPage); - } else { - this.render(this.getPages(this.options.startPage)); - this.setupEvents(); - } - - return this; - }; - - TwbsPagination.prototype = { - - constructor: TwbsPagination, - - destroy: function () { - this.$element.empty(); - this.$element.removeData('twbs-pagination'); - this.$element.off('page'); - - return this; - }, - - show: function (page) { - if (page < 1 || page > this.options.totalPages) { - throw new Error('Page is incorrect.'); - } - this.currentPage = page; - - this.render(this.getPages(page)); - this.setupEvents(); - - this.$element.trigger('page', page); - - return this; - }, - - buildListItems: function (pages) { - var listItems = []; - - if (this.options.first) { - listItems.push(this.buildItem('first', 1)); - } - - if (this.options.prev) { - var prev = pages.currentPage > 1 ? pages.currentPage - 1 : this.options.loop ? this.options.totalPages : 1; - listItems.push(this.buildItem('prev', prev)); - } - - for (var i = 0; i < pages.numeric.length; i++) { - listItems.push(this.buildItem('page', pages.numeric[i])); - } - - if (this.options.next) { - var next = pages.currentPage < this.options.totalPages ? pages.currentPage + 1 : this.options.loop ? 1 : this.options.totalPages; - listItems.push(this.buildItem('next', next)); - } - - if (this.options.last) { - listItems.push(this.buildItem('last', this.options.totalPages)); - } - - return listItems; - }, - - buildItem: function (type, page) { - var $itemContainer = $('
    • '), - $itemContent = $(''), - itemText = this.options[type] ? this.makeText(this.options[type], page) : page; - - $itemContainer.addClass(this.options[type + 'Class']); - $itemContainer.data('page', page); - $itemContainer.data('page-type', type); - $itemContainer.append($itemContent.attr('href', this.makeHref(page)).addClass(this.options.anchorClass).html(itemText)); - - return $itemContainer; - }, - - getPages: function (currentPage) { - var pages = []; - - var half = Math.floor(this.options.visiblePages / 2); - var start = currentPage - half + 1 - this.options.visiblePages % 2; - var end = currentPage + half; - - // handle boundary case - if (start <= 0) { - start = 1; - end = this.options.visiblePages; - } - if (end > this.options.totalPages) { - start = this.options.totalPages - this.options.visiblePages + 1; - end = this.options.totalPages; - } - - var itPage = start; - while (itPage <= end) { - pages.push(itPage); - itPage++; - } - - return {"currentPage": currentPage, "numeric": pages}; - }, - - render: function (pages) { - var _this = this; - this.$listContainer.children().remove(); - var items = this.buildListItems(pages); - jQuery.each(items, function(key, item){ - _this.$listContainer.append(item); - }); - - this.$listContainer.children().each(function () { - var $this = $(this), - pageType = $this.data('page-type'); - - switch (pageType) { - case 'page': - if ($this.data('page') === pages.currentPage) { - $this.addClass(_this.options.activeClass); - } - break; - case 'first': - $this.toggleClass(_this.options.disabledClass, pages.currentPage === 1); - break; - case 'last': - $this.toggleClass(_this.options.disabledClass, pages.currentPage === _this.options.totalPages); - break; - case 'prev': - $this.toggleClass(_this.options.disabledClass, !_this.options.loop && pages.currentPage === 1); - break; - case 'next': - $this.toggleClass(_this.options.disabledClass, - !_this.options.loop && pages.currentPage === _this.options.totalPages); - break; - default: - break; - } - - }); - }, - - setupEvents: function () { - var _this = this; - this.$listContainer.off('click').on('click', 'li', function (evt) { - var $this = $(this); - if ($this.hasClass(_this.options.disabledClass) || $this.hasClass(_this.options.activeClass)) { - return false; - } - // Prevent click event if href is not set. - !_this.options.href && evt.preventDefault(); - _this.show(parseInt($this.data('page'))); - }); - }, - - makeHref: function (page) { - return this.options.href ? this.generateQueryString(page) : "#"; - }, - - makeText: function (text, page) { - return text.replace(this.options.pageVariable, page) - .replace(this.options.totalPagesVariable, this.options.totalPages) - }, - getPageFromQueryString: function (searchStr) { - var search = this.getSearchString(searchStr), - regex = new RegExp(this.options.pageVariable + '(=([^&#]*)|&|#|$)'), - page = regex.exec(search); - if (!page || !page[2]) { - return null; - } - page = decodeURIComponent(page[2]); - page = parseInt(page); - if (isNaN(page)) { - return null; - } - return page; - }, - generateQueryString: function (pageNumber, searchStr) { - var search = this.getSearchString(searchStr), - regex = new RegExp(this.options.pageVariable + '=*[^&#]*'); - if (!search) return ''; - return '?' + search.replace(regex, this.options.pageVariable + '=' + pageNumber); - - }, - getSearchString: function (searchStr) { - var search = searchStr || window.location.search; - if (search === '') { - return null; - } - if (search.indexOf('?') === 0) search = search.substr(1); - return search; - } - - }; - - // PLUGIN DEFINITION - - $.fn.twbsPagination = function (option) { - var args = Array.prototype.slice.call(arguments, 1); - var methodReturn; - - var $this = $(this); - var data = $this.data('twbs-pagination'); - var options = typeof option === 'object' ? option : {}; - - if (!data) $this.data('twbs-pagination', (data = new TwbsPagination(this, options) )); - if (typeof option === 'string') methodReturn = data[ option ].apply(data, args); - - return ( methodReturn === undefined ) ? $this : methodReturn; - }; - - $.fn.twbsPagination.defaults = { - totalPages: 1, - startPage: 1, - visiblePages: 5, - initiateStartPageClick: true, - hideOnlyOnePage: false, - href: false, - pageVariable: '{{page}}', - totalPagesVariable: '{{total_pages}}', - page: null, - first: 'First', - prev: 'Previous', - next: 'Next', - last: 'Last', - loop: false, - onPageClick: null, - paginationClass: 'pagination', - nextClass: 'page-item next', - prevClass: 'page-item prev', - lastClass: 'page-item last', - firstClass: 'page-item first', - pageClass: 'page-item', - activeClass: 'active', - disabledClass: 'disabled', - anchorClass: 'page-link' - }; - - $.fn.twbsPagination.Constructor = TwbsPagination; - - $.fn.twbsPagination.noConflict = function () { - $.fn.twbsPagination = old; - return this; - }; - - $.fn.twbsPagination.version = "1.4.1"; - -})(window.jQuery, window, document); diff --git a/documentation/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.min.js b/documentation/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.min.js deleted file mode 100644 index a9e11c6..0000000 --- a/documentation/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.min.js +++ /dev/null @@ -1,8 +0,0 @@ -/*! - * jQuery pagination plugin v1.4.1 - * http://esimakin.github.io/twbs-pagination/ - * - * Copyright 2014-2016, Eugene Simakin - * Released under Apache 2.0 license - * http://apache.org/licenses/LICENSE-2.0.html - */ !function(t,s,i,e){"use strict";var a=t.fn.twbsPagination,o=function(s,i){if(this.$element=t(s),this.options=t.extend({},t.fn.twbsPagination.defaults,i),this.options.startPage<1||this.options.startPage>this.options.totalPages)throw Error("Start page option is incorrect");if(this.options.totalPages=parseInt(this.options.totalPages),isNaN(this.options.totalPages))throw Error("Total pages option is not correct!");if(this.options.visiblePages=parseInt(this.options.visiblePages),isNaN(this.options.visiblePages))throw Error("Visible pages option is not correct!");if(this.options.onPageClick instanceof Function&&this.$element.first().on("page",this.options.onPageClick),this.options.hideOnlyOnePage&&1==this.options.totalPages)return this.$element.trigger("page",1),this;this.options.totalPages"),this.$listContainer.addClass(this.options.paginationClass),"UL"!==e&&this.$element.append(this.$listContainer),this.options.initiateStartPageClick?this.show(this.options.startPage):(this.render(this.getPages(this.options.startPage)),this.setupEvents()),this};o.prototype={constructor:o,destroy:function(){return this.$element.empty(),this.$element.removeData("twbs-pagination"),this.$element.off("page"),this},show:function(t){if(t<1||t>this.options.totalPages)throw Error("Page is incorrect.");return this.currentPage=t,this.render(this.getPages(t)),this.setupEvents(),this.$element.trigger("page",t),this},buildListItems:function(t){var s=[];if(this.options.first&&s.push(this.buildItem("first",1)),this.options.prev){var i=t.currentPage>1?t.currentPage-1:this.options.loop?this.options.totalPages:1;s.push(this.buildItem("prev",i))}for(var e=0;e"),a=t(""),o=this.options[s]?this.makeText(this.options[s],i):i;return e.addClass(this.options[s+"Class"]),e.data("page",i),e.data("page-type",s),e.append(a.attr("href",this.makeHref(i)).addClass(this.options.anchorClass).html(o)),e},getPages:function(t){var s=[],i=Math.floor(this.options.visiblePages/2),e=t-i+1-this.options.visiblePages%2,a=t+i;e<=0&&(e=1,a=this.options.visiblePages),a>this.options.totalPages&&(e=this.options.totalPages-this.options.visiblePages+1,a=this.options.totalPages);for(var o=e;o<=a;)s.push(o),o++;return{currentPage:t,numeric:s}},render:function(s){var i=this;this.$listContainer.children().remove();var e=this.buildListItems(s);jQuery.each(e,function(t,s){i.$listContainer.append(s)}),this.$listContainer.children().each(function(){var e=t(this),a=e.data("page-type");switch(a){case"page":e.data("page")===s.currentPage&&e.addClass(i.options.activeClass);break;case"first":e.toggleClass(i.options.disabledClass,1===s.currentPage);break;case"last":e.toggleClass(i.options.disabledClass,s.currentPage===i.options.totalPages);break;case"prev":e.toggleClass(i.options.disabledClass,!i.options.loop&&1===s.currentPage);break;case"next":e.toggleClass(i.options.disabledClass,!i.options.loop&&s.currentPage===i.options.totalPages)}})},setupEvents:function(){var s=this;this.$listContainer.off("click").on("click","li",function(i){var e=t(this);if(e.hasClass(s.options.disabledClass)||e.hasClass(s.options.activeClass))return!1;s.options.href||i.preventDefault(),s.show(parseInt(e.data("page")))})},makeHref:function(t){return this.options.href?this.generateQueryString(t):"#"},makeText:function(t,s){return t.replace(this.options.pageVariable,s).replace(this.options.totalPagesVariable,this.options.totalPages)},getPageFromQueryString:function(t){var s=this.getSearchString(t),i=RegExp(this.options.pageVariable+"(=([^&#]*)|&|#|$)").exec(s);return i&&i[2]?(i=parseInt(i=decodeURIComponent(i[2])),isNaN(i))?null:i:null},generateQueryString:function(t,s){var i=this.getSearchString(s),e=RegExp(this.options.pageVariable+"=*[^&#]*");return i?"?"+i.replace(e,this.options.pageVariable+"="+t):""},getSearchString:function(t){var i=t||s.location.search;return""===i?null:(0===i.indexOf("?")&&(i=i.substr(1)),i)}},t.fn.twbsPagination=function(s){var i,e=Array.prototype.slice.call(arguments,1),a=t(this),n=a.data("twbs-pagination");return n||a.data("twbs-pagination",n=new o(this,"object"==typeof s?s:{})),"string"==typeof s&&(i=n[s].apply(n,e)),void 0===i?a:i},t.fn.twbsPagination.defaults={totalPages:1,startPage:1,visiblePages:5,initiateStartPageClick:!0,hideOnlyOnePage:!1,href:!1,pageVariable:"{{page}}",totalPagesVariable:"{{total_pages}}",page:null,first:"First",prev:"Previous",next:"Next",last:"Last",loop:!1,onPageClick:null,paginationClass:"pagination",nextClass:"page-item next",prevClass:"page-item prev",lastClass:"page-item last",firstClass:"page-item first",pageClass:"page-item",activeClass:"active",disabledClass:"disabled",anchorClass:"page-link"},t.fn.twbsPagination.Constructor=o,t.fn.twbsPagination.noConflict=function(){return t.fn.twbsPagination=a,this},t.fn.twbsPagination.version="1.4.1"}(window.jQuery,window,document); \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/styles/main.css b/documentation/docfx_project/templates/singulinkfx/styles/main.css deleted file mode 100644 index e69de29..0000000 diff --git a/documentation/docfx_project/templates/singulinkfx/styles/main.js b/documentation/docfx_project/templates/singulinkfx/styles/main.js deleted file mode 100644 index e69de29..0000000 diff --git a/documentation/docfx_project/templates/singulinkfx/styles/singulink.css b/documentation/docfx_project/templates/singulinkfx/styles/singulink.css deleted file mode 100644 index b478f84..0000000 --- a/documentation/docfx_project/templates/singulinkfx/styles/singulink.css +++ /dev/null @@ -1,572 +0,0 @@ -body { - font-size: var(--base-font-size); -} - -@media (max-width: 1024px) { - body { - font-size: var(--smalldevice-base-font-size); - } -} - -/* Headings */ - -h1, h2, h3, h4, h5 { - line-height: initial; -} - -h1, h1:first-child { - font-size: 2.25em; - letter-spacing: 0.5px; - color: var(--h1-color); - margin-block-start: 1em; - margin-block-end: -0.05em; -} - -.article h1 { - margin-block-end: -0.2em; -} - -h2 { - font-size: 2.1em; - color: var(--h2-color); -} - -.article h2 { - margin-block-start: 1.3em; - padding-bottom: 6px; - border-bottom: 1px solid var(--separator-color); -} - -h3 { - font-size: 1.95em; - font-weight: 500; - margin-block-start: 1.7em; -} - -.article h3 { - font-size: 1.85em; - font-weight: 500; - margin-block-start: 1.2em; - margin-block-end: 0.9em; -} - -h4 { - font-size: 1.8em; - font-weight: 400; - margin-block-start: 2em; - padding-bottom: 10px; -} - -.article h4 { - font-size: 1.5em; - font-weight: 300; - margin-block-start: 1em; - margin-block-end: 1em; - padding-bottom: 0; - border-bottom: none; -} - -h5 { - font-size: 1.1em; -} - -.article h5 { - font-size: 1.13em; - font-weight: 400; - text-decoration: underline; - margin-block-start: 1.5em; - margin-block-end: 1.0em; -} - -a.brand:hover -{ - text-decoration: none; -} - -a.brand .brand-title { - font-size: 1.4em; - font-weight: 500; - letter-spacing: 0.5px; - color: var(--appname-color); - margin-top: 1px; - padding: 0 0 0 0.4em; -} - -@media (min-width: 1024px) { - a.brand .brand-title { - font-size: 1.55em; - } -} - - -a.brand .logomark { - height: 35px; -} - -/* Top bar */ - -.top-navbar { - height: 60px; - padding: 0 0 0 10px; -} - -.burger-icon { - margin-right: 10px; -} - -/* Side Bar */ - -.sidebar { - padding: 25px 17px 32px 17px; -} - -.blackout { - top: 60px; -} - -@media (max-width: 1023.98px) { - .navbar-nav { - margin-top: 0; - } -} - -nav { - width: 94%; - max-width: var(--sidebar-width); - left: calc(var(--sidebar-width) * -1); -} - -@media (max-width: 1023.98px) { - nav { - top: 60px; - } -} - -nav ul { - list-style-type: none; -} - -nav .nav a, nav .nav a:hover { - text-decoration: none; - cursor: pointer; - display: block; -} - -nav a.sidebar-item { - padding: 4px 0 4px 10px; - cursor: pointer; -} - -nav a:focus, nav a.sidebar-item:hover, nav a.sidebar-item:focus { - text-decoration: underline; -} - -nav a, nav a:hover, nav a:focus { - color: var(--sidebar-item-color) !important; -} - -nav a.active, nav a.active:hover, nav a.active:focus { - color: var(--sidebar-active-item-color) !important; -} - -.sidebar-item-separator { - margin: 20px 0; -} - -#toc ul li a { - padding: 0 0 0 10px; -} - -.search { - background: var(--search-bg-color); - border: 1px solid var(--search-border-color); - border-radius: 5px; - position: relative; - margin-block-start: 25px; -} - -@media (max-width: 1023.98px) { - .search { - margin-block-start: 0; - margin-block-end: 15px; - } -} - -.search > input { - font-size: 0.95em; - color: var(--search-color); - border: 0; - background: none; - padding: 11px 30px 10px 37px; - width: 100%; -} - -.search > input:focus { - outline: 0; -} - -.search > .search-icon { - font-size: 1.2em; - color: var(--search-searchicon-color); - position: absolute; - top: 9px; - left: 9px; -} - -.toc-filter { - background: var(--toc-filter-bg-color); - border: 1px solid var(--toc-filter-border-color); - border-radius: 5px; - position: relative; -} - -.toc-filter > input { - font-size: 0.95em; - color: var(--toc-filter-color); - border: 0; - background: none; - padding: 11px 30px 10px 37px; - width: 100%; -} - -.toc-filter > input:focus { - outline: 0; -} - -.toc-filter > .filter-icon { - font-size: 1.2em; - color: var(--toc-filter-filtericon-color); - position: absolute; - top: 9px; - left: 9px; -} - -.toc-filter > .clear-icon { - color: var(--toc-filter-clearicon-color); - position: absolute; - top: 9px; - right: 9px; - cursor: pointer; -} - -.toc .nav > li > .expand-stub::before, .toc .nav > li.active > .expand-stub::before -{ - width: 8px; - height: 8px; - top: 6px; - left: 6px; -} - -#toc ul.level2 -{ - margin-bottom: 20px; -} - -#toc ul.level1 > li > a { - font-weight: 500; - margin-bottom: 10px; - padding: 5px 10px; -} - -#toc ul.level1 > li > a, #toc ul.level1 > li > a.active { - background-color: var(--sidebar-level1-item-bg-color) !important; - border-radius: 2px; -} - -#toc ul.level1 > li > a:hover, #toc ul.level1 > li > a.active:hover, -#toc ul.level1 > li > a:focus, #toc ul.level1 > li > a.active:focus { - background-color: var(--sidebar-level1-item-hover-bg-color) !important; - text-decoration: none; -} - -ul.level2 { - padding-inline-start: 0.7em; -} - -ul.level2 .expand-stub { - top: 1px; -} - -ul.level2 > li > a, ul.level2 > li > a.sidebar-item { - font-weight: 400; - color: var(--sidebar-item-color); - margin: 4px 0 4px; -} - -ul.level3 { - padding-inline-start: 1em; -} - -ul.level3 > li > a, ul.level3 > li > a.sidebar-item { - font-size: 1.05em; - color: var(--sidebar-item-color); - margin: 4px 0; -} - -ul.level4 { - padding-inline-start: 0; - margin-bottom: 12px; -} - -ul.level4 > li > a, ul.level4 > li > a.sidebar-item { - font-size: 1.05em; - color: var(--sidebar-item-color); - margin: 5px 0 5px 10px; -} - -/* Breadcrumbs */ - -.subnav.navbar { - margin: 0 -15px; -} - -#breadcrumb { - overflow: scroll; - margin-bottom: 0; -} - -#breadcrumb::-webkit-scrollbar { - display: none; -} - -#breadcrumb a { - white-space: nowrap; -} - -#breadcrumb wbr { - display: none; -} - -/* Search Results */ - -#search-results h1 { - margin-block-start: 0.5em; -} - -#search-results .item-title { - font-size: 1.3em; - margin-top: 1.5em; -} - -#search-results .item-href { - font-size: 0.85em; -} - -#search-results .item-brief { - margin-top: 0.7em; -} - -#search-results ul.pagination { - text-align: center; - padding: 10px 0 0 0; - margin-block-start: 40px; - border-top: 1px solid var(--separator-color); -} - -#search-results ul.pagination > li { - display: inline-block; - margin: 0 10px; -} - -#search-results ul.pagination > li.disabled a, #search-results ul.pagination > li.disabled a:hover { - color: var(--text-color); - cursor: txt; - text-decoration: none; -} - -/* Content */ - -.main-panel { - margin-bottom: 60px; - padding: 20px; -} - -@media (min-width: 1024px) { - .main-panel { - margin-bottom: 0; - padding: 20px 40px; - } -} - -.pull-right { - margin-top: 70px; - /* Fix unclickable links */ - position: relative; - z-index: 1; -} - -.divider { - margin-left: 4px; -} - -article ul li, article ol li { - margin-bottom: 10px; -} - -legend, pre { - padding: 6px; -} - -.hljs { - color: var(--code-color); -} - -.hljs::-webkit-scrollbar { - height: 6px; -} - -.hljs-keyword, .hljs-title, .hljs-built_in { - font-style: normal; -} - -p .xref, code { - background-color: var(--ref-bg-color); - color: var(--ref-color); - padding: 2px 3px; - font-family: monospace; - font-size: 0.95em; - border-radius: 6px; -} - -span.parametername { - font-family: monospace; -} - -.table { - width: auto; -} - -.table-responsive { - margin-bottom: 0; -} - -table th { - font-size: 14px; - padding: 9px 10px; -} - -table td p { - font-weight: 300; -} - -table td { - padding: 6px 10px; -} - -.footer { - text-align: center; - color: var(--text-color); - padding: 10px; -} - -.footer a:hover, .footer a:focus { - text-decoration: underline; -} - -.copyright-footer { - font-size: 0.85em; - font-weight: bold; - text-align: center; - margin-block-start: 30px; -} - -#contribution { - float: right; - margin-top: 1.1em; -} - - -/* Tabs */ - -.tabGroup { - margin-top: 1rem; - margin-bottom: 1rem; -} - -.tabGroup ul[role="tablist"] { - margin: 0; - padding: 0; - list-style: none; - border-bottom: var(--nav-tabs-border-width) solid var(--nav-tabs-border-color); -} - -.tabGroup ul[role="tablist"] > li { - list-style: none; - display: inline-block; - margin-bottom: 0; -} - -.tabGroup ul[role="tablist"] .dropdown-menu { - /* Make dropdown border overlap tab border */ - margin-top: calc(-1 * var(--nav-tabs-border-width)); - /* Remove the top rounded corners here since there is a hard edge above the menu */ - border-top-left-radius: 0; - border-top-right-radius: 0; -} - -.tabGroup a[role="tab"] { - display: block; - text-decoration: none; - padding: 0.5rem 1rem; - - margin-bottom: calc(-1 * var(--nav-tabs-border-width)); - border: var(--nav-tabs-border-width) solid transparent; - border-top-left-radius: var(--nav-tabs-border-radius); - border-top-right-radius: var(--nav-tabs-border-radius); -} - -.tabGroup a[role="tab"]:hover, .tabGroup a[role="tab"]:focus { - /* Prevents active .nav-link tab overlapping focus outline of previous/next .nav-link */ - isolation: isolate; - border-color: var(--nav-tabs-link-hover-border-color); -} - -.tabGroup a[role="tab"][aria-selected="true"] { - color: var(--nav-tabs-link-active-color); - background-color: var(--nav-tabs-link-active-bg); - border-color: var(--nav-tabs-link-active-border-color); -} - -.tabGroup a[role="tab"]:disabled { - color: var(--nav-link-disabled-color); - background-color: transparent; - border-color: transparent; -} - -.tabGroup section[role="tabpanel"] { - padding: 15px; - margin: 0; - overflow: hidden; - - border: var(--nav-tabs-border-width) solid var(--nav-tabs-border-color); - border-top: none; - border-bottom-left-radius: var(--nav-tabs-border-radius); - border-bottom-right-radius: var(--nav-tabs-border-radius); -} - -.tabGroup section[role="tabpanel"] > .codeHeader, -.tabGroup section[role="tabpanel"] > pre { - margin-left: -16px; - margin-right: -16px; -} - -.tabGroup section[role="tabpanel"] > :first-child { - margin-top: 0; -} - -.tabGroup section[role="tabpanel"] > pre:last-child { - display: block; - margin-bottom: -16px; -} - -.tabGroup > section { - margin: 0; - padding: 1rem; - border-top: 0; - border-top-left-radius: 0; - border-top-right-radius: 0; -} - -.mainContainer[dir='rtl'] main ul[role="tablist"] { - margin: 0; -} \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/styles/singulink.js b/documentation/docfx_project/templates/singulinkfx/styles/singulink.js deleted file mode 100644 index 40b0d0b..0000000 --- a/documentation/docfx_project/templates/singulinkfx/styles/singulink.js +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information. - -function toggleMenu() { - - var sidebar = document.getElementById("sidebar"); - var blackout = document.getElementById("blackout"); - - if (sidebar.style.left === "0px") - { - sidebar.style.left = "-" + sidebar.offsetWidth + "px"; - blackout.classList.remove("showThat"); - blackout.classList.add("hideThat"); - } - else - { - sidebar.style.left = "0px"; - blackout.classList.remove("hideThat"); - blackout.classList.add("showThat"); - } -} - -$(function() { - $('table').each(function(a, tbl) { - var currentTableRows = $(tbl).find('tbody tr').length; - $(tbl).find('th').each(function(i) { - var remove = 0; - var currentTable = $(this).parents('table'); - - var tds = currentTable.find('tr td:nth-child(' + (i + 1) + ')'); - tds.each(function(j) { if ($(this).text().trim() === '') remove++; }); - - if (remove == currentTableRows) { - $(this).hide(); - tds.hide(); - } - }); - }); - - function scrollToc() { - var activeTocItem = $('.sidebar .sidebar-item.active:last')[0] - - if (activeTocItem) { - activeTocItem.scrollIntoView({ block: "center" }); - } - else{ - setTimeout(scrollToc, 500); - } - } - - setTimeout(scrollToc, 500); -}); \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/styles/url.min.js b/documentation/docfx_project/templates/singulinkfx/styles/url.min.js deleted file mode 100644 index 8057e0a..0000000 --- a/documentation/docfx_project/templates/singulinkfx/styles/url.min.js +++ /dev/null @@ -1 +0,0 @@ -/*! url - v1.8.6 - 2013-11-22 */window.url=function(){function a(a){return!isNaN(parseFloat(a))&&isFinite(a)}return function(b,c){var d=c||window.location.toString();if(!b)return d;b=b.toString(),"//"===d.substring(0,2)?d="http:"+d:1===d.split("://").length&&(d="http://"+d),c=d.split("/");var e={auth:""},f=c[2].split("@");1===f.length?f=f[0].split(":"):(e.auth=f[0],f=f[1].split(":")),e.protocol=c[0],e.hostname=f[0],e.port=f[1]||("https"===e.protocol.split(":")[0].toLowerCase()?"443":"80"),e.pathname=(c.length>3?"/":"")+c.slice(3,c.length).join("/").split("?")[0].split("#")[0];var g=e.pathname;"/"===g.charAt(g.length-1)&&(g=g.substring(0,g.length-1));var h=e.hostname,i=h.split("."),j=g.split("/");if("hostname"===b)return h;if("domain"===b)return/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/.test(h)?h:i.slice(-2).join(".");if("sub"===b)return i.slice(0,i.length-2).join(".");if("port"===b)return e.port;if("protocol"===b)return e.protocol.split(":")[0];if("auth"===b)return e.auth;if("user"===b)return e.auth.split(":")[0];if("pass"===b)return e.auth.split(":")[1]||"";if("path"===b)return e.pathname;if("."===b.charAt(0)){if(b=b.substring(1),a(b))return b=parseInt(b,10),i[0>b?i.length+b:b-1]||""}else{if(a(b))return b=parseInt(b,10),j[0>b?j.length+b:b]||"";if("file"===b)return j.slice(-1)[0];if("filename"===b)return j.slice(-1)[0].split(".")[0];if("fileext"===b)return j.slice(-1)[0].split(".")[1]||"";if("?"===b.charAt(0)||"#"===b.charAt(0)){var k=d,l=null;if("?"===b.charAt(0)?k=(k.split("?")[1]||"").split("#")[0]:"#"===b.charAt(0)&&(k=k.split("#")[1]||""),!b.charAt(1))return k;b=b.substring(1),k=k.split("&");for(var m=0,n=k.length;n>m;m++)if(l=k[m].split("="),l[0]===b)return l[1]||"";return null}}return""}}(),"undefined"!=typeof jQuery&&jQuery.extend({url:function(a,b){return window.url(a,b)}}); \ No newline at end of file diff --git a/documentation/docfx_project/templates/singulinkfx/toc.html.tmpl b/documentation/docfx_project/templates/singulinkfx/toc.html.tmpl deleted file mode 100644 index 6549e62..0000000 --- a/documentation/docfx_project/templates/singulinkfx/toc.html.tmpl +++ /dev/null @@ -1,22 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - -
      -
      - {{^_disableSideFilter}} -
      -
      - - - -
      -
      - {{/_disableSideFilter}} -
      -
      - {{^leaf}} - {{>partials/li}} - {{/leaf}} -
      -
      -
      -
      \ No newline at end of file diff --git a/documentation/docfx_project/toc.yml b/documentation/docfx_project/toc.yml deleted file mode 100644 index 59f8010..0000000 --- a/documentation/docfx_project/toc.yml +++ /dev/null @@ -1,5 +0,0 @@ -- name: Articles - href: articles/ -- name: Api Documentation - href: api/ - homepage: api/index.md From 00cb59a031f32614361578ae9b4c8ceaf32cfcde Mon Sep 17 00:00:00 2001 From: purkayasta Date: Sun, 7 Jan 2024 20:23:47 +0600 Subject: [PATCH 03/17] upgraded to .net 8 and .net standard 2.1 --- .../Extensions/PagedListExtension.cs | 1 + .../Helpers/UtilityVerseException.cs | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 src/UtilityVerse/Helpers/UtilityVerseException.cs diff --git a/src/UtilityVerse/Extensions/PagedListExtension.cs b/src/UtilityVerse/Extensions/PagedListExtension.cs index d15d009..fa7ff19 100644 --- a/src/UtilityVerse/Extensions/PagedListExtension.cs +++ b/src/UtilityVerse/Extensions/PagedListExtension.cs @@ -4,6 +4,7 @@ // --------------------------------------------------------------- using UtilityVerse.Contracts; +using UtilityVerse.Helpers; namespace UtilityVerse.Extensions; diff --git a/src/UtilityVerse/Helpers/UtilityVerseException.cs b/src/UtilityVerse/Helpers/UtilityVerseException.cs new file mode 100644 index 0000000..407810e --- /dev/null +++ b/src/UtilityVerse/Helpers/UtilityVerseException.cs @@ -0,0 +1,20 @@ +using System; + +namespace UtilityVerse.Helpers; + +internal class UtilityVerseException +{ + private static readonly string _value = "value"; + internal static void ThrowIfNullOrEmpty(string data, string paramName = null) + { + if (string.IsNullOrEmpty(data) || string.IsNullOrWhiteSpace(data)) + throw new Exception($"{(paramName is not null ? paramName : _value)} is null or empty"); + } + + internal static void ThrowIfNull(object data, string paramName = null) + { + if (data is null) throw new Exception($"{(paramName is not null ? paramName : _value)} is null"); + } + + internal static void Throw(string message) { throw new Exception(message); } +} From ad943ac9984b22770df9000693a21c57fccb5c26 Mon Sep 17 00:00:00 2001 From: purkayasta Date: Sun, 7 Jan 2024 21:57:18 +0600 Subject: [PATCH 04/17] updated byte extension file --- .../Helpers/UtilityVerseException.cs | 20 ------------------- src/UtilityVerse/Helpers/Utils.cs | 2 +- 2 files changed, 1 insertion(+), 21 deletions(-) delete mode 100644 src/UtilityVerse/Helpers/UtilityVerseException.cs diff --git a/src/UtilityVerse/Helpers/UtilityVerseException.cs b/src/UtilityVerse/Helpers/UtilityVerseException.cs deleted file mode 100644 index 407810e..0000000 --- a/src/UtilityVerse/Helpers/UtilityVerseException.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; - -namespace UtilityVerse.Helpers; - -internal class UtilityVerseException -{ - private static readonly string _value = "value"; - internal static void ThrowIfNullOrEmpty(string data, string paramName = null) - { - if (string.IsNullOrEmpty(data) || string.IsNullOrWhiteSpace(data)) - throw new Exception($"{(paramName is not null ? paramName : _value)} is null or empty"); - } - - internal static void ThrowIfNull(object data, string paramName = null) - { - if (data is null) throw new Exception($"{(paramName is not null ? paramName : _value)} is null"); - } - - internal static void Throw(string message) { throw new Exception(message); } -} diff --git a/src/UtilityVerse/Helpers/Utils.cs b/src/UtilityVerse/Helpers/Utils.cs index fed81ab..221d943 100644 --- a/src/UtilityVerse/Helpers/Utils.cs +++ b/src/UtilityVerse/Helpers/Utils.cs @@ -1,4 +1,4 @@ -namespace UtilityVerse.Helpers; +namespace UtilityVerse.Helpers; internal static class Utils { From 54a97ef0fe2bafd9d7f3557428d7180072a62a66 Mon Sep 17 00:00:00 2001 From: purkayasta Date: Sun, 7 Jan 2024 21:57:45 +0600 Subject: [PATCH 05/17] updated Utility to follow UtilituResult type --- .../ByteExtensionTest.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 test/UtilityVerse.UnitTest/ByteExtensionTest.cs diff --git a/test/UtilityVerse.UnitTest/ByteExtensionTest.cs b/test/UtilityVerse.UnitTest/ByteExtensionTest.cs new file mode 100644 index 0000000..b3c0f4a --- /dev/null +++ b/test/UtilityVerse.UnitTest/ByteExtensionTest.cs @@ -0,0 +1,28 @@ +using System.Text.Json; +using System.Text.Json.Nodes; + +namespace UtilityVerse.UnitTest; + +public class ByteExtensionTest +{ + [Fact] + public void ToObject_ThrowsJsonException_WhenInvalidByteArrayProvided() + { + byte[] bytes = [1, 2, 3, 4, 5]; + var result = ByteExtension.ToObject(bytes); + Assert.Throws(() => result); + } + + [Fact] + public void ToObject_ReturnProperObject_WhenValidJsonByteArrayIsProvided() + { + JsonObject jObject = new() + { + { "key1", "value1" }, + { "key2", "value2" } + }; + var byteArr = JsonSerializer.SerializeToUtf8Bytes(jObject); + var result = ByteExtension.ToObject(byteArr); + Assert.Equal(result.Result, jObject.AsObject()); + } +} From ca821d2c5ea88845d47da06c0e8fffb9f198b0c5 Mon Sep 17 00:00:00 2001 From: purkayasta Date: Mon, 8 Jan 2024 01:44:15 +0600 Subject: [PATCH 06/17] removed exception and updated with a result type --- src/UtilityVerse/Extensions/PagedListExtension.cs | 1 - src/UtilityVerse/tasks.md | 4 ++++ test/UtilityVerse.UnitTest/ByteExtensionTest.cs | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 src/UtilityVerse/tasks.md diff --git a/src/UtilityVerse/Extensions/PagedListExtension.cs b/src/UtilityVerse/Extensions/PagedListExtension.cs index fa7ff19..d15d009 100644 --- a/src/UtilityVerse/Extensions/PagedListExtension.cs +++ b/src/UtilityVerse/Extensions/PagedListExtension.cs @@ -4,7 +4,6 @@ // --------------------------------------------------------------- using UtilityVerse.Contracts; -using UtilityVerse.Helpers; namespace UtilityVerse.Extensions; diff --git a/src/UtilityVerse/tasks.md b/src/UtilityVerse/tasks.md new file mode 100644 index 0000000..3aef837 --- /dev/null +++ b/src/UtilityVerse/tasks.md @@ -0,0 +1,4 @@ +# Tasks + +- [ ] Rewrite the unit test and test only the core logic part. +- [ ] Upload into the nuget. \ No newline at end of file diff --git a/test/UtilityVerse.UnitTest/ByteExtensionTest.cs b/test/UtilityVerse.UnitTest/ByteExtensionTest.cs index b3c0f4a..f725e55 100644 --- a/test/UtilityVerse.UnitTest/ByteExtensionTest.cs +++ b/test/UtilityVerse.UnitTest/ByteExtensionTest.cs @@ -22,7 +22,7 @@ public void ToObject_ReturnProperObject_WhenValidJsonByteArrayIsProvided() { "key2", "value2" } }; var byteArr = JsonSerializer.SerializeToUtf8Bytes(jObject); - var result = ByteExtension.ToObject(byteArr); + Shared.UtilityVerseResult result = ByteExtension.ToObject(byteArr); Assert.Equal(result.Result, jObject.AsObject()); } } From f24c73ccf9bb2d59d3422ef70a62277d55897884 Mon Sep 17 00:00:00 2001 From: purkayasta Date: Mon, 8 Jan 2024 01:46:31 +0600 Subject: [PATCH 07/17] added files into the solution --- src/UtilityVerse/tasks.md | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 src/UtilityVerse/tasks.md diff --git a/src/UtilityVerse/tasks.md b/src/UtilityVerse/tasks.md deleted file mode 100644 index 3aef837..0000000 --- a/src/UtilityVerse/tasks.md +++ /dev/null @@ -1,4 +0,0 @@ -# Tasks - -- [ ] Rewrite the unit test and test only the core logic part. -- [ ] Upload into the nuget. \ No newline at end of file From 297c996dba9266ec1af639b59eb86aac8a6125e3 Mon Sep 17 00:00:00 2001 From: purkayasta Date: Sat, 28 Jun 2025 02:28:55 +0600 Subject: [PATCH 08/17] Added Copy --- src/UtilityVerse.Copy/Extensions.cs | 9 +++++++++ test/UtilityVerse.Copy.Test/Program.cs | 2 +- test/UtilityVerse.UnitTest/Usings.cs | 3 ++- 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 src/UtilityVerse.Copy/Extensions.cs diff --git a/src/UtilityVerse.Copy/Extensions.cs b/src/UtilityVerse.Copy/Extensions.cs new file mode 100644 index 0000000..6f841cc --- /dev/null +++ b/src/UtilityVerse.Copy/Extensions.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; +using System.Linq; + +namespace UtilityVerse.Copy; + +public static class Extensions +{ + +} \ No newline at end of file diff --git a/test/UtilityVerse.Copy.Test/Program.cs b/test/UtilityVerse.Copy.Test/Program.cs index 54af99a..ac81b69 100644 --- a/test/UtilityVerse.Copy.Test/Program.cs +++ b/test/UtilityVerse.Copy.Test/Program.cs @@ -1,4 +1,4 @@ -using UtilityVerse.Copy.Test; +using UtilityVerse.Copy.Test; using UtilityVerse.Copy; Console.WriteLine("Starting...."); diff --git a/test/UtilityVerse.UnitTest/Usings.cs b/test/UtilityVerse.UnitTest/Usings.cs index 1b3f01b..c0c5637 100644 --- a/test/UtilityVerse.UnitTest/Usings.cs +++ b/test/UtilityVerse.UnitTest/Usings.cs @@ -1,3 +1,4 @@ global using Xunit; global using UtilityVerse; -global using UtilityVerse.Extensions; \ No newline at end of file +global using UtilityVerse.Extensions; +global using Xunit; \ No newline at end of file From a21c2c7c8d70a7422666130c3e13fa47d24a09e8 Mon Sep 17 00:00:00 2001 From: purkayasta Date: Sun, 29 Jun 2025 14:27:49 +0600 Subject: [PATCH 09/17] Added Inherited Property Support in the Copy --- src/UtilityVerse.Copy/Extensions.cs | 9 --------- src/UtilityVerse.Copy/Helper.cs | 7 +++++++ src/UtilityVerse.Copy/nuget.md | 1 + test/UtilityVerse.Copy.Test/HelloWorld.cs | 1 + 4 files changed, 9 insertions(+), 9 deletions(-) delete mode 100644 src/UtilityVerse.Copy/Extensions.cs diff --git a/src/UtilityVerse.Copy/Extensions.cs b/src/UtilityVerse.Copy/Extensions.cs deleted file mode 100644 index 6f841cc..0000000 --- a/src/UtilityVerse.Copy/Extensions.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace UtilityVerse.Copy; - -public static class Extensions -{ - -} \ No newline at end of file diff --git a/src/UtilityVerse.Copy/Helper.cs b/src/UtilityVerse.Copy/Helper.cs index 83ce90d..1ca2820 100644 --- a/src/UtilityVerse.Copy/Helper.cs +++ b/src/UtilityVerse.Copy/Helper.cs @@ -1,3 +1,9 @@ +/// +/// Author: Pritom Purkayasta +// Copyright (c) Pritom Purkayasta All rights reserved. +// FREE TO USE TO CONNECT THE WORLD +/// + using System.Collections.Generic; using System.Linq; using Microsoft.CodeAnalysis; @@ -57,6 +63,7 @@ internal static bool IsGenericCollection(string? originalDef, out string? kind) "System.Collections.Frozen.FrozenDictionary" => "Dictionary", "System.Collections.Concurrent.ConcurrentDictionary" => "Dictionary", + // Immutable "System.Collections.Immutable.ImmutableArray" => "List", "System.Collections.Immutable.ImmutableSortedSet" => "HashSet", "System.Collections.Immutable.ImmutableHashSet" => "HashSet", diff --git a/src/UtilityVerse.Copy/nuget.md b/src/UtilityVerse.Copy/nuget.md index e84e0bb..f3c0245 100644 --- a/src/UtilityVerse.Copy/nuget.md +++ b/src/UtilityVerse.Copy/nuget.md @@ -1,4 +1,5 @@ --- +--- # 📦 UtilityVerse.Copy — Source Generator for DeepCopy and ShallowCopy in C\# diff --git a/test/UtilityVerse.Copy.Test/HelloWorld.cs b/test/UtilityVerse.Copy.Test/HelloWorld.cs index 9caaae1..8f1f2f5 100644 --- a/test/UtilityVerse.Copy.Test/HelloWorld.cs +++ b/test/UtilityVerse.Copy.Test/HelloWorld.cs @@ -18,6 +18,7 @@ public HelloWorld Clone() } } + [DeepCopy] public partial class Address { From ca34da59af3245934220ed3e520e53d9e08231d0 Mon Sep 17 00:00:00 2001 From: purkayasta Date: Sun, 29 Jun 2025 16:08:22 +0600 Subject: [PATCH 10/17] Copy: Fixed generator issue in Copy --- src/UtilityVerse.Copy/UtilityVerse.Copy.sln | 24 +++++++++++++++++++++ src/UtilityVerse.Copy/nuget.md | 5 +++++ 2 files changed, 29 insertions(+) create mode 100644 src/UtilityVerse.Copy/UtilityVerse.Copy.sln diff --git a/src/UtilityVerse.Copy/UtilityVerse.Copy.sln b/src/UtilityVerse.Copy/UtilityVerse.Copy.sln new file mode 100644 index 0000000..5f63515 --- /dev/null +++ b/src/UtilityVerse.Copy/UtilityVerse.Copy.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UtilityVerse.Copy", "UtilityVerse.Copy.csproj", "{381427B0-86D7-C4BF-ADDE-F56BD66B638B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {381427B0-86D7-C4BF-ADDE-F56BD66B638B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {381427B0-86D7-C4BF-ADDE-F56BD66B638B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {381427B0-86D7-C4BF-ADDE-F56BD66B638B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {381427B0-86D7-C4BF-ADDE-F56BD66B638B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {54E540C6-9E0C-4569-B917-30077F35B028} + EndGlobalSection +EndGlobal diff --git a/src/UtilityVerse.Copy/nuget.md b/src/UtilityVerse.Copy/nuget.md index f3c0245..2ad1c6f 100644 --- a/src/UtilityVerse.Copy/nuget.md +++ b/src/UtilityVerse.Copy/nuget.md @@ -18,5 +18,10 @@ --- +## > Give it a star if you like the project. 👏 🌠 🌟 + + +--- + > Code is fully opensource and more details can be found here at: [Github](https://github.com/purkayasta/TheUtilityVerse/blob/development/src/UtilityVerse.Copy/README.md) \ No newline at end of file From f0d5fa262cb37bba01d09483b14d63d108bf8030 Mon Sep 17 00:00:00 2001 From: purkayasta Date: Wed, 16 Jul 2025 02:10:36 +0600 Subject: [PATCH 11/17] Added enum support and Analyzer warnings --- .../Analyzers/MissingPartialErrorAnalyzer.cs | 56 ++++++++ .../Analyzers/NestedTypeErrorAnalyzer.cs | 122 ++++++++++++++++++ test/UtilityVerse.Copy.Test/HelloWorld.cs | 1 - 3 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 src/UtilityVerse.Copy/Analyzers/MissingPartialErrorAnalyzer.cs create mode 100644 src/UtilityVerse.Copy/Analyzers/NestedTypeErrorAnalyzer.cs diff --git a/src/UtilityVerse.Copy/Analyzers/MissingPartialErrorAnalyzer.cs b/src/UtilityVerse.Copy/Analyzers/MissingPartialErrorAnalyzer.cs new file mode 100644 index 0000000..3161723 --- /dev/null +++ b/src/UtilityVerse.Copy/Analyzers/MissingPartialErrorAnalyzer.cs @@ -0,0 +1,56 @@ +using System.Collections.Immutable; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; + +namespace UtilityVerse.Copy.Analyzers; + +[DiagnosticAnalyzer(LanguageNames.CSharp)] +public class MissingPartialErrorAnalyzer : DiagnosticAnalyzer +{ + private static readonly DiagnosticDescriptor MissingPartialModifierRule = new( + id: "UV001", + title: "Type must be marked as partial for DeepCopy/ShallowCopy generation", + messageFormat: "Type '{0}' must be marked as 'partial' to support DeepCopy/ShallowCopy generation", + category: "UtilityVerse.Copy", + DiagnosticSeverity.Error, + isEnabledByDefault: true, + description: "UtilityVerse.Copy requires all target types to be marked with 'partial' so the DeepCopy() or ShallowCopy() method can be injected." + ); + + public override ImmutableArray SupportedDiagnostics => [MissingPartialModifierRule]; + + public override void Initialize(AnalysisContext context) + { + // Configure analysis for syntax trees + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); + context.EnableConcurrentExecution(); + + context.RegisterSyntaxNodeAction(AnalyzeTypeDeclaration, SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.RecordDeclaration, SyntaxKind.RecordStructDeclaration); + } + + private static void AnalyzeTypeDeclaration(SyntaxNodeAnalysisContext context) + { + var typeDecl = (TypeDeclarationSyntax)context.Node; + + // Skip if already marked partial + if (typeDecl.Modifiers.Any(m => m.IsKind(SyntaxKind.PartialKeyword))) + return; + + // Skip if not user-defined (e.g., external/metadata references) + var symbol = context.SemanticModel.GetDeclaredSymbol(typeDecl); + if (symbol is null || symbol.DeclaringSyntaxReferences.Length == 0) + return; + + // Optionally: check if it's used for DeepCopy somehow + // Example: skip types with [GeneratedCode] or [CompilerGenerated] + if (symbol.GetAttributes().Any(attr => + attr.AttributeClass?.ToDisplayString() is "System.CodeDom.Compiler.GeneratedCodeAttribute" or "System.Runtime.CompilerServices.CompilerGeneratedAttribute")) + return; + + var diagnostic = Diagnostic.Create(MissingPartialModifierRule, typeDecl.Identifier.GetLocation(), symbol.Name); + context.ReportDiagnostic(diagnostic); + } +} \ No newline at end of file diff --git a/src/UtilityVerse.Copy/Analyzers/NestedTypeErrorAnalyzer.cs b/src/UtilityVerse.Copy/Analyzers/NestedTypeErrorAnalyzer.cs new file mode 100644 index 0000000..1c3a407 --- /dev/null +++ b/src/UtilityVerse.Copy/Analyzers/NestedTypeErrorAnalyzer.cs @@ -0,0 +1,122 @@ +using System.Collections.Immutable; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; + +namespace UtilityVerse.Copy.Analyzers; + +[DiagnosticAnalyzer(LanguageNames.CSharp)] +public class NestedTypeErrorAnalyzer : DiagnosticAnalyzer +{ + private static readonly DiagnosticDescriptor DeepRule = new( + id: "UV002", + title: "Nested type missing DeepCopy attribute", + messageFormat: "Property '{0}' of type '{1}' requires nested type '{2}' to have DeepCopy attribute or implement IDeepCopy", + category: "UtilityVerse.Copy", + defaultSeverity: DiagnosticSeverity.Error, + isEnabledByDefault: true); + + private static readonly DiagnosticDescriptor ShallowRule = new DiagnosticDescriptor( + id: "UV003", + title: "Nested type missing ShallowCopy attribute", + messageFormat: "Property '{0}' of type '{1}' requires nested type '{2}' to have ShallowCopy attribute or implement IShallowCopy", + category: "UtilityVerse.Copy", + defaultSeverity: DiagnosticSeverity.Error, + isEnabledByDefault: true); + + public override ImmutableArray SupportedDiagnostics => + [DeepRule, ShallowRule]; + + public override void Initialize(AnalysisContext context) + { + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); + context.EnableConcurrentExecution(); + + context.RegisterSymbolAction(AnalyzeNamedType, SymbolKind.NamedType); + } + + private void AnalyzeNamedType(SymbolAnalysisContext context) + { + var namedType = (INamedTypeSymbol)context.Symbol; + + // Only analyze public partial types (assuming generator requires partial) + if (namedType.DeclaredAccessibility != Accessibility.Public) + return; + + if (!namedType.DeclaringSyntaxReferences.Any(syntaxRef => + syntaxRef.GetSyntax() is TypeDeclarationSyntax tds && + tds.Modifiers.Any(m => m.IsKind(SyntaxKind.PartialKeyword)))) + return; + + // Check if type opts into DeepCopy or ShallowCopy + bool hasDeepCopy = Helper.HasDeepCopyOptIn(namedType); + bool hasShallowCopy = Helper.HasShallowCopyOptIn(namedType); + + if (!hasDeepCopy && !hasShallowCopy) + return; // type itself not opted in - no need to check nested types + + // Get all properties including inherited + var properties = namedType.GetMembers().OfType().Where(p => !p.IsStatic); + + foreach (var prop in properties) + { + if (prop.Type is not INamedTypeSymbol propType) + { + continue; + } + // Skip primitives and enums + if (Helper.IsTrulyPrimitive(propType)) + continue; + + if (propType.IsGenericType) + { + foreach (var typeArg in propType.TypeArguments.OfType()) + { + if (Helper.IsTrulyPrimitive(typeArg)) + continue; + + if (hasDeepCopy && !Helper.HasDeepCopyOptIn(typeArg)) + { + var diagnostic = Diagnostic.Create( + DeepRule, + prop.Locations.FirstOrDefault(), + prop.Name, namedType.Name, typeArg.Name); + context.ReportDiagnostic(diagnostic); + } + + if (hasShallowCopy && !Helper.HasShallowCopyOptIn(typeArg)) + { + var diagnostic = Diagnostic.Create( + ShallowRule, + prop.Locations.FirstOrDefault(), + prop.Name, namedType.Name, typeArg.Name); + context.ReportDiagnostic(diagnostic); + } + } + } + else + { + // Handle non-generic nested types + if (hasDeepCopy && !Helper.HasDeepCopyOptIn(propType)) + { + var diagnostic = Diagnostic.Create( + DeepRule, + prop.Locations.FirstOrDefault(), + prop.Name, namedType.Name, propType.Name); + context.ReportDiagnostic(diagnostic); + } + + if (hasShallowCopy && !Helper.HasShallowCopyOptIn(propType)) + { + var diagnostic = Diagnostic.Create( + ShallowRule, + prop.Locations.FirstOrDefault(), + prop.Name, namedType.Name, propType.Name); + context.ReportDiagnostic(diagnostic); + } + } + } + } +} \ No newline at end of file diff --git a/test/UtilityVerse.Copy.Test/HelloWorld.cs b/test/UtilityVerse.Copy.Test/HelloWorld.cs index 8f1f2f5..9caaae1 100644 --- a/test/UtilityVerse.Copy.Test/HelloWorld.cs +++ b/test/UtilityVerse.Copy.Test/HelloWorld.cs @@ -18,7 +18,6 @@ public HelloWorld Clone() } } - [DeepCopy] public partial class Address { From 702fa106b6e5ac8411b919e8a773ed38a7e7712d Mon Sep 17 00:00:00 2001 From: purkayasta Date: Wed, 16 Jul 2025 02:35:52 +0600 Subject: [PATCH 12/17] Updated Yml file --- .../ByteExtensionTest.cs | 28 ------------------- 1 file changed, 28 deletions(-) delete mode 100644 test/UtilityVerse.UnitTest/ByteExtensionTest.cs diff --git a/test/UtilityVerse.UnitTest/ByteExtensionTest.cs b/test/UtilityVerse.UnitTest/ByteExtensionTest.cs deleted file mode 100644 index f725e55..0000000 --- a/test/UtilityVerse.UnitTest/ByteExtensionTest.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Nodes; - -namespace UtilityVerse.UnitTest; - -public class ByteExtensionTest -{ - [Fact] - public void ToObject_ThrowsJsonException_WhenInvalidByteArrayProvided() - { - byte[] bytes = [1, 2, 3, 4, 5]; - var result = ByteExtension.ToObject(bytes); - Assert.Throws(() => result); - } - - [Fact] - public void ToObject_ReturnProperObject_WhenValidJsonByteArrayIsProvided() - { - JsonObject jObject = new() - { - { "key1", "value1" }, - { "key2", "value2" } - }; - var byteArr = JsonSerializer.SerializeToUtf8Bytes(jObject); - Shared.UtilityVerseResult result = ByteExtension.ToObject(byteArr); - Assert.Equal(result.Result, jObject.AsObject()); - } -} From cac5545d8aa6b6f30bfd24854d2aecbea8965627 Mon Sep 17 00:00:00 2001 From: purkayasta Date: Sat, 19 Jul 2025 13:21:27 +0600 Subject: [PATCH 13/17] COPY: Updated The validation error analyzer --- .../Analyzers/MissingPartialErrorAnalyzer.cs | 56 -------- .../Analyzers/NestedTypeErrorAnalyzer.cs | 122 ------------------ src/UtilityVerse.Copy/Helper.cs | 7 - src/UtilityVerse.Copy/UtilityVerse.Copy.sln | 24 ---- 4 files changed, 209 deletions(-) delete mode 100644 src/UtilityVerse.Copy/Analyzers/MissingPartialErrorAnalyzer.cs delete mode 100644 src/UtilityVerse.Copy/Analyzers/NestedTypeErrorAnalyzer.cs delete mode 100644 src/UtilityVerse.Copy/UtilityVerse.Copy.sln diff --git a/src/UtilityVerse.Copy/Analyzers/MissingPartialErrorAnalyzer.cs b/src/UtilityVerse.Copy/Analyzers/MissingPartialErrorAnalyzer.cs deleted file mode 100644 index 3161723..0000000 --- a/src/UtilityVerse.Copy/Analyzers/MissingPartialErrorAnalyzer.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Collections.Immutable; -using System.Linq; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Diagnostics; - -namespace UtilityVerse.Copy.Analyzers; - -[DiagnosticAnalyzer(LanguageNames.CSharp)] -public class MissingPartialErrorAnalyzer : DiagnosticAnalyzer -{ - private static readonly DiagnosticDescriptor MissingPartialModifierRule = new( - id: "UV001", - title: "Type must be marked as partial for DeepCopy/ShallowCopy generation", - messageFormat: "Type '{0}' must be marked as 'partial' to support DeepCopy/ShallowCopy generation", - category: "UtilityVerse.Copy", - DiagnosticSeverity.Error, - isEnabledByDefault: true, - description: "UtilityVerse.Copy requires all target types to be marked with 'partial' so the DeepCopy() or ShallowCopy() method can be injected." - ); - - public override ImmutableArray SupportedDiagnostics => [MissingPartialModifierRule]; - - public override void Initialize(AnalysisContext context) - { - // Configure analysis for syntax trees - context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); - context.EnableConcurrentExecution(); - - context.RegisterSyntaxNodeAction(AnalyzeTypeDeclaration, SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.RecordDeclaration, SyntaxKind.RecordStructDeclaration); - } - - private static void AnalyzeTypeDeclaration(SyntaxNodeAnalysisContext context) - { - var typeDecl = (TypeDeclarationSyntax)context.Node; - - // Skip if already marked partial - if (typeDecl.Modifiers.Any(m => m.IsKind(SyntaxKind.PartialKeyword))) - return; - - // Skip if not user-defined (e.g., external/metadata references) - var symbol = context.SemanticModel.GetDeclaredSymbol(typeDecl); - if (symbol is null || symbol.DeclaringSyntaxReferences.Length == 0) - return; - - // Optionally: check if it's used for DeepCopy somehow - // Example: skip types with [GeneratedCode] or [CompilerGenerated] - if (symbol.GetAttributes().Any(attr => - attr.AttributeClass?.ToDisplayString() is "System.CodeDom.Compiler.GeneratedCodeAttribute" or "System.Runtime.CompilerServices.CompilerGeneratedAttribute")) - return; - - var diagnostic = Diagnostic.Create(MissingPartialModifierRule, typeDecl.Identifier.GetLocation(), symbol.Name); - context.ReportDiagnostic(diagnostic); - } -} \ No newline at end of file diff --git a/src/UtilityVerse.Copy/Analyzers/NestedTypeErrorAnalyzer.cs b/src/UtilityVerse.Copy/Analyzers/NestedTypeErrorAnalyzer.cs deleted file mode 100644 index 1c3a407..0000000 --- a/src/UtilityVerse.Copy/Analyzers/NestedTypeErrorAnalyzer.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System.Collections.Immutable; -using System.Linq; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Diagnostics; - -namespace UtilityVerse.Copy.Analyzers; - -[DiagnosticAnalyzer(LanguageNames.CSharp)] -public class NestedTypeErrorAnalyzer : DiagnosticAnalyzer -{ - private static readonly DiagnosticDescriptor DeepRule = new( - id: "UV002", - title: "Nested type missing DeepCopy attribute", - messageFormat: "Property '{0}' of type '{1}' requires nested type '{2}' to have DeepCopy attribute or implement IDeepCopy", - category: "UtilityVerse.Copy", - defaultSeverity: DiagnosticSeverity.Error, - isEnabledByDefault: true); - - private static readonly DiagnosticDescriptor ShallowRule = new DiagnosticDescriptor( - id: "UV003", - title: "Nested type missing ShallowCopy attribute", - messageFormat: "Property '{0}' of type '{1}' requires nested type '{2}' to have ShallowCopy attribute or implement IShallowCopy", - category: "UtilityVerse.Copy", - defaultSeverity: DiagnosticSeverity.Error, - isEnabledByDefault: true); - - public override ImmutableArray SupportedDiagnostics => - [DeepRule, ShallowRule]; - - public override void Initialize(AnalysisContext context) - { - context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); - context.EnableConcurrentExecution(); - - context.RegisterSymbolAction(AnalyzeNamedType, SymbolKind.NamedType); - } - - private void AnalyzeNamedType(SymbolAnalysisContext context) - { - var namedType = (INamedTypeSymbol)context.Symbol; - - // Only analyze public partial types (assuming generator requires partial) - if (namedType.DeclaredAccessibility != Accessibility.Public) - return; - - if (!namedType.DeclaringSyntaxReferences.Any(syntaxRef => - syntaxRef.GetSyntax() is TypeDeclarationSyntax tds && - tds.Modifiers.Any(m => m.IsKind(SyntaxKind.PartialKeyword)))) - return; - - // Check if type opts into DeepCopy or ShallowCopy - bool hasDeepCopy = Helper.HasDeepCopyOptIn(namedType); - bool hasShallowCopy = Helper.HasShallowCopyOptIn(namedType); - - if (!hasDeepCopy && !hasShallowCopy) - return; // type itself not opted in - no need to check nested types - - // Get all properties including inherited - var properties = namedType.GetMembers().OfType().Where(p => !p.IsStatic); - - foreach (var prop in properties) - { - if (prop.Type is not INamedTypeSymbol propType) - { - continue; - } - // Skip primitives and enums - if (Helper.IsTrulyPrimitive(propType)) - continue; - - if (propType.IsGenericType) - { - foreach (var typeArg in propType.TypeArguments.OfType()) - { - if (Helper.IsTrulyPrimitive(typeArg)) - continue; - - if (hasDeepCopy && !Helper.HasDeepCopyOptIn(typeArg)) - { - var diagnostic = Diagnostic.Create( - DeepRule, - prop.Locations.FirstOrDefault(), - prop.Name, namedType.Name, typeArg.Name); - context.ReportDiagnostic(diagnostic); - } - - if (hasShallowCopy && !Helper.HasShallowCopyOptIn(typeArg)) - { - var diagnostic = Diagnostic.Create( - ShallowRule, - prop.Locations.FirstOrDefault(), - prop.Name, namedType.Name, typeArg.Name); - context.ReportDiagnostic(diagnostic); - } - } - } - else - { - // Handle non-generic nested types - if (hasDeepCopy && !Helper.HasDeepCopyOptIn(propType)) - { - var diagnostic = Diagnostic.Create( - DeepRule, - prop.Locations.FirstOrDefault(), - prop.Name, namedType.Name, propType.Name); - context.ReportDiagnostic(diagnostic); - } - - if (hasShallowCopy && !Helper.HasShallowCopyOptIn(propType)) - { - var diagnostic = Diagnostic.Create( - ShallowRule, - prop.Locations.FirstOrDefault(), - prop.Name, namedType.Name, propType.Name); - context.ReportDiagnostic(diagnostic); - } - } - } - } -} \ No newline at end of file diff --git a/src/UtilityVerse.Copy/Helper.cs b/src/UtilityVerse.Copy/Helper.cs index 1ca2820..83ce90d 100644 --- a/src/UtilityVerse.Copy/Helper.cs +++ b/src/UtilityVerse.Copy/Helper.cs @@ -1,9 +1,3 @@ -/// -/// Author: Pritom Purkayasta -// Copyright (c) Pritom Purkayasta All rights reserved. -// FREE TO USE TO CONNECT THE WORLD -/// - using System.Collections.Generic; using System.Linq; using Microsoft.CodeAnalysis; @@ -63,7 +57,6 @@ internal static bool IsGenericCollection(string? originalDef, out string? kind) "System.Collections.Frozen.FrozenDictionary" => "Dictionary", "System.Collections.Concurrent.ConcurrentDictionary" => "Dictionary", - // Immutable "System.Collections.Immutable.ImmutableArray" => "List", "System.Collections.Immutable.ImmutableSortedSet" => "HashSet", "System.Collections.Immutable.ImmutableHashSet" => "HashSet", diff --git a/src/UtilityVerse.Copy/UtilityVerse.Copy.sln b/src/UtilityVerse.Copy/UtilityVerse.Copy.sln deleted file mode 100644 index 5f63515..0000000 --- a/src/UtilityVerse.Copy/UtilityVerse.Copy.sln +++ /dev/null @@ -1,24 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.5.2.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UtilityVerse.Copy", "UtilityVerse.Copy.csproj", "{381427B0-86D7-C4BF-ADDE-F56BD66B638B}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {381427B0-86D7-C4BF-ADDE-F56BD66B638B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {381427B0-86D7-C4BF-ADDE-F56BD66B638B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {381427B0-86D7-C4BF-ADDE-F56BD66B638B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {381427B0-86D7-C4BF-ADDE-F56BD66B638B}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {54E540C6-9E0C-4569-B917-30077F35B028} - EndGlobalSection -EndGlobal From 72223100126f87ba7eeb8c62e62b24f6d971af16 Mon Sep 17 00:00:00 2001 From: purkayasta Date: Sat, 19 Jul 2025 13:26:32 +0600 Subject: [PATCH 14/17] COPY: Updated nuget.md file --- src/UtilityVerse.Copy/nuget.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/UtilityVerse.Copy/nuget.md b/src/UtilityVerse.Copy/nuget.md index 2ad1c6f..f3c0245 100644 --- a/src/UtilityVerse.Copy/nuget.md +++ b/src/UtilityVerse.Copy/nuget.md @@ -18,10 +18,5 @@ --- -## > Give it a star if you like the project. 👏 🌠 🌟 - - ---- - > Code is fully opensource and more details can be found here at: [Github](https://github.com/purkayasta/TheUtilityVerse/blob/development/src/UtilityVerse.Copy/README.md) \ No newline at end of file From 24257ec3fd00b51e2d5dc6b20886b1358b070f0e Mon Sep 17 00:00:00 2001 From: purkayasta Date: Sun, 20 Jul 2025 00:19:43 +0600 Subject: [PATCH 15/17] Copy: Fixed analyzer to support inbuilt method by default --- .../Analyzers/ValidationAnalyzer.cs | 242 ++++++------- .../Generators/DeepCopyGenerator.cs | 338 +++++++++--------- .../Generators/ShallowCopyGenerator.cs | 217 +++++------ src/UtilityVerse.Copy/Helper.cs | 246 +++++++------ test/UtilityVerse.Copy.Test/HelloWorld.cs | 66 ++-- test/UtilityVerse.Copy.Test/Program.cs | 11 + 6 files changed, 595 insertions(+), 525 deletions(-) diff --git a/src/UtilityVerse.Copy/Analyzers/ValidationAnalyzer.cs b/src/UtilityVerse.Copy/Analyzers/ValidationAnalyzer.cs index 6207a06..b1cb920 100644 --- a/src/UtilityVerse.Copy/Analyzers/ValidationAnalyzer.cs +++ b/src/UtilityVerse.Copy/Analyzers/ValidationAnalyzer.cs @@ -9,125 +9,125 @@ namespace UtilityVerse.Copy.Analyzers; [DiagnosticAnalyzer(LanguageNames.CSharp)] public class ValidationAnalyzer : DiagnosticAnalyzer { - public override ImmutableArray SupportedDiagnostics => - [Rules.MissingPartialRule, Rules.DeepRule, Rules.ShallowRule]; - - public override void Initialize(AnalysisContext context) - { - context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); - context.EnableConcurrentExecution(); - - context.RegisterCompilationStartAction(compilationContext => - { - compilationContext.RegisterSymbolAction(AnalyzeNamedType, SymbolKind.NamedType); - }); - } - - private static void AnalyzeNamedType(SymbolAnalysisContext context) - { - if (context.Symbol is not INamedTypeSymbol namedType) - return; - - if (namedType.TypeKind is not (TypeKind.Class or TypeKind.Struct)) - return; - - if (namedType.GetAttributes().Any(attr => - attr.AttributeClass?.ToDisplayString() is - "System.CodeDom.Compiler.GeneratedCodeAttribute" or - "System.Runtime.CompilerServices.CompilerGeneratedAttribute")) - return; - - var syntaxRef = namedType.DeclaringSyntaxReferences.FirstOrDefault(); - if (syntaxRef?.GetSyntax() is not TypeDeclarationSyntax typeSyntax) - return; - - var hasDeepCopy = Helper.HasDeepCopyOptIn(namedType); - var hasShallowCopy = Helper.HasShallowCopyOptIn(namedType); - - if ((hasDeepCopy || hasShallowCopy) && !Helper.IsPartial(namedType)) - { - var diagnostic = Diagnostic.Create(Rules.MissingPartialRule, typeSyntax.Identifier.GetLocation(), namedType.Name); - context.ReportDiagnostic(diagnostic); - } - - if (!hasDeepCopy && !hasShallowCopy) - return; - - foreach (var prop in Helper.GetAllProperties(namedType).Where(p => !p.IsStatic)) - { - AnalyzeTypeRecursive( - context, - prop.Type, - prop.Locations.FirstOrDefault() ?? typeSyntax.Identifier.GetLocation(), - prop.Name, - namedType, - hasDeepCopy, - hasShallowCopy - ); - } - } - - private static void AnalyzeTypeRecursive( - SymbolAnalysisContext context, - ITypeSymbol type, - Location diagnosticLocation, - string propertyName, - INamedTypeSymbol parentType, - bool requireDeepCopy, - bool requireShallowCopy) - { - if (type is not INamedTypeSymbol namedType) - return; - - var unwrapped = UnwrapNullable(namedType); - - if (Helper.IsTrulyPrimitive(unwrapped)) - return; - - if (Helper.IsGenericCollection(unwrapped.OriginalDefinition.ToDisplayString(), out _)) - { - foreach (var typeArg in unwrapped.TypeArguments.OfType()) - { - AnalyzeTypeRecursive(context, typeArg, diagnosticLocation, propertyName, parentType, requireDeepCopy, requireShallowCopy); - } - return; - } - - if (requireDeepCopy && !Helper.HasDeepCopyOptIn(unwrapped)) - { - var diag = Diagnostic.Create(Rules.DeepRule, diagnosticLocation, - propertyName, parentType.Name, unwrapped.Name); - context.ReportDiagnostic(diag); - } - - if (requireShallowCopy && !Helper.HasShallowCopyOptIn(unwrapped)) - { - var diag = Diagnostic.Create(Rules.ShallowRule, diagnosticLocation, - propertyName, parentType.Name, unwrapped.Name); - context.ReportDiagnostic(diag); - } - } - - private static INamedTypeSymbol UnwrapNullable(INamedTypeSymbol type) - { - return type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T && - type.TypeArguments.FirstOrDefault() is INamedTypeSymbol underlying - ? underlying - : type; - } - - private static bool IsInsideCopyEnabledPartialParent(INamedTypeSymbol? symbol) - { - while (symbol is not null) - { - if (!Helper.IsPartial(symbol)) - return false; - - if (Helper.HasDeepCopyOptIn(symbol) || Helper.HasShallowCopyOptIn(symbol)) - return true; - - symbol = symbol.ContainingType; - } - return false; - } + public override ImmutableArray SupportedDiagnostics => + [Rules.MissingPartialRule, Rules.DeepRule, Rules.ShallowRule]; + + public override void Initialize(AnalysisContext context) + { + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); + context.EnableConcurrentExecution(); + + context.RegisterCompilationStartAction(compilationContext => + { + compilationContext.RegisterSymbolAction(AnalyzeNamedType, SymbolKind.NamedType); + }); + } + + private static void AnalyzeNamedType(SymbolAnalysisContext context) + { + if (context.Symbol is not INamedTypeSymbol namedType) + return; + + if (namedType.TypeKind is not (TypeKind.Class or TypeKind.Struct)) + return; + + if (namedType.GetAttributes().Any(attr => + attr.AttributeClass?.ToDisplayString() is + "System.CodeDom.Compiler.GeneratedCodeAttribute" or + "System.Runtime.CompilerServices.CompilerGeneratedAttribute")) + return; + + var syntaxRef = namedType.DeclaringSyntaxReferences.FirstOrDefault(); + if (syntaxRef?.GetSyntax() is not TypeDeclarationSyntax typeSyntax) + return; + + var hasDeepCopy = Helper.HasDeepCopyOptIn(namedType); + var hasShallowCopy = Helper.HasShallowCopyOptIn(namedType); + + if ((hasDeepCopy || hasShallowCopy) && !Helper.IsPartial(namedType)) + { + var diagnostic = Diagnostic.Create(Rules.MissingPartialRule, typeSyntax.Identifier.GetLocation(), namedType.Name); + context.ReportDiagnostic(diagnostic); + } + + if (!hasDeepCopy && !hasShallowCopy) + return; + + foreach (var prop in Helper.GetAllProperties(namedType).Where(p => !p.IsStatic)) + { + AnalyzeTypeRecursive( + context, + prop.Type, + prop.Locations.FirstOrDefault() ?? typeSyntax.Identifier.GetLocation(), + prop.Name, + namedType, + hasDeepCopy, + hasShallowCopy + ); + } + } + + private static void AnalyzeTypeRecursive( + SymbolAnalysisContext context, + ITypeSymbol type, + Location diagnosticLocation, + string propertyName, + INamedTypeSymbol parentType, + bool requireDeepCopy, + bool requireShallowCopy) + { + if (type is not INamedTypeSymbol namedType) + return; + + var unwrapped = Helper.UnwrapNullable(namedType); + + if (Helper.IsTrulyPrimitive(unwrapped) || Helper.IsBuiltinType(unwrapped)) + return; + + if (Helper.IsGenericCollection(unwrapped.OriginalDefinition.ToDisplayString(), out _)) + { + foreach (var typeArg in unwrapped.TypeArguments.OfType()) + { + AnalyzeTypeRecursive(context, typeArg, diagnosticLocation, propertyName, parentType, requireDeepCopy, requireShallowCopy); + } + return; + } + + if (requireDeepCopy && !Helper.HasDeepCopyOptIn(unwrapped)) + { + var diag = Diagnostic.Create(Rules.DeepRule, diagnosticLocation, + propertyName, parentType.Name, unwrapped.Name); + context.ReportDiagnostic(diag); + } + + if (requireShallowCopy && !Helper.HasShallowCopyOptIn(unwrapped)) + { + var diag = Diagnostic.Create(Rules.ShallowRule, diagnosticLocation, + propertyName, parentType.Name, unwrapped.Name); + context.ReportDiagnostic(diag); + } + } + + //private static INamedTypeSymbol UnwrapNullable(INamedTypeSymbol type) + //{ + // return type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T && + // type.TypeArguments.FirstOrDefault() is INamedTypeSymbol underlying + // ? underlying + // : type; + //} + + private static bool IsInsideCopyEnabledPartialParent(INamedTypeSymbol? symbol) + { + while (symbol is not null) + { + if (!Helper.IsPartial(symbol)) + return false; + + if (Helper.HasDeepCopyOptIn(symbol) || Helper.HasShallowCopyOptIn(symbol)) + return true; + + symbol = symbol.ContainingType; + } + return false; + } } diff --git a/src/UtilityVerse.Copy/Generators/DeepCopyGenerator.cs b/src/UtilityVerse.Copy/Generators/DeepCopyGenerator.cs index 0677cc8..fd5b564 100644 --- a/src/UtilityVerse.Copy/Generators/DeepCopyGenerator.cs +++ b/src/UtilityVerse.Copy/Generators/DeepCopyGenerator.cs @@ -12,30 +12,30 @@ namespace UtilityVerse.Copy.Generators; internal static class DeepCopyGenerator { - internal static string? Generate(INamedTypeSymbol typeSymbol) - { - if (typeSymbol.IsAbstract) return string.Empty; - if (!Helper.IsPartial(typeSymbol)) return string.Empty; + internal static string? Generate(INamedTypeSymbol typeSymbol) + { + if (typeSymbol.IsAbstract) return string.Empty; + if (!Helper.IsPartial(typeSymbol)) return string.Empty; - var isGlobalNamespace = typeSymbol.ContainingNamespace.IsGlobalNamespace; - var namespaceName = isGlobalNamespace ? null : typeSymbol.ContainingNamespace.ToDisplayString(); - var typeName = typeSymbol.Name; + var isGlobalNamespace = typeSymbol.ContainingNamespace.IsGlobalNamespace; + var namespaceName = isGlobalNamespace ? null : typeSymbol.ContainingNamespace.ToDisplayString(); + var typeName = typeSymbol.Name; - var typeKind = typeSymbol switch - { - { TypeKind: TypeKind.Class, IsRecord: true } => "record", - { TypeKind: TypeKind.Struct, IsRecord: true } => "record struct", - { TypeKind: TypeKind.Class } => "class", - { TypeKind: TypeKind.Struct } => "struct", - _ => null - }; + var typeKind = typeSymbol switch + { + { TypeKind: TypeKind.Class, IsRecord: true } => "record", + { TypeKind: TypeKind.Struct, IsRecord: true } => "record struct", + { TypeKind: TypeKind.Class } => "class", + { TypeKind: TypeKind.Struct } => "struct", + _ => null + }; - if (typeKind == null) - return string.Empty; + if (typeKind == null) + return string.Empty; - var sb = new StringBuilder(); + var sb = new StringBuilder(); - sb.AppendLine(""" + sb.AppendLine(""" // // This code was generated by Copy. @@ -54,156 +54,156 @@ internal static class DeepCopyGenerator """); - if (!string.IsNullOrEmpty(namespaceName)) - { - sb.AppendLine($"namespace {namespaceName}"); - sb.AppendLine("{"); - } - - sb.AppendLine($" public partial {typeKind} {typeName}"); - sb.AppendLine(" {"); - sb.AppendLine(" [System.CodeDom.Compiler.GeneratedCode(\"DeepCopyGenerator\", \"1.0\")]"); - sb.AppendLine($" public {typeName} DeepCopy()"); - sb.AppendLine(" {"); - - var hasParameterlessCtor = typeSymbol.InstanceConstructors.Any(c => c.Parameters.Length == 0); - - if (!hasParameterlessCtor) - { - var ctor = typeSymbol.InstanceConstructors - .OrderByDescending(c => c.Parameters.Length) - .FirstOrDefault(); - - if (ctor != null) - { - var args = ctor.Parameters.Select(p => - { - var prop = Helper.GetAllProperties(typeSymbol) - .FirstOrDefault(m => m.Name.Equals(p.Name, System.StringComparison.OrdinalIgnoreCase)); - - if (prop == null) - return $"default({p.Type.ToDisplayString()})"; - - return Helper.IsTrulyPrimitive(prop.Type) - ? $"this.{prop.Name}" - : $"this.{prop.Name}?.DeepCopy()"; - }); - - sb.AppendLine($" return new {typeName}({string.Join(", ", args)});"); - } - else - { - // No constructor found - return empty string (no code generated) - if (!string.IsNullOrEmpty(namespaceName)) - sb.AppendLine(" }"); - sb.AppendLine(" }"); - if (!string.IsNullOrEmpty(namespaceName)) - sb.AppendLine("}"); - return string.Empty; - } - } - else - { - sb.AppendLine($@" return new {typeName} + if (!string.IsNullOrEmpty(namespaceName)) + { + sb.AppendLine($"namespace {namespaceName}"); + sb.AppendLine("{"); + } + + sb.AppendLine($" public partial {typeKind} {typeName}"); + sb.AppendLine(" {"); + sb.AppendLine(" [System.CodeDom.Compiler.GeneratedCode(\"DeepCopyGenerator\", \"1.0\")]"); + sb.AppendLine($" public {typeName} DeepCopy()"); + sb.AppendLine(" {"); + + var hasParameterlessCtor = typeSymbol.InstanceConstructors.Any(c => c.Parameters.Length == 0); + + if (!hasParameterlessCtor) + { + var ctor = typeSymbol.InstanceConstructors + .OrderByDescending(c => c.Parameters.Length) + .FirstOrDefault(); + + if (ctor != null) + { + var args = ctor.Parameters.Select(p => + { + var prop = Helper.GetAllProperties(typeSymbol) + .FirstOrDefault(m => m.Name.Equals(p.Name, System.StringComparison.OrdinalIgnoreCase)); + + if (prop == null) + return $"default({p.Type.ToDisplayString()})"; + + return (Helper.IsTrulyPrimitive(prop.Type) || Helper.IsBuiltinType(prop.Type)) + ? $"this.{prop.Name}" + : $"this.{prop.Name}?.DeepCopy()"; + }); + + sb.AppendLine($" return new {typeName}({string.Join(", ", args)});"); + } + else + { + // No constructor found - return empty string (no code generated) + if (!string.IsNullOrEmpty(namespaceName)) + sb.AppendLine(" }"); + sb.AppendLine(" }"); + if (!string.IsNullOrEmpty(namespaceName)) + sb.AppendLine("}"); + return string.Empty; + } + } + else + { + sb.AppendLine($@" return new {typeName} {{"); - foreach (var member in Helper.GetAllProperties(typeSymbol)) - { - if (member.IsReadOnly || member.SetMethod is null) - continue; - - var propType = member.Type; - string assignment; - - if (Helper.IsTrulyPrimitive(propType)) - { - assignment = $"this.{member.Name}"; - } - else switch (propType) - { - case IArrayTypeSymbol arrayType: - { - var elementType = arrayType.ElementType; - assignment = Helper.IsTrulyPrimitive(elementType) - ? $"this.{member.Name}?.ToArray()" - : $"this.{member.Name}?.Select(x => x?.DeepCopy()).ToArray()"; - break; - } - case INamedTypeSymbol { IsGenericType: true } named: - { - var original = named.OriginalDefinition.ToDisplayString(); - var typeArgs = named.TypeArguments; - - if (Helper.IsGenericCollection(original, out var collectionKind)) - { - var elementType = typeArgs[0]; - var cloneExpr = Helper.IsTrulyPrimitive(elementType) - ? "x" - : "x?.DeepCopy()"; - - if (collectionKind == "HashSet") - { - assignment = - $"this.{member.Name} != null ? new HashSet<{elementType.ToDisplayString()}>(this.{member.Name}.Select(x => {cloneExpr}).ToList()) : null"; - } - else if (collectionKind == "Dictionary") - { - var keyType = typeArgs[0]; - var valueType = typeArgs[1]; - - var keyCopy = Helper.IsTrulyPrimitive(keyType) ? "x.Key" : "x.Key?.DeepCopy()"; - var valueCopy = Helper.IsTrulyPrimitive(valueType) ? "x.Value" : "x.Value?.DeepCopy()"; - - assignment = $"this.{member.Name}?.ToDictionary(x => {keyCopy}, x => {valueCopy})"; - } - else - { - // For List, IEnumerable, Collection, ReadOnlyCollection, etc. - assignment = $"this.{member.Name}?.Select(x => {cloneExpr}).ToList()"; - } - } - else if (original == "System.Collections.Generic.Dictionary") - { - var keyType = typeArgs[0]; - var valueType = typeArgs[1]; - - assignment = $"this.{member.Name}?.ToDictionary(" + - $"x => {(Helper.IsTrulyPrimitive(keyType) ? "x.Key" : "x.Key?.DeepCopy()")}, " + - $"x => {(Helper.IsTrulyPrimitive(valueType) ? "x.Value" : "x.Value?.DeepCopy()")})"; - } - else if (original.StartsWith("System.Tuple") || original.StartsWith("System.ValueTuple")) - { - var tupleArgs = typeArgs.Select((arg, i) => - Helper.IsTrulyPrimitive(arg) ? $"x.Item{i + 1}" : $"x.Item{i + 1}?.DeepCopy()"); - - assignment = $"this.{member.Name} is {{ }} x ? new {propType.ToDisplayString()}({string.Join(", ", tupleArgs)}) : default"; - } - else - { - assignment = $"this.{member.Name}?.DeepCopy()"; - } - - break; - } - default: - assignment = $"this.{member.Name}?.DeepCopy()"; - break; - } - - sb.AppendLine($" {member.Name} = {assignment},"); - } - - sb.AppendLine(@" };"); - } - - sb.AppendLine(" }"); - sb.AppendLine(" }"); - - if (!string.IsNullOrEmpty(namespaceName)) - { - sb.AppendLine("}"); - } - - return sb.ToString(); - } + foreach (var member in Helper.GetAllProperties(typeSymbol)) + { + if (member.IsReadOnly || member.SetMethod is null) + continue; + + var propType = member.Type; + string assignment; + + if (Helper.IsTrulyPrimitive(propType) || Helper.IsBuiltinType(propType)) + { + assignment = $"this.{member.Name}"; + } + else switch (propType) + { + case IArrayTypeSymbol arrayType: + { + var elementType = arrayType.ElementType; + assignment = (Helper.IsTrulyPrimitive(elementType) || Helper.IsBuiltinType(elementType)) + ? $"this.{member.Name}?.ToArray()" + : $"this.{member.Name}?.Select(x => x?.DeepCopy()).ToArray()"; + break; + } + case INamedTypeSymbol { IsGenericType: true } named: + { + var original = named.OriginalDefinition.ToDisplayString(); + var typeArgs = named.TypeArguments; + + if (Helper.IsGenericCollection(original, out var collectionKind)) + { + var elementType = typeArgs[0]; + var cloneExpr = (Helper.IsTrulyPrimitive(elementType) || Helper.IsBuiltinType(elementType)) + ? "x" + : "x?.DeepCopy()"; + + if (collectionKind == "HashSet") + { + assignment = + $"this.{member.Name} != null ? new HashSet<{elementType.ToDisplayString()}>(this.{member.Name}.Select(x => {cloneExpr}).ToList()) : null"; + } + else if (collectionKind == "Dictionary") + { + var keyType = typeArgs[0]; + var valueType = typeArgs[1]; + + var keyCopy = (Helper.IsTrulyPrimitive(keyType) || Helper.IsBuiltinType(keyType)) ? "x.Key" : "x.Key?.DeepCopy()"; + var valueCopy = (Helper.IsTrulyPrimitive(valueType) || Helper.IsBuiltinType(valueType)) ? "x.Value" : "x.Value?.DeepCopy()"; + + assignment = $"this.{member.Name}?.ToDictionary(x => {keyCopy}, x => {valueCopy})"; + } + else + { + // For List, IEnumerable, Collection, ReadOnlyCollection, etc. + assignment = $"this.{member.Name}?.Select(x => {cloneExpr}).ToList()"; + } + } + else if (original == "System.Collections.Generic.Dictionary") + { + var keyType = typeArgs[0]; + var valueType = typeArgs[1]; + + assignment = $"this.{member.Name}?.ToDictionary(" + + $"x => {((Helper.IsTrulyPrimitive(keyType) || Helper.IsBuiltinType(keyType)) ? "x.Key" : "x.Key?.DeepCopy()")}, " + + $"x => {((Helper.IsTrulyPrimitive(valueType) || Helper.IsBuiltinType(valueType)) ? "x.Value" : "x.Value?.DeepCopy()")})"; + } + else if (original.StartsWith("System.Tuple") || original.StartsWith("System.ValueTuple")) + { + var tupleArgs = typeArgs.Select((arg, i) => + (Helper.IsTrulyPrimitive(arg) || Helper.IsBuiltinType(arg)) ? $"x.Item{i + 1}" : $"x.Item{i + 1}?.DeepCopy()"); + + assignment = $"this.{member.Name} is {{ }} x ? new {propType.ToDisplayString()}({string.Join(", ", tupleArgs)}) : default"; + } + else + { + assignment = $"this.{member.Name}?.DeepCopy()"; + } + + break; + } + default: + assignment = $"this.{member.Name}?.DeepCopy()"; + break; + } + + sb.AppendLine($" {member.Name} = {assignment},"); + } + + sb.AppendLine(@" };"); + } + + sb.AppendLine(" }"); + sb.AppendLine(" }"); + + if (!string.IsNullOrEmpty(namespaceName)) + { + sb.AppendLine("}"); + } + + return sb.ToString(); + } } \ No newline at end of file diff --git a/src/UtilityVerse.Copy/Generators/ShallowCopyGenerator.cs b/src/UtilityVerse.Copy/Generators/ShallowCopyGenerator.cs index f3c1da9..fa4886d 100644 --- a/src/UtilityVerse.Copy/Generators/ShallowCopyGenerator.cs +++ b/src/UtilityVerse.Copy/Generators/ShallowCopyGenerator.cs @@ -12,30 +12,30 @@ namespace UtilityVerse.Copy.Generators; internal static class ShallowCopyGenerator { - internal static string? Generate(INamedTypeSymbol typeSymbol) - { - if (typeSymbol.IsAbstract) return string.Empty; - if (!Helper.IsPartial(typeSymbol)) return string.Empty; + internal static string? Generate(INamedTypeSymbol typeSymbol) + { + if (typeSymbol.IsAbstract) return string.Empty; + if (!Helper.IsPartial(typeSymbol)) return string.Empty; - var isGlobalNamespace = typeSymbol.ContainingNamespace.IsGlobalNamespace; - var namespaceName = isGlobalNamespace ? null : typeSymbol.ContainingNamespace.ToDisplayString(); - var typeName = typeSymbol.Name; + var isGlobalNamespace = typeSymbol.ContainingNamespace.IsGlobalNamespace; + var namespaceName = isGlobalNamespace ? null : typeSymbol.ContainingNamespace.ToDisplayString(); + var typeName = typeSymbol.Name; - var typeKind = typeSymbol switch - { - { TypeKind: TypeKind.Class, IsRecord: true } => "record", - { TypeKind: TypeKind.Struct, IsRecord: true } => "record struct", - { TypeKind: TypeKind.Class } => "class", - { TypeKind: TypeKind.Struct } => "struct", - _ => null - }; + var typeKind = typeSymbol switch + { + { TypeKind: TypeKind.Class, IsRecord: true } => "record", + { TypeKind: TypeKind.Struct, IsRecord: true } => "record struct", + { TypeKind: TypeKind.Class } => "class", + { TypeKind: TypeKind.Struct } => "struct", + _ => null + }; - if (typeKind == null) - return null; + if (typeKind == null) + return null; - var sb = new StringBuilder(); + var sb = new StringBuilder(); - sb.AppendLine(""" + sb.AppendLine(""" // // This code was generated by Copy. @@ -54,93 +54,94 @@ internal static class ShallowCopyGenerator """); - if (!string.IsNullOrEmpty(namespaceName)) - { - sb.AppendLine($"namespace {namespaceName}"); - sb.AppendLine("{"); - } - - sb.AppendLine($" public partial {typeKind} {typeName}"); - sb.AppendLine(" {"); - sb.AppendLine(" [System.CodeDom.Compiler.GeneratedCode(\"ShallowCopyGenerator\", \"1.0\")]"); - sb.AppendLine($" public {typeName} ShallowCopy()"); - sb.AppendLine(" {"); - - if (typeSymbol.TypeKind == TypeKind.Class || typeSymbol.IsRecord) - { - sb.AppendLine($" var copy = ({typeName})this.MemberwiseClone();"); - - foreach (var member in Helper.GetAllProperties(typeSymbol)) - { - if (member.IsReadOnly || member.SetMethod is null) - continue; - - var propType = member.Type; - if (Helper.IsPrimitive(propType)) continue; - - string? assignment = null; - - switch (propType) - { - case IArrayTypeSymbol: - assignment = $"this.{member.Name} != null ? ({member.Type.ToDisplayString()})this.{member.Name}.Clone() : null"; - break; - - case INamedTypeSymbol named when named.IsGenericType: - { - var original = named.OriginalDefinition.ConstructUnboundGenericType().ToDisplayString(); - - if (Helper.IsGenericCollection(original, out var kind)) - { - var itemType = named.TypeArguments.FirstOrDefault()?.ToDisplayString() ?? "var"; - assignment = kind switch - { - "List" or "Enumerable" => - $"this.{member.Name}?.ToList()", - - "HashSet" => - $"this.{member.Name} != null ? new HashSet<{itemType}>(this.{member.Name}) : null", - - "Dictionary" => - $"this.{member.Name}?.ToDictionary(x => x.Key, x => x.Value)", - - _ => null - }; - } - else if (original.StartsWith("System.Tuple")) - { - assignment = $"this.{member.Name}"; - } - - break; - } - - case INamedTypeSymbol named when named.ToDisplayString().StartsWith("System.ValueTuple"): - assignment = $"this.{member.Name}"; - break; - } - - if (assignment != null) - { - sb.AppendLine($" copy.{member.Name} = {assignment};"); - } - } - - sb.AppendLine(" return copy;"); - } - else - { - sb.AppendLine(" return this;"); - } - - sb.AppendLine(" }"); - sb.AppendLine(" }"); - - if (!string.IsNullOrEmpty(namespaceName)) - { - sb.AppendLine("}"); - } - - return sb.ToString(); - } + if (!string.IsNullOrEmpty(namespaceName)) + { + sb.AppendLine($"namespace {namespaceName}"); + sb.AppendLine("{"); + } + + sb.AppendLine($" public partial {typeKind} {typeName}"); + sb.AppendLine(" {"); + sb.AppendLine(" [System.CodeDom.Compiler.GeneratedCode(\"ShallowCopyGenerator\", \"1.0\")]"); + sb.AppendLine($" public {typeName} ShallowCopy()"); + sb.AppendLine(" {"); + + if (typeSymbol.TypeKind == TypeKind.Class || typeSymbol.IsRecord) + { + sb.AppendLine($" var copy = ({typeName})this.MemberwiseClone();"); + + foreach (var member in Helper.GetAllProperties(typeSymbol)) + { + if (member.IsReadOnly || member.SetMethod is null) + continue; + + var propType = member.Type; + + if (Helper.IsTrulyPrimitive(propType) || Helper.IsBuiltinType(propType)) continue; + + string? assignment = null; + + switch (propType) + { + case IArrayTypeSymbol: + assignment = $"this.{member.Name} != null ? ({member.Type.ToDisplayString()})this.{member.Name}.Clone() : null"; + break; + + case INamedTypeSymbol named when named.IsGenericType: + { + var original = named.OriginalDefinition.ConstructUnboundGenericType().ToDisplayString(); + + if (Helper.IsGenericCollection(original, out var kind)) + { + var itemType = named.TypeArguments.FirstOrDefault()?.ToDisplayString() ?? "var"; + assignment = kind switch + { + "List" or "Enumerable" => + $"this.{member.Name}?.ToList()", + + "HashSet" => + $"this.{member.Name} != null ? new HashSet<{itemType}>(this.{member.Name}) : null", + + "Dictionary" => + $"this.{member.Name}?.ToDictionary(x => x.Key, x => x.Value)", + + _ => null + }; + } + else if (original.StartsWith("System.Tuple")) + { + assignment = $"this.{member.Name}"; + } + + break; + } + + case INamedTypeSymbol named when named.ToDisplayString().StartsWith("System.ValueTuple"): + assignment = $"this.{member.Name}"; + break; + } + + if (assignment != null) + { + sb.AppendLine($" copy.{member.Name} = {assignment};"); + } + } + + sb.AppendLine(" return copy;"); + } + else + { + sb.AppendLine(" return this;"); + } + + sb.AppendLine(" }"); + sb.AppendLine(" }"); + + if (!string.IsNullOrEmpty(namespaceName)) + { + sb.AppendLine("}"); + } + + return sb.ToString(); + } } \ No newline at end of file diff --git a/src/UtilityVerse.Copy/Helper.cs b/src/UtilityVerse.Copy/Helper.cs index 83ce90d..76591da 100644 --- a/src/UtilityVerse.Copy/Helper.cs +++ b/src/UtilityVerse.Copy/Helper.cs @@ -8,109 +8,145 @@ namespace UtilityVerse.Copy; internal static class Helper { - internal static bool IsPrimitive(ITypeSymbol symbol) => - symbol.IsValueType || symbol.SpecialType == SpecialType.System_String; - - internal static bool IsTrulyPrimitive(ITypeSymbol symbol) - { - return symbol.SpecialType switch - { - SpecialType.System_Boolean or - SpecialType.System_Byte or - SpecialType.System_SByte or - SpecialType.System_Int16 or - SpecialType.System_UInt16 or - SpecialType.System_Int32 or - SpecialType.System_UInt32 or - SpecialType.System_Int64 or - SpecialType.System_UInt64 or - SpecialType.System_Single or - SpecialType.System_Double or - SpecialType.System_Char or - SpecialType.System_Enum or - SpecialType.System_String => true, - _ => false - }; - } - - internal static bool IsGenericCollection(string? originalDef, out string? kind) - { - kind = originalDef switch - { - "System.Collections.Generic.List" => "List", - "System.Collections.Generic.IList" => "List", - "System.Collections.ObjectModel.Collection" => "List", - "System.Collections.ObjectModel.ReadOnlyCollection" => "List", - "System.Collections.ObjectModel.ObservableCollection" => "List", - "System.ComponentModel.BindingList" => "List", - "System.Collections.Immutable.ImmutableList" => "List", - "System.Collections.Generic.ReadOnlyList" => "List", - - "System.Collections.Generic.IEnumerable" => "Enumerable", - "System.Collections.Generic.ICollection" => "Enumerable", - "System.Collections.Generic.IReadOnlyCollection" => "Enumerable", - "System.Collections.Generic.IReadOnlyList" => "Enumerable", - - "System.Collections.Generic.HashSet" => "HashSet", - - "System.Collections.Generic.Dictionary" => "Dictionary", - "System.Collections.Frozen.FrozenDictionary" => "Dictionary", - "System.Collections.Concurrent.ConcurrentDictionary" => "Dictionary", - - "System.Collections.Immutable.ImmutableArray" => "List", - "System.Collections.Immutable.ImmutableSortedSet" => "HashSet", - "System.Collections.Immutable.ImmutableHashSet" => "HashSet", - "System.Collections.Immutable.ImmutableDictionary" => "Dictionary", - "System.Collections.Immutable.ImmutableSortedDictionary" => "Dictionary", - - "System.Collections.Generic.Queue" => "Queue", - "System.Collections.Generic.Stack" => "Stack", - - _ => null - }; - - return kind != null; - } - - internal static IEnumerable GetAllProperties(INamedTypeSymbol? type) - { - while (type != null && type.SpecialType != SpecialType.System_Object) - { - foreach (var member in type.GetMembers().OfType()) - { - if (!member.IsReadOnly && member.SetMethod != null) - yield return member; - } - - type = type.BaseType; - } - } - - internal static bool IsPartial(INamedTypeSymbol typeSymbol) - { - return typeSymbol.DeclaringSyntaxReferences.Any(syntaxRef => - syntaxRef.GetSyntax() is TypeDeclarationSyntax syntax && - syntax.Modifiers.Any(m => m.IsKind(SyntaxKind.PartialKeyword))); - } - - internal static bool HasDeepCopyOptIn(INamedTypeSymbol typeSymbol) - { - return typeSymbol.GetAttributes().Any(a => - SymbolEquals(a.AttributeClass, "UtilityVerse.Copy.DeepCopy")) || - typeSymbol.AllInterfaces.Any(i => - SymbolEquals(i, "UtilityVerse.Copy.IDeepCopy")); - } - - internal static bool HasShallowCopyOptIn(INamedTypeSymbol typeSymbol) - { - return typeSymbol.GetAttributes().Any(a => - SymbolEquals(a.AttributeClass, "UtilityVerse.Copy.ShallowCopy")) || - typeSymbol.AllInterfaces.Any(i => - SymbolEquals(i, "UtilityVerse.Copy.IShallowCopy")); - } - - private static bool SymbolEquals(ISymbol? symbol, string fullyQualifiedMetadataName) - { - return symbol?.ToDisplayString() == fullyQualifiedMetadataName; - } + internal static bool IsTrulyPrimitive(ITypeSymbol symbol) + { + return symbol.IsValueType || symbol.TypeKind is TypeKind.Enum || symbol.SpecialType switch + { + SpecialType.System_Boolean or + SpecialType.System_Byte or + SpecialType.System_SByte or + SpecialType.System_Int16 or + SpecialType.System_UInt16 or + SpecialType.System_Int32 or + SpecialType.System_UInt32 or + SpecialType.System_Int64 or + SpecialType.System_UInt64 or + SpecialType.System_Single or + SpecialType.System_Double or + SpecialType.System_Char or + SpecialType.System_Enum or + SpecialType.System_String => true, + _ => false + }; + } + + internal static bool IsBuiltinType(ITypeSymbol symbol) + { + return symbol.ToDisplayString() switch + { + "System.DateTime" or + "System.DateOnly" or + "System.DateTimeOffset" or + "System.Guid" or + "System.TimeSpan" or + "System.Decimal" or + "System.Uri" or + "System.Version" or + "System.Numerics.BigInteger" or + "System.Numerics.Complex" or + "System.Index" or + "System.Range" or + "System.Half" or + "System.Int128" or + "System.UInt128" => true, + _ => false + }; + } + internal static bool IsCollectionType(ITypeSymbol symbol) + { + return symbol.AllInterfaces.Any(i => + i.OriginalDefinition.ToDisplayString() == "System.Collections.Generic.IEnumerable"); + } + + internal static bool IsGenericCollection(string? originalDef, out string? kind) + { + kind = originalDef switch + { + "System.Collections.Generic.List" => "List", + "System.Collections.Generic.IList" => "List", + "System.Collections.ObjectModel.Collection" => "List", + "System.Collections.ObjectModel.ReadOnlyCollection" => "List", + "System.Collections.ObjectModel.ObservableCollection" => "List", + "System.ComponentModel.BindingList" => "List", + "System.Collections.Immutable.ImmutableList" => "List", + "System.Collections.Generic.ReadOnlyList" => "List", + + "System.Collections.Generic.IEnumerable" => "Enumerable", + "System.Collections.Generic.ICollection" => "Enumerable", + "System.Collections.Generic.IReadOnlyCollection" => "Enumerable", + "System.Collections.Generic.IReadOnlyList" => "Enumerable", + + "System.Collections.Generic.HashSet" => "HashSet", + + "System.Collections.Generic.Dictionary" => "Dictionary", + "System.Collections.Frozen.FrozenDictionary" => "Dictionary", + "System.Collections.Concurrent.ConcurrentDictionary" => "Dictionary", + + "System.Collections.Immutable.ImmutableArray" => "List", + "System.Collections.Immutable.ImmutableSortedSet" => "HashSet", + "System.Collections.Immutable.ImmutableHashSet" => "HashSet", + "System.Collections.Immutable.ImmutableDictionary" => "Dictionary", + "System.Collections.Immutable.ImmutableSortedDictionary" => "Dictionary", + + "System.Collections.Generic.Queue" => "Queue", + "System.Collections.Generic.Stack" => "Stack", + + _ => null + }; + + return kind != null; + } + + internal static IEnumerable GetAllProperties(INamedTypeSymbol? type) + { + while (type != null && type.SpecialType != SpecialType.System_Object) + { + foreach (var member in type.GetMembers().OfType()) + { + if (!member.IsReadOnly && member.SetMethod != null) + yield return member; + } + + type = type.BaseType; + } + } + + internal static bool IsPartial(INamedTypeSymbol typeSymbol) + { + return typeSymbol.DeclaringSyntaxReferences.Any(syntaxRef => + syntaxRef.GetSyntax() is TypeDeclarationSyntax syntax && + syntax.Modifiers.Any(m => m.IsKind(SyntaxKind.PartialKeyword))); + } + + internal static bool HasDeepCopyOptIn(INamedTypeSymbol typeSymbol) + { + return typeSymbol.GetAttributes().Any(a => + SymbolEquals(a.AttributeClass, "UtilityVerse.Copy.DeepCopy")) || + typeSymbol.AllInterfaces.Any(i => + SymbolEquals(i, "UtilityVerse.Copy.IDeepCopy")); + } + + internal static bool HasShallowCopyOptIn(INamedTypeSymbol typeSymbol) + { + return typeSymbol.GetAttributes().Any(a => + SymbolEquals(a.AttributeClass, "UtilityVerse.Copy.ShallowCopy")) || + typeSymbol.AllInterfaces.Any(i => + SymbolEquals(i, "UtilityVerse.Copy.IShallowCopy")); + } + + internal static bool SymbolEquals(ISymbol? symbol, string fullyQualifiedMetadataName) + { + return symbol?.ToDisplayString() == fullyQualifiedMetadataName; + } + internal static INamedTypeSymbol UnwrapNullable(ITypeSymbol type) + { + if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T && + type is INamedTypeSymbol namedType && + namedType.TypeArguments.FirstOrDefault() is INamedTypeSymbol underlying) + { + return underlying; + } + + return type as INamedTypeSymbol ?? throw new System.InvalidOperationException("Expected named type."); + } } diff --git a/test/UtilityVerse.Copy.Test/HelloWorld.cs b/test/UtilityVerse.Copy.Test/HelloWorld.cs index 9caaae1..3256989 100644 --- a/test/UtilityVerse.Copy.Test/HelloWorld.cs +++ b/test/UtilityVerse.Copy.Test/HelloWorld.cs @@ -3,31 +3,53 @@ namespace UtilityVerse.Copy.Test; [DeepCopy] public partial class HelloWorld { - public int Id { get; set; } - public string? Name { get; set; } - public IEnumerable
      Addresses { get; set; } = []; - - public HelloWorld Clone() - { - return new HelloWorld - { - Id = Id, - Name = Name, - Addresses = Addresses.Select(x => x.Clone()).ToList() - }; - } + public int Id { get; set; } + public string? Name { get; set; } + public DateTime CreatedAt { get; set; } + public IEnumerable
      Addresses { get; set; } = []; + + public HelloWorld Clone() + { + return new HelloWorld + { + Id = Id, + Name = Name, + Addresses = Addresses.Select(x => x.Clone()).ToList() + }; + } } [DeepCopy] public partial class Address { - public string? StreetNumber { get; set; } - - public Address Clone() - { - return new Address - { - StreetNumber = StreetNumber - }; - } + public string? StreetNumber { get; set; } + + public Address Clone() + { + return new Address + { + StreetNumber = StreetNumber + }; + } +} + + +[DeepCopy] +public partial class Hello +{ + public Guid Id { get; set; } + public DateTime CreatedAt { get; set; } + public Status Status { get; set; } + public DateOnly CreatedDateOnly { get; set; } + + public Hello2[]? Hello2s { get; set; } +} + +[DeepCopy] +public partial record Hello2(Guid Id); + +public enum Status +{ + Ready, + Finished } \ No newline at end of file diff --git a/test/UtilityVerse.Copy.Test/Program.cs b/test/UtilityVerse.Copy.Test/Program.cs index ac81b69..3e9c547 100644 --- a/test/UtilityVerse.Copy.Test/Program.cs +++ b/test/UtilityVerse.Copy.Test/Program.cs @@ -44,6 +44,15 @@ static void AutomatedTesting() static void ManualTesting() { + var h = new Hello() + { + + }; + + h.DeepCopy(); + + + var originalObject = new HelloWorld() { Id = 1, @@ -51,6 +60,8 @@ static void ManualTesting() Addresses = new[] { new Address() { StreetNumber = "12" } } }; var clonedObject = originalObject.Clone(); + + var c = originalObject.DeepCopy(); Console.WriteLine("Before Cloning..."); Console.WriteLine( $"OriginalObject Id: {originalObject.Id} Name: {originalObject.Name} Addresses: {originalObject.Addresses.First().StreetNumber}"); From 48ad4eb931ddabce44cad10b404590964e76a02f Mon Sep 17 00:00:00 2001 From: purkayasta Date: Sun, 20 Jul 2025 01:16:41 +0600 Subject: [PATCH 16/17] COPY: 0.5.0 Pushed --- src/UtilityVerse.Copy/UtilityVerse.Copy.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UtilityVerse.Copy/UtilityVerse.Copy.csproj b/src/UtilityVerse.Copy/UtilityVerse.Copy.csproj index ad62653..511e9dd 100644 --- a/src/UtilityVerse.Copy/UtilityVerse.Copy.csproj +++ b/src/UtilityVerse.Copy/UtilityVerse.Copy.csproj @@ -15,7 +15,7 @@ Copy UtilityVerse.Copy - 0.4.0 + 0.5.0 Pritom Purkayasta A Roslyn source generator for generating shallow copy and deep copy for class, records and structs From c3b57ed376dedc9b9519b26f201d202e4ece970a Mon Sep 17 00:00:00 2001 From: purkayasta Date: Sun, 20 Jul 2025 01:16:41 +0600 Subject: [PATCH 17/17] COPY: 0.5.0 Pushed modified: src/UtilityVerse.Copy/Analyzers/ValidationAnalyzer.cs modified: src/UtilityVerse.Copy/UtilityVerse.Copy.csproj --- src/UtilityVerse.Copy/Analyzers/ValidationAnalyzer.cs | 8 -------- src/UtilityVerse.Copy/UtilityVerse.Copy.csproj | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/UtilityVerse.Copy/Analyzers/ValidationAnalyzer.cs b/src/UtilityVerse.Copy/Analyzers/ValidationAnalyzer.cs index b1cb920..d9332ff 100644 --- a/src/UtilityVerse.Copy/Analyzers/ValidationAnalyzer.cs +++ b/src/UtilityVerse.Copy/Analyzers/ValidationAnalyzer.cs @@ -108,14 +108,6 @@ private static void AnalyzeTypeRecursive( } } - //private static INamedTypeSymbol UnwrapNullable(INamedTypeSymbol type) - //{ - // return type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T && - // type.TypeArguments.FirstOrDefault() is INamedTypeSymbol underlying - // ? underlying - // : type; - //} - private static bool IsInsideCopyEnabledPartialParent(INamedTypeSymbol? symbol) { while (symbol is not null) diff --git a/src/UtilityVerse.Copy/UtilityVerse.Copy.csproj b/src/UtilityVerse.Copy/UtilityVerse.Copy.csproj index ad62653..511e9dd 100644 --- a/src/UtilityVerse.Copy/UtilityVerse.Copy.csproj +++ b/src/UtilityVerse.Copy/UtilityVerse.Copy.csproj @@ -15,7 +15,7 @@ Copy UtilityVerse.Copy - 0.4.0 + 0.5.0 Pritom Purkayasta A Roslyn source generator for generating shallow copy and deep copy for class, records and structs