From 795b7af2322e4c1f05dd3360d2e02b8df2a4e4fc Mon Sep 17 00:00:00 2001 From: root Date: Sun, 3 Nov 2024 11:15:40 +0000 Subject: [PATCH] start and redesign again for new version of wooc... --- LICENSE.txt | 676 +- README.txt | 66 +- admin/class-ssbhesabix-admin.php | 3175 +-- admin/css/bootstrap.css | 21578 ++++++++-------- admin/css/fontiran.css | 208 +- ...hesabix-admin.css => ssbhesabfa-admin.css} | 134 +- admin/fonts/svg/IRANYekanWebRegular.svg | 3096 +-- admin/fonts/svg/iranyekanwebblack.svg | 2948 +-- admin/fonts/svg/iranyekanwebbold.svg | 3138 +-- admin/fonts/svg/iranyekanwebextrablack.svg | 2972 +-- admin/fonts/svg/iranyekanwebextrabold.svg | 2944 +-- admin/fonts/svg/iranyekanweblight.svg | 3238 +-- admin/fonts/svg/iranyekanwebmedium.svg | 3146 +-- admin/fonts/svg/iranyekanwebthin.svg | 3278 +-- admin/img/hesabix-logo.fa.png | Bin 13643 -> 26562 bytes admin/img/logo.png | Bin 5553 -> 5466 bytes admin/img/menu-icon.png | Bin 4974 -> 4994 bytes admin/js/bootstrap.bundle.min.js | 12 +- admin/js/ssbhesabix-admin.js | 1730 +- admin/partials/ssbhesabix-admin-display.php | 742 +- admin/partials/ssbhesabix-admin-functions.php | 5612 +++- admin/partials/ssbhesabix-admin-setting.php | 4179 +-- admin/partials/ssbhesabix-html-output.php | 743 +- admin/services/HesabixLogService.php | 126 +- admin/services/HesabixWpFaService.php | 726 +- admin/services/ssbhesabixCustomerService.php | 504 +- admin/services/ssbhesabixItemService.php | 212 +- includes/class-ssbhesabix-activator.php | 140 +- includes/class-ssbhesabix-api.php | 973 +- includes/class-ssbhesabix-deactivator.php | 56 +- includes/class-ssbhesabix-i18n.php | 67 +- includes/class-ssbhesabix-loader.php | 245 +- includes/class-ssbhesabix-validation.php | 635 +- includes/class-ssbhesabix-webhook.php | 631 +- includes/class-ssbhesabix.php | 664 +- ...bix-webhook.php => ssbhesabfa-webhook.php} | 61 +- languages/ssbhesabix-fa_IR.mo | Bin 30068 -> 29506 bytes languages/ssbhesabix-fa_IR.po | 1971 +- ssbhesabix.php | 145 +- uninstall.php | 67 +- 40 files changed, 37494 insertions(+), 33344 deletions(-) rename admin/css/{ssbhesabix-admin.css => ssbhesabfa-admin.css} (93%) rename includes/{ssbhesabix-webhook.php => ssbhesabfa-webhook.php} (90%) diff --git a/LICENSE.txt b/LICENSE.txt index ecbc059..0a98ec0 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,339 +1,339 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. \ No newline at end of file diff --git a/README.txt b/README.txt index 0e0f515..34c2bdf 100644 --- a/README.txt +++ b/README.txt @@ -1,31 +1,35 @@ -=== Hesabix Accounting === -Contributors: saeedsb, hamidprime, sepehr-najafi -Tags: accounting cloud hesabix -Requires at least: 5.2 -Tested up to: 6.4.2 -Requires PHP: 5.6 -Stable tag: 2.0.93 -License: GPLv2 or later -License URI: https://www.gnu.org/licenses/gpl-2.0.html - -Connect Hesabix Online Accounting to WooCommerce. - -== Description == -This plugin helps connect your (online) store to Hesabix online accounting software. By using this plugin, saving products, contacts, and orders in your store will also save them automatically in your Hesabix account. Besides that, just after a client pays a bill, the receipt document will be stored in Hesabix as well. Of course, you have to register your account in Hesabix first. To do so, visit Hesabix at the link here hesabix.ir and sign up for free. After you signed up and entered your account, choose your business, then in the settings menu/API, you can find the API keys for the business and import them to the plugin settings. Now your module is ready to use. - -For more information and a full guide to how to use Hesabix and WooCommerce Plugin, visit Hesabix’s website and go to the “Accounting School” menu. - -== Installation == -1. Upload the plugin files to the `/wp-content/plugins/hesabix-accounting` directory, or install the hesabix plugin through the WordPress plugins screen directly. -2. Activate the plugin through the \'Plugins\' screen in WordPress -3. Use the Settings->Hesabix screen to configure the plugin - -== Screenshots == -1. API setting page -2. Catalog setting page -3. Customers setting page -4. Invoice setting page -5. Payment Methods setting page -6. Import and export setting page -7. Sync setting page -8. Log file +=== Hesabix Accounting === +Contributors: saeedsb, hamidprime, sepehr-najafi, Babak alizadeh +Tags: accounting cloud Hesabix +Requires at least: 5.2 +Tested up to: 6.6.1 +Requires PHP: 5.6 +Stable tag: 2.1.1 +License: GPLv2 or later +License URI: https://www.gnu.org/licenses/gpl-2.0.html + +Connect Hesabix Online Accounting to WooCommerce. + +== Description == +This plugin helps connect your (online) store to Hesabix online accounting software. By using this plugin, saving products, contacts, and orders in your store will also save them automatically in your Hesabix account. Besides that, just after a client pays a bill, the receipt document will be stored in Hesabix as well. Of course, you have to register your account in Hesabix first. To do so, visit Hesabix at the link here www.Hesabix.com and sign up for free. After you signed up and entered your account, choose your business, then in the settings menu/API, you can find the API keys for the business and import them to the plugin settings. Now your module is ready to use. + +For more information and a full guide to how to use Hesabix and WooCommerce Plugin, visit Hesabix’s website and go to the “Accounting School” menu. + +== Installation == +1. Upload the plugin files to the `/wp-content/plugins/hesabixWCplugin` directory, or install the Hesabix plugin through the WordPress plugins screen directly. +2. Activate the plugin through the \'Plugins\' screen in WordPress +3. Use the Settings->Hesabix screen to configure the plugin + +== Screenshots == +1. API setting page +2. Catalog setting page +3. Customers setting page +4. Invoice setting page +5. Payment Methods setting page +6. Import and export setting page +7. Sync setting page +8. Log file + +== Changelog == += 1.0.0 - 07.03.2024 = +* Initial stable release. \ No newline at end of file diff --git a/admin/class-ssbhesabix-admin.php b/admin/class-ssbhesabix-admin.php index d294617..5b80987 100644 --- a/admin/class-ssbhesabix-admin.php +++ b/admin/class-ssbhesabix-admin.php @@ -1,1517 +1,1658 @@ - - * @author HamidReza Gharahzadeh - * @author Sepehr Najafi - */ -class Ssbhesabix_Admin -{ - - /** - * The ID of this plugin. - * - * @since 1.0.0 - * @access private - * @var string $plugin_name The ID of this plugin. - */ - private $plugin_name; - - /** - * The version of this plugin. - * - * @since 1.0.0 - * @access private - * @var string $version The current version of this plugin. - */ - private $version; -//========================================================================================================================= - /** - * Initialize the class and set its properties. - * - * @param string $plugin_name The name of this plugin. - * @param string $version The version of this plugin. - * @since 1.0.0 - */ - public function __construct($plugin_name, $version) - { - $this->plugin_name = $plugin_name; - $this->version = $version; - $this->load_dependencies(); - } - - /** - * Check DB ver on plugin update and do necessary actions - * - * @since 1.0.7 - */ -//========================================================================================================================= - public function ssbhesabix_update_db_check() - { - $current_db_ver = get_site_option('ssbhesabix_db_version'); - if ($current_db_ver === false || $current_db_ver < 1.1) { - global $wpdb; - $table_name = $wpdb->prefix . "ssbhesabix"; - - $sql = "ALTER TABLE $table_name - ADD `id_ps_attribute` INT(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `id_ps`;"; - - if (!$wpdb->query($sql)) { - HesabixLogService::log(array("Cannot alter table $table_name. Current DB Version: $current_db_ver")); - } else { - update_option('ssbhesabix_db_version', 1.1); - HesabixLogService::log(array("Alter table $table_name. Current DB Version: $current_db_ver")); - } - } - } -//========================================================================================================================= - /** - * Register the stylesheets for the admin area. - * - * @since 1.0.0 - */ - public function enqueue_styles() - { - /** - * This function is provided for demonstration purposes only. - * - * An instance of this class should be passed to the run() function - * defined in Ssbhesabix_Loader as all of the hooks are defined - * in that particular class. - * - * The Ssbhesabix_Loader will then create the relationship - * between the defined hooks and the functions defined in this - * class. - */ - if( isset($_GET['page']) && str_contains($_GET['page'], "hesabix") ){ - wp_enqueue_style($this->plugin_name, plugin_dir_url(__FILE__) . 'css/ssbhesabix-admin.css?v=1', array(), $this->version, 'all'); - wp_enqueue_style('bootstrap_css', plugin_dir_url(__FILE__) . 'css/bootstrap.css', array(), $this->version, 'all'); - } - } -//========================================================================================================================= - /** - * Register the JavaScript for the admin area. - * - * @since 1.0.0 - */ - public function enqueue_scripts() - { - /** - * This function is provided for demonstration purposes only. - * - * An instance of this class should be passed to the run() function - * defined in Ssbhesabix_Loader as all of the hooks are defined - * in that particular class. - * - * The Ssbhesabix_Loader will then create the relationship - * between the defined hooks and the functions defined in this - * class. - */ - - wp_enqueue_script($this->plugin_name, plugin_dir_url(__FILE__) . 'js/ssbhesabix-admin.js', array('jquery'), $this->version, false); - if( isset($_GET['page']) && str_contains($_GET['page'], "hesabix") ) - wp_enqueue_script('bootstrap_js', plugin_dir_url(__FILE__) . 'js/bootstrap.bundle.min.js', array('jquery'), $this->version, false); - } -//========================================================================================================================= - private function load_dependencies() - { - /** - * The class responsible for defining all actions that occur in the Dashboard - */ - require_once plugin_dir_path(dirname(__FILE__)) . 'admin/partials/ssbhesabix-admin-display.php'; - - /** - * The class responsible for defining function for display Html element - */ - require_once plugin_dir_path(dirname(__FILE__)) . 'admin/partials/ssbhesabix-html-output.php'; - - /** - * The class responsible for defining function for display general setting tab - */ - require_once plugin_dir_path(dirname(__FILE__)) . 'admin/partials/ssbhesabix-admin-setting.php'; - - /** - * The class responsible for defining function for admin area - */ - require_once plugin_dir_path(dirname(__FILE__)) . 'admin/partials/ssbhesabix-admin-functions.php'; - } - - /** - * WC missing notice for the admin area. - * - * @since 1.0.0 - */ -//========================================================================================================================= - public function ssbhesabix_missing_notice() - { - echo '

' . sprintf(__('Hesabix Plugin requires the %s to work!', 'ssbhesabix'), '' . __('WooCommerce', 'ssbhesabix') . '') . '

'; - } - - /** - * Hesabix Plugin Live mode notice for the admin area. - * - * @since 1.0.0 - */ -//========================================================================================================================= - public function ssbhesabix_live_mode_notice() - { - echo '

' . __('Hesabix Plugin need to connect to Hesabix Accounting, Please check the API credential!', 'ssbhesabix') . '

'; - } -//========================================================================================================================= - - /** - * Missing hesabix default currency notice for the admin area. - * - * @since 1.0.0 - */ -//========================================================================================================================= - public function ssbhesabix_currency_notice() - { - echo '

' . __('Hesabix Plugin cannot works! because WooCommerce currency in not match with Hesabix.', 'ssbhesabix') . '

'; - } -//========================================================================================================================= - public function ssbhesabix_general_notices() { - if (!empty( $_REQUEST['submit_selected_orders_invoice_in_hesabix'])) { - if(!empty($_REQUEST['error_msg']) && $_REQUEST['error_msg'] == "select_max_10_items") { - printf( '

%s

', - __('Error: Select maximum 10 orders. Due to some limitations in Hesabix API, sending too many requests in one minute is not possible.', 'ssbhesabix')); - } else { - $success_count = intval( $_REQUEST['success_count'] ); - printf( '

%s %d

', __('Selected orders invoices have been saved. Number of saved invoices: ', 'ssbhesabix'), $success_count); - } - } - } - -//========================================================================================================================= - /* - * Action - Ajax 'export products' from Hesabix/Export tab - * @since 1.0.0 - */ - public function adminExportProductsCallback() - { - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - - $batch = wc_clean($_POST['batch']); - $totalBatch = wc_clean($_POST['totalBatch']); - $total = wc_clean($_POST['total']); - $updateCount = wc_clean($_POST['updateCount']); - - $func = new Ssbhesabix_Admin_Functions(); - $result = $func->exportProducts($batch, $totalBatch, $total, $updateCount); - - if ($result['error']) { - if ($updateCount === -1) { - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productExportResult=false&error=-1'); - } else { - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productExportResult=false'); - } - } else { - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productExportResult=true&processed=' . $result['updateCount']); - } - - echo json_encode($result); - die(); - } - } -//========================================================================================================================= - public function adminImportProductsCallback() - { - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - - $batch = wc_clean($_POST['batch']); - $totalBatch = wc_clean($_POST['totalBatch']); - $total = wc_clean($_POST['total']); - $updateCount = wc_clean($_POST['updateCount']); - - $func = new Ssbhesabix_Admin_Functions(); - $result = $func->importProducts($batch, $totalBatch, $total, $updateCount); - $import_count = $result['updateCount']; - - if ($result['error']) { - if ($import_count === -1) { - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productImportResult=false&error=-1'); - } else { - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productImportResult=false'); - } - } else { - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productImportResult=true&processed=' . $import_count); - } - - echo json_encode($result); - die(); - } - } -//========================================================================================================================= - /* - * Action - Ajax 'export products Opening Quantity' from Hesabix/Export tab - * @since 1.0.6 - */ - public function adminExportProductsOpeningQuantityCallback() - { - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - - $batch = wc_clean($_POST['batch']); - $totalBatch = wc_clean($_POST['totalBatch']); - $total = wc_clean($_POST['total']); - - $func = new Ssbhesabix_Admin_Functions(); - $result = $func->exportOpeningQuantity($batch, $totalBatch, $total); - if ($result['error']) { - if ($result['errorType'] == 'shareholderError') { - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productOpeningQuantityExportResult=false&shareholderError=true'); - } else if ($result['errorType'] == 'noProduct') { - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productOpeningQuantityExportResult=false&noProduct=true'); - } else { - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productOpeningQuantityExportResult=false'); - } - } else { - if ($result["done"] == true) - update_option('ssbhesabix_use_export_product_opening_quantity', true); - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productOpeningQuantityExportResult=true'); - } - - echo json_encode($result); - die(); - } - } -//========================================================================================================================= - /* - * Action - Ajax 'export customers' from Hesabix/Export tab - * @since 1.0.0 - */ - public function adminExportCustomersCallback() - { - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - - $batch = wc_clean($_POST['batch']); - $totalBatch = wc_clean($_POST['totalBatch']); - $total = wc_clean($_POST['total']); - $updateCount = wc_clean($_POST['updateCount']); - - $func = new Ssbhesabix_Admin_Functions(); - $result = $func->exportCustomers($batch, $totalBatch, $total, $updateCount); - - if ($result["error"]) { - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&customerExportResult=false'); - } else { - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&customerExportResult=true&processed=' . $result["updateCount"]); - } - echo json_encode($result); - - die(); - } - } -//========================================================================================================================= - /* - * Action - Ajax 'Sync Changes' from Hesabix/Sync tab - * @since 1.0.0 - */ - public function adminSyncChangesCallback() - { - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - include(plugin_dir_path(__DIR__) . 'includes/class-ssbhesabix-webhook.php'); - new Ssbhesabix_Webhook(); - - $redirect_url = admin_url('admin.php?page=ssbhesabix-option&tab=sync&changesSyncResult=true'); - echo $redirect_url; - - die(); - } - } -//========================================================================================================================= - /* - * Action - Ajax 'Sync Products' from Hesabix/Sync tab - * @since 1.0.0 - */ - public function adminSyncProductsCallback() - { - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - - $batch = wc_clean($_POST['batch']); - $totalBatch = wc_clean($_POST['totalBatch']); - $total = wc_clean($_POST['total']); - - $func = new Ssbhesabix_Admin_Functions(); - $result = $func->syncProducts($batch, $totalBatch, $total); - if ($result['error']) { - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&productSyncResult=false'); - echo json_encode($result); - } else { - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&productSyncResult=true'); - echo json_encode($result); - } - die(); - } - } -//========================================================================================================================= - /* - * Action - Ajax 'Sync Orders from Hesabix/Sync tab - * @since 1.0.0 - */ - public function adminSyncOrdersCallback() - { - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - - $batch = wc_clean($_POST['batch']); - $totalBatch = wc_clean($_POST['totalBatch']); - $total = wc_clean($_POST['total']); - $updateCount = wc_clean($_POST['updateCount']); - $from_date = wc_clean($_POST['date']); - - $func = new Ssbhesabix_Admin_Functions(); - $result = $func->syncOrders($from_date, $batch, $totalBatch, $total, $updateCount); - - if (!$result['error']) - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&orderSyncResult=true&processed=' . $result["updateCount"]); - else { - switch ($result['error']) { - case 'fiscalYearError': - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&orderSyncResult=false&fiscal=true'); - break; - case 'inputDateError': - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&orderSyncResult=false'); - break; - default: - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&orderSyncResult=true&processed=' . $updateCount); - } - } - - echo json_encode($result); - die(); - } - } -//========================================================================================================================= - /* - * Action - Ajax 'Update Products' from Hesabix/Sync tab - * @since 1.0.0 - */ - public function adminUpdateProductsCallback() - { - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - - $batch = wc_clean($_POST['batch']); - $totalBatch = wc_clean($_POST['totalBatch']); - $total = wc_clean($_POST['total']); - - $func = new Ssbhesabix_Admin_Functions(); - $result = $func->updateProductsInHesabixBasedOnStore($batch, $totalBatch, $total); - - if ($result['error']) { - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&$productUpdateResult=false'); - } else { - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&$productUpdateResult=true'); - } - echo json_encode($result); - die(); - } - } - -//========================================================================================================================= - public function adminUpdateProductsWithFilterCallback() - { - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - - $offset = wc_clean($_POST['offset']); - $rpp = wc_clean($_POST['rpp']); - if(abs($rpp-$offset) <= 200) { - $func = new Ssbhesabix_Admin_Functions(); - $result = $func->updateProductsInHesabixBasedOnStoreWithFilter($offset, $rpp); - - if ($result['error']) { - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&$productUpdateWithFilterResult=false'); - } else { - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&$productUpdateWithFilterResult=true'); - } - echo json_encode($result); - die(); - } else { - $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&$productUpdateWithFilterResult=false'); - echo json_encode($result); - die(); - } - } - } -//========================================================================================================================== - public function adminSubmitInvoiceCallback() - { - HesabixLogService::writeLogStr('Submit Invoice Manually'); - - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - - $orderId = wc_clean($_POST['orderId']); - - $func = new Ssbhesabix_Admin_Functions(); - $result = $func->setOrder($orderId); - if ($result) - $func->setOrderPayment($orderId); - - echo json_encode($result); - die(); - } - } -//========================================================================================================================= - public function adminSyncProductsManuallyCallback() - { - HesabixLogService::writeLogStr('Sync Products Manually'); - - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - - $page = wc_clean($_POST["page"]); - $rpp = wc_clean($_POST["rpp"]); - if (!$page) $page = 1; - if (!$rpp) $rpp = 10; - - if (isset($_POST["data"])) { - $data = wc_clean($_POST['data']); - $data = str_replace('\\', '', $data); - $data = json_decode($data, true); - } else { - $errors = true; - } - - $func = new Ssbhesabix_Admin_Functions(); - $res = $func->syncProductsManually($data); - if ($res["result"] == true) { - $redirect_url = admin_url("admin.php?page=hesabix-sync-products-manually&p=$page&rpp=$rpp&result=true"); - } else { - $data = implode(",", $res["data"]); - $redirect_url = admin_url("admin.php?page=hesabix-sync-products-manually&p=$page&rpp=$rpp&result=false&data=$data"); - } - echo $redirect_url; - - die(); - } - } -//========================================================================================================================= - public function adminClearPluginDataCallback() - { - - HesabixLogService::writeLogStr('Clear Plugin Data'); - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - - //Call API - $hesabixApi = new Ssbhesabix_Api(); - $result = $hesabixApi->fixClearTags(); - if (!$result->Success) { - - HesabixLogService::log(array("ssbhesabix - Cannot clear tags. Error Message: " . (string)$changes->ErrorMessage . ". Error Code: " . (string)$changes->ErrorCode)); - } - - global $wpdb; - $options = $wpdb->get_results("SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '%ssbhesabix%'"); - foreach ($options as $option) { - delete_option($option->option_name); - } - - $wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}ssbhesabix"); - - die(); - } - } -//========================================================================================================================= - public function adminInstallPluginDataCallback() - { - - HesabixLogService::writeLogStr('Install Plugin Data'); - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - - // create table and settings - require_once plugin_dir_path(__DIR__) . 'includes/class-ssbhesabix-activator.php'; - Ssbhesabix_Activator::activate(); - - die(); - } - } -//========================================================================================================================= - public function ssbhesabix_init_internal() - { - add_rewrite_rule('ssbhesabix-webhook.php$', 'index.php?ssbhesabix_webhook=1', 'top'); - //$this->checkForSyncChanges(); - } -//========================================================================================================================= - private function checkForSyncChanges() - { - $syncChangesLastDate = get_option('ssbhesabix_sync_changes_last_date'); - if (!isset($syncChangesLastDate) || $syncChangesLastDate == false) { - add_option('ssbhesabix_sync_changes_last_date', new DateTime()); - $syncChangesLastDate = new DateTime(); - } - - $nowDateTime = new DateTime(); - $diff = $nowDateTime->diff($syncChangesLastDate); - - if ($diff->i >= 3) { - HesabixLogService::writeLogStr('Sync Changes Automatically'); - update_option('ssbhesabix_sync_changes_last_date', new DateTime()); - require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-ssbhesabix-webhook.php'; - new Ssbhesabix_Webhook(); - } - } -//========================================================================================================================= - public function ssbhesabix_query_vars($query_vars) - { - $query_vars[] = 'ssbhesabix_webhook'; - return $query_vars; - } -//========================================================================================================================= - public function custom_hesabix_column_order_list($columns) - { - $reordered_columns = array(); - - foreach ($columns as $key => $column) { - $reordered_columns[$key] = $column; - if ($key == 'order_status') { - // Inserting after "Status" column - $reordered_columns['hesabix-column-invoice-number'] = __('Invoice in Hesabix', 'ssbhesabix'); - $reordered_columns['hesabix-column-submit-invoice'] = __('Submit Invoice', 'ssbhesabix'); - } - } - return $reordered_columns; - } -//========================================================================================================================= - public function custom_orders_list_column_content($column, $post_id) - { - global $wpdb; - - switch ($column) { - case 'hesabix-column-invoice-number' : - // Get custom post meta data - $row = $wpdb->get_row("SELECT `id_hesabix` FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id_ps` = $post_id AND `obj_type` = 'order'"); - - //$my_var_one = get_post_meta( $post_id, '_the_meta_key1', true ); - if (!empty($row)) - echo '' . $row->id_hesabix . ''; - else - echo ''; - break; - - case 'hesabix-column-submit-invoice' : - echo '"; - echo __('Submit Invoice', 'ssbhesabix'); - echo ''; - break; - } - } -//========================================================================================================================= - public function ssbhesabix_parse_request(&$wp) - { - if (array_key_exists('ssbhesabix_webhook', $wp->query_vars)) { - include(plugin_dir_path(__DIR__) . 'includes/ssbhesabix-webhook.php'); - exit(); - } - } -//========================================================================================================================= - public function custom_orders_list_bulk_action($actions) { - $actions['submit_invoice_in_hesabix'] = __('Submit Invoice in Hesabix', 'ssbhesabix'); - return $actions; - } -//========================================================================================================================= - public function custom_orders_list_bulk_action_run($redirect_to, $action, $post_ids) { - if ( $action !== 'submit_invoice_in_hesabix' ) - return $redirect_to; // Exit - - - HesabixLogService::writeLogStr("Submit selected orders invoice"); - - if(count($post_ids) > 10) - return $redirect_to = add_query_arg( array( - 'submit_selected_orders_invoice_in_hesabix' => '1', - 'error_msg' => 'select_max_10_items' - ), $redirect_to ); - - $success_count = 0; - $func = new Ssbhesabix_Admin_Functions(); - foreach ($post_ids as $orderId) { - $result = $func->setOrder($orderId); - if ($result) { - $success_count++; - $func->setOrderPayment($orderId); - } - } - - return $redirect_to = add_query_arg( array( - 'submit_selected_orders_invoice_in_hesabix' => '1', - 'success_count' => $success_count, - 'error_msg' => '0' - ), $redirect_to ); - } -//========================================================================================================================= - //Hooks - //Contact - public function ssbhesabix_hook_edit_user(WP_User $user) - { - $wpFaService = new HesabixWpFaService(); - $code = isset($user) ? $wpFaService->getCustomerCodeByWpId($user->ID) : ''; - ?> -
- - - - - -
-
-
- -
-
-
- getWpFaByHesabixId('customer', $user_hesabix_code); - $wpFa = $wpFaService->getWpFa('customer', $id_customer); - - if (!$wpFaOld || !$wpFa || $wpFaOld->id !== $wpFa->id) { - if ($wpFaOld) - $wpFaService->delete($wpFaOld); - - if ($wpFa) { - $wpFa->idHesabix = $user_hesabix_code; - $wpFaService->update($wpFa); - } else { - $wpFa = new WpFa(); - $wpFa->objType = 'customer'; - $wpFa->idWp = $id_customer; - $wpFa->idHesabix = intval($user_hesabix_code); - $wpFaService->save($wpFa); - } - } - } - - $function = new Ssbhesabix_Admin_Functions(); - - if(get_option('ssbhesabix_contact_automatically_save_in_hesabix') == 'yes') - $function->setContact($id_customer); - } -//========================================================================================================================= - public function ssbhesabix_hook_delete_user($id_customer) - { - $wpFaService = new HesabixWpFaService(); - $id_obj = $wpFaService->getWpFaId('customer', $id_customer); - if ($id_obj != false) { - global $wpdb; - $row = $wpdb->get_row("SELECT `id_hesabix` FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id` = $id_obj AND `obj_type` = 'customer'"); - - if (is_object($row)) { - //Call API - $hesabixApi = new Ssbhesabix_Api(); - $hesabixApi->contactDelete($row->id_hesabix); - } - - global $wpdb; - $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id_ps' => $id_customer)); - - - HesabixLogService::log(array("Customer deleted. Customer ID: $id_customer")); - } - } -//========================================================================================================================= - //Invoice - public function ssbhesabix_hook_order_status_change($id_order, $from, $to) - { - HesabixLogService::writeLogStr("Order Status Hook"); - $function = new Ssbhesabix_Admin_Functions(); - - foreach (get_option('ssbhesabix_invoice_status') as $status) { - - HesabixLogService::writeLogStr("status: $status"); - - if ($status == $to) { - $orderResult = $function->setOrder($id_order); - if ($orderResult) { - // set payment - foreach (get_option('ssbhesabix_payment_status') as $statusPayment) { - if ($statusPayment == $to) - $function->setOrderPayment($id_order); - } - } - } - } - - $values = get_option('ssbhesabix_invoice_return_status'); - if(is_array($values) || is_object($values)) { - foreach ($values as $status) { - if ($status == $to) - $function->setOrder($id_order, 2, $function->getInvoiceCodeByOrderId($id_order)); - } - } - } -//========================================================================================================================= - public function ssbhesabix_hook_payment_confirmation($id_order, $from, $to) - { - foreach (get_option('ssbhesabix_payment_status') as $status) { - if ($status == $to) { - $function = new Ssbhesabix_Admin_Functions(); - $function->setOrderPayment($id_order); - } - } - } - - //Item - private $call_time = 1; -//========================================================================================================================= - public function ssbhesabix_hook_new_product($id_product) - { - if (get_option("ssbhesabix_inside_product_edit", 0) === 1) - return; - - if ($this->call_time === 1) { - $this->call_time++; - return; - } else { - $this->call_time = 1; - } - - if (get_option("ssbhesabix_do_not_submit_product_automatically", "no") === "yes") return; - $function = new Ssbhesabix_Admin_Functions(); - $function->setItems(array($id_product)); - } -//========================================================================================================================= - public function ssbhesabix_hook_save_product_variation($id_attribute) - { - - HesabixLogService::writeLogStr("ssbhesabix_hook_save_product_variation"); - - //change hesabix item code - $variable_field_id = "ssbhesabix_hesabix_item_code_" . $id_attribute; - $code = $_POST[$variable_field_id]; - $id_product = $_POST['product_id']; - - if ($code === "") - return; - - if (isset($code)) { - global $wpdb; - $row = $wpdb->get_row("SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id_hesabix` = " . $code . " AND `obj_type` = 'product'"); - - if (is_object($row)) { - if ($row->id_ps == $id_product && $row->id_ps_attribute == $id_attribute) { - return false; - } - - echo '

' . __('The new Item code already used for another Item', 'ssbhesabix') . '

'; - - HesabixLogService::log(array("The new Item code already used for another Item. Product ID: $id_product")); - } else { - $row2 = $wpdb->get_row("SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id_ps` = $id_product AND `obj_type` = 'product' AND `id_ps_attribute` = $id_attribute"); - - if (is_object($row2)) { - $wpdb->update($wpdb->prefix . 'ssbhesabix', array( - 'id_hesabix' => (int)$code, - ), array( - 'id_ps' => $id_product, - 'id_ps_attribute' => $id_attribute, - 'obj_type' => 'product', - )); - } else if ((int)$code !== 0) { - $wpdb->insert($wpdb->prefix . 'ssbhesabix', array( - 'id_hesabix' => (int)$code, - 'id_ps' => (int)$id_product, - 'id_ps_attribute' => $id_attribute, - 'obj_type' => 'product', - )); - } - } - } - - //add attribute if not exists - $func = new Ssbhesabix_Admin_Functions(); - $wpFaService = new HesabixWpFaService(); - $code = $wpFaService->getProductCodeByWpId($id_product, $id_attribute); - if ($code == null) { - $func->setItems(array($id_product)); - } - } -//========================================================================================================================= - //ToDo: check why base product is not deleted - public function ssbhesabix_hook_delete_product($id_product) - { - - HesabixLogService::writeLogStr("Product Delete Hook"); - - $func = new Ssbhesabix_Admin_Functions(); - $wpFaService = new HesabixWpFaService(); - - $hesabixApi = new Ssbhesabix_Api(); - global $wpdb; - - $variations = $func->getProductVariations($id_product); - if ($variations != false) { - foreach ($variations as $variation) { - $id_attribute = $variation->get_id(); - $code = $wpFaService->getProductCodeByWpId($id_product, $id_attribute); - if ($code != false) { - $hesabixApi->itemDelete($code); - $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id_hesabix' => $code, 'obj_type' => 'product')); - - HesabixLogService::log(array("Product variation deleted. Product ID: $id_product-$id_attribute")); - } - } - } - - $code = $wpFaService->getProductCodeByWpId($id_product); - - if ($code != false) { - $hesabixApi->itemDelete($code); - $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id_hesabix' => $code, 'obj_type' => 'product')); - - HesabixLogService::log(array("Product deleted. Product ID: $id_product")); - } - } -//========================================================================================================================= - public function ssbhesabix_hook_delete_product_variation($id_attribute) - { -// $func = new Ssbhesabix_Admin_Functions(); - - $hesabixApi = new Ssbhesabix_Api(); - global $wpdb; - $row = $wpdb->get_row("SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id_ps_attribute` = $id_attribute AND `obj_type` = 'product'"); - - if (is_object($row)) { - $hesabixApi->itemDelete($row->id_hesabix); - - $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id' => $row->id)); - - HesabixLogService::log(array("Product variation deleted. Product ID: $row->id_ps-$id_attribute")); - } - } -//========================================================================================================================= - public function ssbhesabix_hook_product_options_general_product_data() - { - $wpFaService = new HesabixWpFaService(); - $value = isset($_GET['post']) ? $wpFaService->getProductCodeByWpId($_GET['post']) : ''; - $args = array( - 'id' => 'ssbhesabix_hesabix_item_code_0', - 'label' => __('Hesabix base item code', 'ssbhesabix'), - 'desc_tip' => true, - 'description' => __('The base Item code of this product in Hesabix, if you want to map this product to another item in Hesabix, enter the new Item code.', 'ssbhesabix'), - 'value' => $value, - 'type' => 'number', - ); - woocommerce_wp_text_input($args); - } -//========================================================================================================================= - public function ssbhesabix_hook_process_product_meta($post_id) - { - $itemCode = isset($_POST['ssbhesabix_hesabix_item_code_0']) ? $_POST['ssbhesabix_hesabix_item_code_0'] : ''; - - if ($itemCode === "") - return; - - if (isset($itemCode)) { - global $wpdb; - $row = $wpdb->get_row("SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id_hesabix` = " . $itemCode . " AND `obj_type` = 'product'"); - - if (is_object($row)) { - //ToDo: show error to customer in BO - echo '

' . __('The new Item code already used for another Item', 'ssbhesabix') . '

'; - - HesabixLogService::log(array("The new Item code already used for another Item. Product ID: $post_id")); - } else { - $row2 = $wpdb->get_row("SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id_ps` = $post_id AND `obj_type` = 'product' AND `id_ps_attribute` = 0"); - if (is_object($row2)) { - $wpdb->update($wpdb->prefix . 'ssbhesabix', array( - 'id_hesabix' => (int)$itemCode, - ), array( - 'id_ps' => $post_id, - 'id_ps_attribute' => 0, - 'obj_type' => 'product', - )); - } else if ((int)$itemCode !== 0) { - $wpdb->insert($wpdb->prefix . 'ssbhesabix', array( - 'id_hesabix' => (int)$itemCode, - 'id_ps' => (int)$post_id, - 'id_ps_attribute' => 0, - 'obj_type' => 'product', - )); - } - } - } - } -//========================================================================================================================= - public function ssbhesabix_hook_product_after_variable_attributes($loop, $variation_data, $variation) - { - $wpFaService = new HesabixWpFaService(); - $value = isset($_POST['product_id']) ? $wpFaService->getProductCodeByWpId($_POST['product_id'], $variation->ID) : ''; - $args = array( - 'id' => 'ssbhesabix_hesabix_item_code_' . $variation->ID, - 'label' => __('Hesabix variable item code', 'ssbhesabix'), - 'desc_tip' => true, - 'description' => __('The variable Item code of this product variable in Hesabix, if you want to map this product to another item in Hesabix, enter the new Item code.', 'ssbhesabix'), - 'value' => $value, - ); - woocommerce_wp_text_input($args); - } -//========================================================================================================================= - /* - * Action - Ajax 'clean log file' from Hesabix/Log tab - * @since 1.0.0 - */ - public function adminCleanLogFileCallback() - { - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - $func = new Ssbhesabix_Admin_Functions(); - $result = $func->cleanLogFile(); - - if ($result) { - $redirect_url = admin_url('admin.php?page=ssbhesabix-option&tab=log&cleanLogResult=true'); - } else { - $redirect_url = admin_url('admin.php?page=ssbhesabix-option&tab=log&cleanLogResult=false'); - } - echo $redirect_url; - - die(); - } - } -//========================================================================================================================= - // custom data tab in edit product page in admin panel - function add_hesabix_product_data_tab($product_data_tabs) - { - $product_data_tabs['hesabix'] = array( - 'label' => __('Hesabix', 'ssbhesabix'), - 'target' => 'panel_product_data_hesabix', - ); - return $product_data_tabs; - } -//========================================================================================================================= - function add_hesabix_product_data_fields() - { - global $woocommerce, $post, $product; - - $funcs = new Ssbhesabix_Admin_Functions(); - $items = array(); - $id_product = $post->ID; -// $product = new WC_Product($id_product); - $product = wc_get_product($id_product); - - if ($product->get_status() === "auto-draft") { - ?> -
- هنوز محصول ذخیره نشده است. -
- پس از ذخیره محصول، در این قسمت می توانید ارتباط محصول و متغیرهای آن با حسابیکس - را مدیریت کنید. -
- get_stock_quantity(); - $items[0]["Id"] = $id_product; - $i = 1; - - $variations = $funcs->getProductVariations($id_product); - if ($variations) { - foreach ($variations as $variation) { - $items[] = ssbhesabixItemService::mapProductVariation($product, $variation, $id_product, false); - $items[$i]["Quantity"] = $variation->get_stock_quantity(); - $items[$i]["Id"] = $variation->get_id(); - $i++; - } - } - - ?> -
- - - - - - - - - - - - - - - - - - - - - -
نام کالاکد در حسابیکسذخیره کدحذف ارتباطبروزرسانی قیمت و موجودیقیمتموجودی
" - id="hesabix-item-" style="width: 75px;" - class="hesabix-item-code" data-id="">" - class="button hesabix-item-save">" - class="button hesabix-item-delete-link">" - class="button button-primary hesabix-item-update">">">
- - - - - -
- - #hesabixID { - width: 5vw; - color: #2271b1; - } - '; - return array_slice($columns, 0, 3, true) + array('hesabixID' => 'کد حسابیکس') + array_slice($columns, 3, count($columns) - 3, true); - } -//====== - function admin_products_hesabixId_column_content( $column ){ - $funcs = new Ssbhesabix_Admin_Functions(); - $items = array(); - $id_product = get_the_ID(); -// $product = new WC_Product($id_product); - $product = wc_get_product($id_product); - - $items[] = ssbhesabixItemService::mapProduct($product, $id_product, false); - $i = 1; - - $variations = $funcs->getProductVariations($id_product); - if ($variations) { - foreach ($variations as $variation) { - $items[] = ssbhesabixItemService::mapProductVariation($product, $variation, $id_product, false); - $i++; - } - } - - echo '
'; - foreach ($items as $item) { - if ( $column == 'hesabixID' ) { - $hesabixId = $item["Code"]; - echo "" . $hesabixId . " " . ""; - } - } - echo '
'; - } -//========================================================================================================================= - function adminChangeProductCodeCallback() - { - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - - $productId = (int)wc_clean($_POST['productId']); - $attributeId = (int)wc_clean($_POST['attributeId']); - if ($productId == $attributeId) $attributeId = 0; - $code = (int)wc_clean($_POST['code']); - $result = array(); - - if (!$code) { - $result["error"] = true; - $result["message"] = "کد کالا وارد نشده است."; - echo json_encode($result); - die(); - return; - } - - $wpFaService = new HesabixWpFaService(); - $wpFa = $wpFaService->getWpFaByHesabixId('product', $code); - if ($wpFa) { - $result["error"] = true; - $result["message"] = "این کد به کالای دیگری متصل است. \n" . $wpFa->idWp . " - " . $wpFa->idWpAttribute; - echo json_encode($result); - die(); - return; - } - - $api = new Ssbhesabix_Api(); - $response = $api->itemGet($code); - if (!$response->Success) { - $result["error"] = true; - $result["message"] = "کالایی با کد وارد شده در حسابیکس پیدا نشد."; - echo json_encode($result); - die(); - return; - } - - $wpFa = $wpFaService->getWpFa('product', $productId, $attributeId); - if ($wpFa) { - $wpFa->idHesabix = $code; - $wpFaService->update($wpFa); - } else { - $wpFa = new WpFa(); - $wpFa->idHesabix = $code; - $wpFa->idWp = $productId; - $wpFa->idWpAttribute = $attributeId; - $wpFa->objType = 'product'; - $wpFaService->save($wpFa); - } - $result["error"] = false; - echo json_encode($result); - die(); - } - } -//========================================================================================================================= - function adminDeleteProductLinkCallback() - { - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - - $productId = wc_clean($_POST['productId']); - $attributeId = wc_clean($_POST['attributeId']); - if ($productId == $attributeId) $attributeId = 0; - $result = array(); - - $wpFaService = new HesabixWpFaService(); - $wpFa = $wpFaService->getWpFa('product', $productId, $attributeId); - if ($wpFa) - $wpFaService->delete($wpFa); - - $result["error"] = false; - echo json_encode($result); - die(); - } - } -//========================================================================================================================= - function adminUpdateProductCallback() - { - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - - if (get_option('ssbhesabix_item_update_price', 'no') == 'no' && - get_option('ssbhesabix_item_update_quantity', 'no') == 'no') { - $result["error"] = true; - $result["message"] = "خطا: در تنظیمات افزونه، گزینه های بروزرسانی قیمت و موجودی محصول بر اساس حسابیکس فعال نیستند."; - echo json_encode($result); - die(); - } - - $productId = wc_clean($_POST['productId']); - $attributeId = wc_clean($_POST['attributeId']); - - if (get_option('ssbhesabix_item_update_quantity', 'no') == 'yes') - update_post_meta($attributeId, '_manage_stock', 'yes'); - - if ($productId == $attributeId) $attributeId = 0; - $result = array(); - - $wpFaService = new HesabixWpFaService(); - $wpFa = $wpFaService->getWpFa('product', $productId, $attributeId); - if ($wpFa) { - - $api = new Ssbhesabix_Api(); - $warehouse = get_option('ssbhesabix_item_update_quantity_based_on', "-1"); - if ($warehouse == "-1") - $response = $api->itemGet($wpFa->idHesabix); - else { - $response = $api->itemGetQuantity($warehouse, array($wpFa->idHesabix)); - } - - if ($response->Success) { - $item = $warehouse == "-1" ? $response->Result : $response->Result[0]; - $newProps = Ssbhesabix_Admin_Functions::setItemChanges($item); - $result["error"] = false; - $result["newPrice"] = $newProps["newPrice"]; - $result["newQuantity"] = $newProps["newQuantity"]; - } else { - $result["error"] = true; - $result["message"] = "کالا در حسابیکس پیدا نشد."; - } - } - - echo json_encode($result); - die(); - } - } -//========================================================================================================================= - function adminChangeProductsCodeCallback() - { - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - $wpFaService = new HesabixWpFaService(); - - $productId = (int)wc_clean($_POST['productId']); - $itemsData = wc_clean($_POST['itemsData'], true); - $result = array(); - $codes = []; - - foreach ($itemsData as $itemData) { - $attributeId = (int)$itemData["attributeId"]; - $code = (int)$itemData["code"]; - if ($productId == $attributeId) $attributeId = 0; - $codes[] = str_pad($code, 6, "0", STR_PAD_LEFT); - - if (!$code) { - $result["error"] = true; - $result["message"] = "کد کالا وارد نشده است."; - echo json_encode($result); - die(); - return; - } - - $wpFa = $wpFaService->getWpFaByHesabixId('product', $code); - $wpFa2 = $wpFaService->getWpFa('product', $productId, $attributeId); - if ($wpFa && $wpFa2 && $wpFa->id != $wpFa2->id) { - $result["error"] = true; - $result["message"] = "این کد ($code) به کالای دیگری متصل است. \n" . $wpFa->idWp . " - " . $wpFa->idWpAttribute; - echo json_encode($result); - die(); - return; - } - } - - $api = new Ssbhesabix_Api(); - $filters = array(array("Property" => "Code", "Operator" => "in", "Value" => $codes)); - $response = $api->itemGetItems(array('Filters' => $filters)); - if ($response->Success) { - $items = $response->Result->List; - foreach ($codes as $code) { - $found = false; - foreach ($items as $item) { - if ($item->Code == $code) - $found = true; - } - if (!$found) { - $result["error"] = true; - $result["message"] = "کالایی با کد $code در حسابیکس پیدا نشد."; - echo json_encode($result); - die(); - return; - } - } - } else { - $result["error"] = true; - $result["message"] = "کالایی با کد وارد شده در حسابیکس پیدا نشد."; - echo json_encode($result); - die(); - return; - } - - - foreach ($itemsData as $itemData) { - $attributeId = (int)$itemData["attributeId"]; - $code = (int)$itemData["code"]; - if ($productId == $attributeId) $attributeId = 0; - - $wpFa = $wpFaService->getWpFa('product', $productId, $attributeId); - if ($wpFa) { - $wpFa->idHesabix = $code; - $wpFaService->update($wpFa); - } else { - $wpFa = new WpFa(); - $wpFa->idHesabix = $code; - $wpFa->idWp = $productId; - $wpFa->idWpAttribute = $attributeId; - $wpFa->objType = 'product'; - $wpFaService->save($wpFa); - } - } - - $result["error"] = false; - echo json_encode($result); - die(); - } - } -//========================================================================================================================= - function adminDeleteProductsLinkCallback() - { - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - - $productId = wc_clean($_POST['productId']); - $result = array(); - - $wpFaService = new HesabixWpFaService(); - $wpFaService->deleteAll($productId); - - $result["error"] = false; - echo json_encode($result); - die(); - } - } -//========================================================================================================================= - function adminUpdateProductAndVariationsCallback() - { - if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { - - if (get_option('ssbhesabix_item_update_price', 'no') == 'no' && - get_option('ssbhesabix_item_update_quantity', 'no') == 'no') { - $result["error"] = true; - $result["message"] = "خطا: در تنظیمات افزونه، گزینه های بروزرسانی قیمت و موجودی محصول بر اساس حسابیکس فعال نیستند."; - echo json_encode($result); - die(); - } - - //Call API - $api = new Ssbhesabix_Api(); - $wpFaService = new HesabixWpFaService(); - - $productId = wc_clean($_POST['productId']); - $productAndCombinations = $wpFaService->getProductAndCombinations($productId); - $result = array(); - if (count($productAndCombinations) == 0) { - $result["error"] = true; - $result["message"] = "هیچ ارتباطی پیدا نشد."; - echo json_encode($result); - die(); - } - $codes = []; - $ssbhesabix_item_update_quantity = get_option('ssbhesabix_item_update_quantity', 'no'); - foreach ($productAndCombinations as $p) { - $codes[] = str_pad($p->idHesabix, 6, "0", STR_PAD_LEFT); - - if ($ssbhesabix_item_update_quantity == 'yes') - update_post_meta($p->idWpAttribute == 0 ? $p->idWp : $p->idWpAttribute, '_manage_stock', 'yes'); - } - - $filters = array(array("Property" => "Code", "Operator" => "in", "Value" => $codes)); - $warehouse = get_option('ssbhesabix_item_update_quantity_based_on', "-1"); - if ($warehouse == "-1") - $response = $api->itemGetItems(array('Filters' => $filters)); - else { - $response = $api->itemGetQuantity($warehouse, $codes); - } - - if ($response->Success) { - $items = $warehouse == "-1" ? $response->Result->List : $response->Result; - $newData = []; - $result["error"] = false; - foreach ($items as $item) { - $newProps = Ssbhesabix_Admin_Functions::setItemChanges($item); - $wpFa = $wpFaService->getWpFaByHesabixId('product', $item->Code); - $newData[] = array("newPrice" => $newProps["newPrice"], - "newQuantity" => $newProps["newQuantity"], - "attributeId" => $wpFa->idWpAttribute > 0 ? $wpFa->idWpAttribute : $wpFa->idWp); - } - $result["newData"] = $newData; - } else { - $result["error"] = true; - $result["message"] = "کالایی با کد وارد شده در حسابیکس پیدا نشد."; - echo json_encode($result); - die(); - return; - } - - echo json_encode($result); - die(); - } - } -//========================================================================================================================= - function add_additional_fields_to_checkout( $fields ) { - - $NationalCode_isActive = get_option('ssbhesabix_contact_NationalCode_checkbox_hesabix'); - $EconomicCode_isActive = get_option('ssbhesabix_contact_EconomicCode_checkbox_hesabix'); - $RegistrationNumber_isActive = get_option('ssbhesabix_contact_RegistrationNumber_checkbox_hesabix'); - $Website_isActive = get_option('ssbhesabix_contact_Website_checkbox_hesabix'); - - $NationalCode_isRequired = get_option('ssbhesabix_contact_NationalCode_isRequired_hesabix'); - $EconomicCode_isRequired = get_option('ssbhesabix_contact_EconomicCode_isRequired_hesabix'); - $RegistrationNumber_isRequired = get_option('ssbhesabix_contact_RegistrationNumber_isRequired_hesabix'); - $Website_isRequired = get_option('ssbhesabix_contact_Website_isRequired_hesabix'); - - - //NationalCode - if($NationalCode_isActive == 'yes'){ - $fields['billing']['billing_hesabix_nationalcode'] = array( - 'label' => __('National code', 'ssbhesabix'), - 'placeholder' => __('please enter your National code', 'ssbhesabix'), - 'priority' => 30, - 'required' => (bool) $NationalCode_isRequired, - 'clear' => true, - 'maxlength' => 10, - ); - } - //Economic code - if($EconomicCode_isActive == 'yes'){ - $fields['billing']['billing_hesabix_economiccode'] = array( - 'label' => __('Economic code', 'ssbhesabix'), - 'placeholder' => __('please enter your Economic code', 'ssbhesabix'), - 'priority' => 31, - 'required' => (bool) $EconomicCode_isRequired, - 'clear' => true - ); - } - //Registration Number - if($RegistrationNumber_isActive == 'yes'){ - $fields['billing']['billing_hesabix_registerationnumber'] = array( - 'label' => __('Registration number', 'ssbhesabix'), - 'placeholder' => __('please enter your Registration number', 'ssbhesabix'), - 'priority' => 32, - 'required' => (bool) $RegistrationNumber_isRequired, - 'clear' => true - ); - } - //Website - if($Website_isActive == 'yes'){ - $fields['billing']['billing_hesabix_website'] = array( - 'type' => 'url', - 'label' => __('Website', 'ssbhesabix'), - 'placeholder' => __('please enter your Website address', 'ssbhesabix'), - 'priority' => 33, - 'required' => (bool) $Website_isRequired, - 'clear' => true, - ); - } - if(isset($_POST['billing_hesabix_nationalcode']) || isset($_POST['billing_hesabix_website'])) { - $func = new Ssbhesabix_Admin_Functions(); - $NationalCode = $_POST['billing_hesabix_nationalcode']; - $Website = $_POST['billing_hesabix_website']; - if($NationalCode_isRequired) { - $func->CheckNationalCode($NationalCode); - } - - if($Website_isRequired) { - $func->CheckWebsite($Website); - } - } - return $fields; - } -//========================================================================================================================= - function show_additional_fields_in_order_detail($order) { - //this function is used to show codes and website in woocommerce orders detail - $orderId = $order->get_id(); - $NationalCode = '_billing_hesabix_nationalcode'; - $EconomicCode = '_billing_hesabix_economiccode'; - $RegistrationNumber = '_billing_hesabix_registerationnumber'; - $Website = '_billing_hesabix_website'; - - $NationalCode_isActive = get_option('ssbhesabix_contact_NationalCode_checkbox_hesabix'); - $EconomicCode_isActive = get_option('ssbhesabix_contact_EconomicCode_checkbox_hesabix'); - $RegistrationNumber_isActive = get_option('ssbhesabix_contact_RegistrationNumber_checkbox_hesabix'); - $Website_isActive = get_option('ssbhesabix_contact_Website_checkbox_hesabix'); - - if($NationalCode_isActive == 'yes') { - echo '

' . __('National code', 'ssbhesabix') . ': ' .'
'. '' . get_post_meta( $orderId, $NationalCode, true ) . '

'; - } - - if($EconomicCode_isActive == 'yes') - echo '

' . __('Economic code', 'ssbhesabix') . ': ' .'
'. '' . get_post_meta( $orderId, $EconomicCode, true ) . '

'; - - if($RegistrationNumber_isActive == 'yes') - echo '

' . __('Registration number', 'ssbhesabix') . ': ' .'
'. '' . get_post_meta( $orderId, $RegistrationNumber, true ) . '

'; - - if($Website_isActive == 'yes') - echo '

' . __('Website', 'ssbhesabix') . ': ' .'
'. '' . get_post_meta( $orderId, $Website, true ) . '

'; - } -//========================================================================================================================= -} + + * @author HamidReza Gharahzadeh + * @author Sepehr Najafi + */ +class Ssbhesabix_Admin +{ + + /** + * The ID of this plugin. + * + * @since 1.0.0 + * @access private + * @var string $plugin_name The ID of this plugin. + */ + private $plugin_name; + + /** + * The version of this plugin. + * + * @since 1.0.0 + * @access private + * @var string $version The current version of this plugin. + */ + private $version; +//========================================================================================================================= + /** + * Initialize the class and set its properties. + * + * @param string $plugin_name The name of this plugin. + * @param string $version The version of this plugin. + * @since 1.0.0 + */ + public function __construct($plugin_name, $version) + { + $this->plugin_name = $plugin_name; + $this->version = $version; + $this->load_dependencies(); + } + + /** + * Check DB ver on plugin update and do necessary actions + * + * @since 1.0.7 + */ +//========================================================================================================================= + public function ssbhesabix_update_db_check() + { + $current_db_ver = get_site_option('ssbhesabix_db_version'); + if ($current_db_ver === false || $current_db_ver < 1.1) { + global $wpdb; + $table_name = $wpdb->prefix . "ssbhesabix"; + + $sql = "ALTER TABLE $table_name + ADD `id_ps_attribute` INT(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `id_ps`;"; + + if (!$wpdb->query($sql)) { + HesabixLogService::log(array("Cannot alter table $table_name. Current DB Version: $current_db_ver")); + } else { + update_option('ssbhesabix_db_version', 1.1); + HesabixLogService::log(array("Alter table $table_name. Current DB Version: $current_db_ver")); + } + } + } +//========================================================================================================================= + /** + * Register the stylesheets for the admin area. + * + * @since 1.0.0 + */ + public function enqueue_styles() + { + /** + * This function is provided for demonstration purposes only. + * + * An instance of this class should be passed to the run() function + * defined in Ssbhesabix_Loader as all of the hooks are defined + * in that particular class. + * + * The Ssbhesabix_Loader will then create the relationship + * between the defined hooks and the functions defined in this + * class. + */ + if( isset($_GET['page']) && str_contains($_GET['page'], "hesabix") ){ + wp_enqueue_style($this->plugin_name, plugin_dir_url(__FILE__) . 'css/ssbhesabix-admin.css?v=1', array(), $this->version, 'all'); + wp_enqueue_style('bootstrap_css', plugin_dir_url(__FILE__) . 'css/bootstrap.css', array(), $this->version, 'all'); + } + } +//========================================================================================================================= + /** + * Register the JavaScript for the admin area. + * + * @since 1.0.0 + */ + public function enqueue_scripts() + { + /** + * This function is provided for demonstration purposes only. + * + * An instance of this class should be passed to the run() function + * defined in Ssbhesabix_Loader as all of the hooks are defined + * in that particular class. + * + * The Ssbhesabix_Loader will then create the relationship + * between the defined hooks and the functions defined in this + * class. + */ + + wp_enqueue_script($this->plugin_name, plugin_dir_url(__FILE__) . 'js/ssbhesabix-admin.js', array('jquery'), $this->version, false); + if( isset($_GET['page']) && str_contains($_GET['page'], "hesabix") ) + wp_enqueue_script('bootstrap_js', plugin_dir_url(__FILE__) . 'js/bootstrap.bundle.min.js', array('jquery'), $this->version, false); + } +//========================================================================================================================= + private function load_dependencies() + { + /** + * The class responsible for defining all actions that occur in the Dashboard + */ + require_once plugin_dir_path(dirname(__FILE__)) . 'admin/partials/ssbhesabix-admin-display.php'; + + /** + * The class responsible for defining function for display Html element + */ + require_once plugin_dir_path(dirname(__FILE__)) . 'admin/partials/ssbhesabix-html-output.php'; + + /** + * The class responsible for defining function for display general setting tab + */ + require_once plugin_dir_path(dirname(__FILE__)) . 'admin/partials/ssbhesabix-admin-setting.php'; + + /** + * The class responsible for defining function for admin area + */ + require_once plugin_dir_path(dirname(__FILE__)) . 'admin/partials/ssbhesabix-admin-functions.php'; + } + + /** + * WC missing notice for the admin area. + * + * @since 1.0.0 + */ +//========================================================================================================================= + public function ssbhesabix_missing_notice() + { + echo '

' . sprintf(__('Hesabix Plugin requires the %s to work!', 'ssbhesabix'), '' . __('WooCommerce', 'ssbhesabix') . '') . '

'; + } + + /** + * Hesabix Plugin Live mode notice for the admin area. + * + * @since 1.0.0 + */ +//========================================================================================================================= + public function ssbhesabix_live_mode_notice() + { + echo '

' . __('Hesabix Plugin need to connect to Hesabix Accounting, Please check the API credential!', 'ssbhesabix') . '

'; + } +//========================================================================================================================= + public function ssbhesabix_business_expired_notice() + { + echo '

' . __('Cannot connect to Hesabix. Business expired.', 'ssbhesabix') . '

'; + } + + /** + * Missing hesabix default currency notice for the admin area. + * + * @since 1.0.0 + */ +//========================================================================================================================= + public function ssbhesabix_currency_notice() + { + echo '

' . __('Hesabix Plugin cannot works! because WooCommerce currency in not match with Hesabix.', 'ssbhesabix') . '

'; + } +//========================================================================================================================= + public function ssbhesabix_general_notices() { + if (!empty( $_REQUEST['submit_selected_orders_invoice_in_hesabix'])) { + if(!empty($_REQUEST['error_msg']) && $_REQUEST['error_msg'] == "select_max_10_items") { + printf( '

%s

', + __('Error: Select maximum 10 orders. Due to some limitations in Hesabix API, sending too many requests in one minute is not possible.', 'ssbhesabix')); + } else { + $success_count = intval( $_REQUEST['success_count'] ); + printf( '

%s %d

', __('Selected orders invoices have been saved. Number of saved invoices: ', 'ssbhesabix'), $success_count); + } + } + } + +//========================================================================================================================= + /* + * Action - Ajax 'export products' from Hesabix/Export tab + * @since 1.0.0 + */ + public function adminExportProductsCallback() + { + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + + $batch = wc_clean($_POST['batch']); + $totalBatch = wc_clean($_POST['totalBatch']); + $total = wc_clean($_POST['total']); + $updateCount = wc_clean($_POST['updateCount']); + + $func = new Ssbhesabix_Admin_Functions(); + $result = $func->exportProducts($batch, $totalBatch, $total, $updateCount); + + if ($result['error']) { + if ($updateCount === -1) { + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productExportResult=false&error=-1'); + } else { + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productExportResult=false'); + } + } else { + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productExportResult=true&processed=' . $result['updateCount']); + } + + echo json_encode($result); + die(); + } + } +//========================================================================================================================= + public function adminImportProductsCallback() + { + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + + $batch = wc_clean($_POST['batch']); + $totalBatch = wc_clean($_POST['totalBatch']); + $total = wc_clean($_POST['total']); + $updateCount = wc_clean($_POST['updateCount']); + + $func = new Ssbhesabix_Admin_Functions(); + $result = $func->importProducts($batch, $totalBatch, $total, $updateCount); + $import_count = $result['updateCount']; + + if ($result['error']) { + if ($import_count === -1) { + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productImportResult=false&error=-1'); + } else { + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productImportResult=false'); + } + } else { + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productImportResult=true&processed=' . $import_count); + } + + echo json_encode($result); + die(); + } + } +//========================================================================================================================= + /* + * Action - Ajax 'export products Opening Quantity' from Hesabix/Export tab + * @since 1.0.6 + */ + public function adminExportProductsOpeningQuantityCallback() + { + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + + $batch = wc_clean($_POST['batch']); + $totalBatch = wc_clean($_POST['totalBatch']); + $total = wc_clean($_POST['total']); + + $func = new Ssbhesabix_Admin_Functions(); + $result = $func->exportOpeningQuantity($batch, $totalBatch, $total); + if ($result['error']) { + if ($result['errorType'] == 'shareholderError') { + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productOpeningQuantityExportResult=false&shareholderError=true'); + } else if ($result['errorType'] == 'noProduct') { + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productOpeningQuantityExportResult=false&noProduct=true'); + } else { + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productOpeningQuantityExportResult=false'); + } + } else { + if ($result["done"] == true) + update_option('ssbhesabix_use_export_product_opening_quantity', true); + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&productOpeningQuantityExportResult=true'); + } + + echo json_encode($result); + die(); + } + } +//========================================================================================================================= + /* + * Action - Ajax 'export customers' from Hesabix/Export tab + * @since 1.0.0 + */ + public function adminExportCustomersCallback() + { + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + + $batch = wc_clean($_POST['batch']); + $totalBatch = wc_clean($_POST['totalBatch']); + $total = wc_clean($_POST['total']); + $updateCount = wc_clean($_POST['updateCount']); + + $func = new Ssbhesabix_Admin_Functions(); + $result = $func->exportCustomers($batch, $totalBatch, $total, $updateCount); + + if ($result["error"]) { + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&customerExportResult=false'); + } else { + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=export&customerExportResult=true&processed=' . $result["updateCount"]); + } + echo json_encode($result); + + die(); + } + } +//========================================================================================================================= + /* + * Action - Ajax 'Sync Changes' from Hesabix/Sync tab + * @since 1.0.0 + */ + public function adminSyncChangesCallback() + { + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + include(plugin_dir_path(__DIR__) . 'includes/class-ssbhesabix-webhook.php'); + new Ssbhesabix_Webhook(); + + $redirect_url = admin_url('admin.php?page=ssbhesabix-option&tab=sync&changesSyncResult=true'); + echo $redirect_url; + + die(); + } + } +//========================================================================================================================= + /* + * Action - Ajax 'Sync Products' from Hesabix/Sync tab + * @since 1.0.0 + */ + public function adminSyncProductsCallback() + { + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + + $batch = wc_clean($_POST['batch']); + $totalBatch = wc_clean($_POST['totalBatch']); + $total = wc_clean($_POST['total']); + + $func = new Ssbhesabix_Admin_Functions(); + $result = $func->syncProducts($batch, $totalBatch, $total); + if ($result['error']) { + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&productSyncResult=false'); + echo json_encode($result); + } else { + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&productSyncResult=true'); + echo json_encode($result); + } + die(); + } + } +//========================================================================================================================= + /* + * Action - Ajax 'Sync Orders from Hesabix/Sync tab + * @since 1.0.0 + */ + public function adminSyncOrdersCallback() + { + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + + $batch = wc_clean($_POST['batch']); + $totalBatch = wc_clean($_POST['totalBatch']); + $total = wc_clean($_POST['total']); + $updateCount = wc_clean($_POST['updateCount']); + $from_date = wc_clean($_POST['date']); + $end_date = wc_clean($_POST['endDate']); + + $func = new Ssbhesabix_Admin_Functions(); + $result = $func->syncOrders($from_date, $end_date, $batch, $totalBatch, $total, $updateCount); + + if (!$result['error']) + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&orderSyncResult=true&processed=' . $result["updateCount"]); + else { + switch ($result['error']) { + case 'fiscalYearError': + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&orderSyncResult=false&fiscal=true'); + break; + case 'inputDateError': + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&orderSyncResult=false'); + break; + default: + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&orderSyncResult=true&processed=' . $updateCount); + } + } + + echo json_encode($result); + die(); + } + } +//========================================================================================================================= + /* + * Action - Ajax 'Update Products' from Hesabix/Sync tab + * @since 1.0.0 + */ + public function adminUpdateProductsCallback() + { + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + + $batch = wc_clean($_POST['batch']); + $totalBatch = wc_clean($_POST['totalBatch']); + $total = wc_clean($_POST['total']); + + $func = new Ssbhesabix_Admin_Functions(); + $result = $func->updateProductsInHesabixBasedOnStore($batch, $totalBatch, $total); + + if ($result['error']) { + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&$productUpdateResult=false'); + } else { + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&$productUpdateResult=true'); + } + echo json_encode($result); + die(); + } + } + +//========================================================================================================================= + public function adminUpdateProductsWithFilterCallback() + { + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + + $offset = wc_clean($_POST['offset']); + $rpp = wc_clean($_POST['rpp']); + if(abs($rpp-$offset) <= 200) { + $func = new Ssbhesabix_Admin_Functions(); + $result = $func->updateProductsInHesabixBasedOnStoreWithFilter($offset, $rpp); + + if ($result['error']) { + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&$productUpdateWithFilterResult=false'); + } else { + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&$productUpdateWithFilterResult=true'); + } + echo json_encode($result); + die(); + } else { + $result["redirectUrl"] = admin_url('admin.php?page=ssbhesabix-option&tab=sync&$productUpdateWithFilterResult=false'); + echo json_encode($result); + die(); + } + } + } +//========================================================================================================================== + public function adminSubmitInvoiceCallback() + { + HesabixLogService::writeLogStr('Submit Invoice Manually'); + + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + $orderId = wc_clean($_POST['orderId']); + + $func = new Ssbhesabix_Admin_Functions(); + $result = $func->setOrder($orderId); + if ($result) + $func->setOrderPayment($orderId); + + echo json_encode($result); + die(); + } + } +//========================================================================================================================= + public function adminSyncProductsManuallyCallback() + { + HesabixLogService::writeLogStr('Sync Products Manually'); + + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + + $page = wc_clean($_POST["page"]); + $rpp = wc_clean($_POST["rpp"]); + if (!$page) $page = 1; + if (!$rpp) $rpp = 10; + + if (isset($_POST["data"])) { + $data = wc_clean($_POST['data']); + $data = str_replace('\\', '', $data); + $data = json_decode($data, true); + } else { + $errors = true; + } + + $func = new Ssbhesabix_Admin_Functions(); + $res = $func->syncProductsManually($data); + if ($res["result"] == true) { + $redirect_url = admin_url("admin.php?page=hesabix-sync-products-manually&p=$page&rpp=$rpp&result=true"); + } else { + $data = implode(",", $res["data"]); + $redirect_url = admin_url("admin.php?page=hesabix-sync-products-manually&p=$page&rpp=$rpp&result=false&data=$data"); + } + echo $redirect_url; + + die(); + } + } +//========================================================================================================================= + public function adminClearPluginDataCallback() + { + + HesabixLogService::writeLogStr('Clear Plugin Data'); + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + + //Call API + $hesabixApi = new Ssbhesabix_Api(); + $result = $hesabixApi->fixClearTags(); + if (!$result->Success) { + + HesabixLogService::log(array("ssbhesabix - Cannot clear tags. Error Message: " . (string)$result->ErrorMessage . ". Error Code: " . (string)$result->ErrorCode)); + } + + global $wpdb; + $options = $wpdb->get_results("SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '%ssbhesabix%'"); + foreach ($options as $option) { + delete_option($option->option_name); + } + + $wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}ssbhesabix"); + + die(); + } + } +//========================================================================================================================= + public function adminInstallPluginDataCallback() + { + + HesabixLogService::writeLogStr('Install Plugin Data'); + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + + // create table and settings + require_once plugin_dir_path(__DIR__) . 'includes/class-ssbhesabix-activator.php'; + Ssbhesabix_Activator::activate(); + + die(); + } + } +//========================================================================================================================= + public function admin_product_add_column( $columns ) { + $hesabixArray = array("hesabix_code" => "کد در حسابیکس"); + $columns = $hesabixArray + $columns; + return $columns; + } +//========================================================================================================================= + public function admin_product_export_rows($rows, $products) { + $rowsArray = explode("\n", $rows); + $exportRows = []; + + $reflection = new ReflectionClass($products); + $property = $reflection->getProperty('row_data'); + $property->setAccessible(true); + $productsArray = $property->getValue($products); + $matchingArray = []; + + if (!empty($productsArray)) { + foreach ($productsArray as $product) { + if (is_array($product) && isset($product['id'])) { + $wpFaService = new HesabixWpFaService(); + + if ($product["type"] == "variation") { + if(array_key_exists('parent_id', $product)) { + $parentId = $product['parent_id']; + $productParentId = explode(':', $parentId)[1]; + $wpFa = $wpFaService->getWpFaSearch($productParentId, $product['id'], '', "product"); + } + } elseif ($product["type"] == "simple" || $product["type"] == "variable") { + $wpFa = $wpFaService->getWpFaSearch($product['id'], 0, '', "product"); + } + + if (is_array($wpFa)) { + foreach ($wpFa as $item) { + if ($item->idWpAttribute != 0) { + $matchingArray[$item->idWpAttribute] = $item->idHesabix; + } else { + $matchingArray[$item->idWp] = $item->idHesabix; + } + } + } + } + } + } + + foreach ($rowsArray as $row) { + if (empty(trim($row))) { + continue; + } + $columns = str_getcsv($row); + $inserted = false; + + if (isset($columns[1])) { + foreach ($matchingArray as $wpId => $hesabixId) { + if ($columns[1] == $wpId && !$inserted) { + $columns[0] = $hesabixId; + $inserted = true; + break; + } + } + } + + if (!$inserted) { + $columns[0] = "کد ندارد"; + } + + $exportRows[] = implode(",", $columns); + } + + return implode("\n", $exportRows); + } +//========================================================================================================================= + public function ssbhesabix_init_internal() + { + add_rewrite_rule('ssbhesabix-webhook.php$', 'index.php?ssbhesabix_webhook=1', 'top'); + //$this->checkForSyncChanges(); + } +//========================================================================================================================= + private function checkForSyncChanges() + { + $syncChangesLastDate = get_option('ssbhesabix_sync_changes_last_date'); + if (!isset($syncChangesLastDate) || $syncChangesLastDate == false) { + add_option('ssbhesabix_sync_changes_last_date', new DateTime()); + $syncChangesLastDate = new DateTime(); + } + + $nowDateTime = new DateTime(); + $diff = $nowDateTime->diff($syncChangesLastDate); + + if ($diff->i >= 4) { + HesabixLogService::writeLogStr('Sync Changes Automatically'); + update_option('ssbhesabix_sync_changes_last_date', new DateTime()); + require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-ssbhesabix-webhook.php'; + new Ssbhesabix_Webhook(); + } + } +//========================================================================================================================= + public function ssbhesabix_query_vars($query_vars) + { + $query_vars[] = 'ssbhesabix_webhook'; + return $query_vars; + } +//========================================================================================================================= + public function custom_hesabix_column_order_list($columns) + { + $reordered_columns = array(); + + foreach ($columns as $key => $column) { + $reordered_columns[$key] = $column; + if ($key == 'order_status') { + // Inserting after "Status" column + $reordered_columns['hesabix-column-invoice-number'] = __('Invoice in Hesabix', 'ssbhesabix'); + $reordered_columns['hesabix-column-submit-invoice'] = __('Submit Invoice', 'ssbhesabix'); + } + } + return $reordered_columns; + } +//========================================================================================================================= + public function custom_orders_list_column_content($column, $post_id) + { + + global $wpdb; + + if (get_option('woocommerce_custom_orders_table_enabled') == 'yes') { + switch ($column) { + case 'hesabix-column-invoice-number': + $product_id = $post_id->ID; // Extract product ID from the object + // $row = $wpdb->get_row("SELECT `id_hesabix` FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id_ps` = $post_id AND `obj_type` = 'order'"); + $table_name = $wpdb->prefix . 'ssbhesabix'; + $row = $wpdb->get_row( + $wpdb->prepare( + "SELECT id_hesabix FROM $table_name WHERE id_ps = %d AND obj_type = 'order'", + $product_id + ) + ); + + if (!empty($row)) { + echo '' . $row->id_hesabix . ''; + } else { + echo ''; + } + break; + + case 'hesabix-column-submit-invoice': + // Use the product ID for the data attribute value + $product_id = $post_id->ID; + echo ''; + echo __('Submit Invoice', 'ssbhesabix'); + echo ''; + break; + } + } else { + switch ($column) { + case 'hesabix-column-invoice-number' : + // Get custom post meta data + $row = $wpdb->get_row("SELECT `id_hesabix` FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id_ps` = $post_id AND `obj_type` = 'order'"); + + //$my_var_one = get_post_meta( $post_id, '_the_meta_key1', true ); + if (!empty($row)) + echo '' . $row->id_hesabix . ''; + else + echo ''; + break; + + case 'hesabix-column-submit-invoice' : + echo '"; + echo __('Submit Invoice', 'ssbhesabix'); + echo ''; + break; + } + } + } +//========================================================================================================================= + public function ssbhesabix_parse_request(&$wp) + { + if (array_key_exists('ssbhesabix_webhook', $wp->query_vars)) { + include(plugin_dir_path(__DIR__) . 'includes/ssbhesabix-webhook.php'); + exit(); + } + } +//========================================================================================================================= + public function custom_orders_list_bulk_action($actions) { + $actions['submit_invoice_in_hesabix'] = __('Submit Invoice in Hesabix', 'ssbhesabix'); + return $actions; + } +//========================================================================================================================= + public function custom_orders_list_bulk_action_run($redirect_to, $action, $post_ids) { + if ( $action !== 'submit_invoice_in_hesabix' ) + return $redirect_to; // Exit + + + HesabixLogService::writeLogStr("Submit selected orders invoice"); + + if(count($post_ids) > 10) + return $redirect_to = add_query_arg( array( + 'submit_selected_orders_invoice_in_hesabix' => '1', + 'error_msg' => 'select_max_10_items' + ), $redirect_to ); + + $success_count = 0; + $func = new Ssbhesabix_Admin_Functions(); + foreach ($post_ids as $orderId) { + $result = $func->setOrder($orderId); + if ($result) { + $success_count++; + $func->setOrderPayment($orderId); + } + } + + return $redirect_to = add_query_arg( array( + 'submit_selected_orders_invoice_in_hesabix' => '1', + 'success_count' => $success_count, + 'error_msg' => '0' + ), $redirect_to ); + } +//========================================================================================================================= + //Hooks + //Contact + public function ssbhesabix_hook_edit_user(WP_User $user) + { + $wpFaService = new HesabixWpFaService(); + $code = isset($user) ? $wpFaService->getCustomerCodeByWpId($user->ID) : ''; + ?> +
+ + + + + +
+ +
+
+ +
+
+
+ getWpFaByHesabixId('customer', $user_hesabix_code); + $wpFa = $wpFaService->getWpFa('customer', $id_customer); + + if (!$wpFaOld || !$wpFa || $wpFaOld->id !== $wpFa->id) { + if ($wpFaOld) + $wpFaService->delete($wpFaOld); + + if ($wpFa) { + $wpFa->idHesabix = $user_hesabix_code; + $wpFaService->update($wpFa); + } else { + $wpFa = new WpFa(); + $wpFa->objType = 'customer'; + $wpFa->idWp = $id_customer; + $wpFa->idHesabix = intval($user_hesabix_code); + $wpFaService->save($wpFa); + } + } + } + + $function = new Ssbhesabix_Admin_Functions(); + + if(get_option('ssbhesabix_contact_automatically_save_in_hesabix') == 'yes') + $function->setContact($id_customer); + } +//========================================================================================================================= + public function ssbhesabix_hook_delete_user($id_customer) + { + $wpFaService = new HesabixWpFaService(); + $id_obj = $wpFaService->getWpFaId('customer', $id_customer); + if ($id_obj != false) { + global $wpdb; + $row = $wpdb->get_row("SELECT `id_hesabix` FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id` = $id_obj AND `obj_type` = 'customer'"); + + if (is_object($row)) { + $hesabixApi = new Ssbhesabix_Api(); + $hesabixApi->contactDelete($row->id_hesabix); + } + + global $wpdb; + $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id_ps' => $id_customer)); + + + HesabixLogService::log(array("Customer deleted. Customer ID: $id_customer")); + } + } +//========================================================================================================================= + //Invoice + public function ssbhesabix_hook_order_status_change($id_order, $from, $to) + { + HesabixLogService::writeLogStr("Order Status Hook"); + $function = new Ssbhesabix_Admin_Functions(); + + foreach (get_option('ssbhesabix_invoice_status') as $status) { + + HesabixLogService::writeLogStr("status: $status"); + + if ($status == $to) { + $orderResult = $function->setOrder($id_order); + if ($orderResult) { + // set payment + foreach (get_option('ssbhesabix_payment_status') as $statusPayment) { + if ($statusPayment == $to) + $function->setOrderPayment($id_order); + } + } + } + } + + $values = get_option('ssbhesabix_invoice_return_status'); + if(is_array($values) || is_object($values)) { + foreach ($values as $status) { + if ($status == $to) + $function->setOrder($id_order, 2, $function->getInvoiceCodeByOrderId($id_order)); + } + } + } +//========================================================================================================================= + public function ssbhesabix_hook_new_order($id_order, $order) + { + HesabixLogService::writeLogStr("New Order Hook"); + $function = new Ssbhesabix_Admin_Functions(); + $orderStatus = wc_get_order($id_order)->get_status(); + $orderItems = $order->get_items(); + + foreach (get_option('ssbhesabix_invoice_status') as $status) { + + HesabixLogService::writeLogStr("status: $status"); + + if ($status == $orderStatus) { + $orderResult = $function->setOrder($id_order, 0, null, $orderItems); + if ($orderResult) { + // set payment + foreach (get_option('ssbhesabix_payment_status') as $statusPayment) { + if ($statusPayment == $orderStatus) + $function->setOrderPayment($id_order); + } + } + } + } + + HesabixLogService::log(array($orderStatus)); + + $values = get_option('ssbhesabix_invoice_return_status'); + if(is_array($values) || is_object($values)) { + foreach ($values as $status) { + if ($status == $orderStatus) + $function->setOrder($id_order, 2, $function->getInvoiceCodeByOrderId($id_order), $orderItems); + } + } + } +//========================================================================================================================= + public function ssbhesabix_hook_payment_confirmation($id_order, $from, $to) + { + foreach (get_option('ssbhesabix_payment_status') as $status) { + if ($status == $to) { + $function = new Ssbhesabix_Admin_Functions(); + $function->setOrderPayment($id_order); + } + } + } + + //Item + private $call_time = 1; +//========================================================================================================================= + public function ssbhesabix_hook_new_product($id_product) + { +// if (get_option("ssbhesabix_inside_product_edit", 0) === 1) +// return; + + if ($this->call_time === 1) { + $this->call_time++; + return; + } else { + $this->call_time = 1; + } + + if (get_option("ssbhesabix_do_not_submit_product_automatically", "no") === "yes") return; + $function = new Ssbhesabix_Admin_Functions(); + $function->setItems(array($id_product)); + } +//========================================================================================================================= + public function ssbhesabix_hook_save_product_variation($id_attribute) + { + + HesabixLogService::writeLogStr("ssbhesabix_hook_save_product_variation"); + + if (get_option("ssbhesabix_do_not_submit_product_automatically", "no") === "yes" || get_option("ssbhesabix_do_not_submit_product_automatically", "no") == "1") { + //change hesabix item code + $variable_field_id = "ssbhesabix_hesabix_item_code_" . $id_attribute; + $code = $_POST[$variable_field_id]; + $id_product = $_POST['product_id']; + + if ($code === "") + return; + + if (isset($code)) { + global $wpdb; + $row = $wpdb->get_row("SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id_hesabix` = " . $code . " AND `obj_type` = 'product'"); + + if (is_object($row)) { + if ($row->id_ps == $id_product && $row->id_ps_attribute == $id_attribute) { + return false; + } + + echo '

' . __('The new Item code already used for another Item', 'ssbhesabix') . '

'; + + HesabixLogService::log(array("The new Item code already used for another Item. Product ID: $id_product")); + } else { + $row2 = $wpdb->get_row("SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id_ps` = $id_product AND `obj_type` = 'product' AND `id_ps_attribute` = $id_attribute"); + + if (is_object($row2)) { + $wpdb->update($wpdb->prefix . 'ssbhesabix', array( + 'id_hesabix' => (int)$code, + ), array( + 'id_ps' => $id_product, + 'id_ps_attribute' => $id_attribute, + 'obj_type' => 'product', + )); + } else if ((int)$code !== 0) { + $wpdb->insert($wpdb->prefix . 'ssbhesabix', array( + 'id_hesabix' => (int)$code, + 'id_ps' => (int)$id_product, + 'id_ps_attribute' => $id_attribute, + 'obj_type' => 'product', + )); + } + } + } + + //add attribute if not exists + $func = new Ssbhesabix_Admin_Functions(); + $wpFaService = new HesabixWpFaService(); + $code = $wpFaService->getProductCodeByWpId($id_product, $id_attribute); + if ($code == null) { + $func->setItems(array($id_product)); + } + } + } +//========================================================================================================================= + //ToDo: check why base product is not deleted + public function ssbhesabix_hook_delete_product($id_product) + { + + HesabixLogService::writeLogStr("Product Delete Hook"); + + $func = new Ssbhesabix_Admin_Functions(); + $wpFaService = new HesabixWpFaService(); + + $hesabixApi = new Ssbhesabix_Api(); + global $wpdb; + + $variations = $func->getProductVariations($id_product); + if ($variations != false) { + foreach ($variations as $variation) { + $id_attribute = $variation->get_id(); + $code = $wpFaService->getProductCodeByWpId($id_product, $id_attribute); + if ($code != false) { + $hesabixApi->itemDelete($code); + $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id_hesabix' => $code, 'obj_type' => 'product')); + + HesabixLogService::log(array("Product variation deleted. Product ID: $id_product-$id_attribute")); + } + } + } + + $code = $wpFaService->getProductCodeByWpId($id_product); + + if ($code != false) { + $hesabixApi->itemDelete($code); + $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id_hesabix' => $code, 'obj_type' => 'product')); + + HesabixLogService::log(array("Product deleted. Product ID: $id_product")); + } + } +//========================================================================================================================= + public function ssbhesabix_hook_delete_product_variation($id_attribute) + { +// $func = new Ssbhesabix_Admin_Functions(); + + $hesabixApi = new Ssbhesabix_Api(); + global $wpdb; + $row = $wpdb->get_row("SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id_ps_attribute` = $id_attribute AND `obj_type` = 'product'"); + + if (is_object($row)) { + $hesabixApi->itemDelete($row->id_hesabix); + + $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id' => $row->id)); + + HesabixLogService::log(array("Product variation deleted. Product ID: $row->id_ps-$id_attribute")); + } + } +//========================================================================================================================= + public function ssbhesabix_hook_product_options_general_product_data() + { + $wpFaService = new HesabixWpFaService(); + $value = isset($_GET['post']) ? $wpFaService->getProductCodeByWpId($_GET['post']) : ''; + $args = array( + 'id' => 'ssbhesabix_hesabix_item_code_0', + 'label' => __('Hesabix base item code', 'ssbhesabix'), + 'desc_tip' => true, + 'description' => __('The base Item code of this product in Hesabix, if you want to map this product to another item in Hesabix, enter the new Item code.', 'ssbhesabix'), + 'value' => $value, + 'type' => 'number', + ); + woocommerce_wp_text_input($args); + } +//========================================================================================================================= + public function ssbhesabix_hook_process_product_meta($post_id) + { + $itemCode = isset($_POST['ssbhesabix_hesabix_item_code_0']) ? $_POST['ssbhesabix_hesabix_item_code_0'] : ''; + + if ($itemCode === "") + return; + + if (isset($itemCode)) { + global $wpdb; + $row = $wpdb->get_row("SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id_hesabix` = " . $itemCode . " AND `obj_type` = 'product'"); + + if (is_object($row)) { + //ToDo: show error to customer in BO + echo '

' . __('The new Item code already used for another Item', 'ssbhesabix') . '

'; + + HesabixLogService::log(array("The new Item code already used for another Item. Product ID: $post_id")); + } else { + $row2 = $wpdb->get_row("SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id_ps` = $post_id AND `obj_type` = 'product' AND `id_ps_attribute` = 0"); + if (is_object($row2)) { + $wpdb->update($wpdb->prefix . 'ssbhesabix', array( + 'id_hesabix' => (int)$itemCode, + ), array( + 'id_ps' => $post_id, + 'id_ps_attribute' => 0, + 'obj_type' => 'product', + )); + } else if ((int)$itemCode !== 0) { + $wpdb->insert($wpdb->prefix . 'ssbhesabix', array( + 'id_hesabix' => (int)$itemCode, + 'id_ps' => (int)$post_id, + 'id_ps_attribute' => 0, + 'obj_type' => 'product', + )); + } + } + } + } +//========================================================================================================================= + public function ssbhesabix_hook_product_after_variable_attributes($loop, $variation_data, $variation) + { + $wpFaService = new HesabixWpFaService(); + $value = isset($_POST['product_id']) ? $wpFaService->getProductCodeByWpId($_POST['product_id'], $variation->ID) : ''; + $args = array( + 'id' => 'ssbhesabix_hesabix_item_code_' . $variation->ID, + 'label' => __('Hesabix variable item code', 'ssbhesabix'), + 'desc_tip' => true, + 'description' => __('The variable Item code of this product variable in Hesabix, if you want to map this product to another item in Hesabix, enter the new Item code.', 'ssbhesabix'), + 'value' => $value, + ); + woocommerce_wp_text_input($args); + } +//========================================================================================================================= + /* + * Action - Ajax 'clean log file' from Hesabix/Log tab + * @since 1.0.0 + */ + public function adminCleanLogFileCallback() + { + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + $func = new Ssbhesabix_Admin_Functions(); + $result = $func->cleanLogFile(); + + if ($result) { + $redirect_url = admin_url('admin.php?page=ssbhesabix-option&tab=log&cleanLogResult=true'); + } else { + $redirect_url = admin_url('admin.php?page=ssbhesabix-option&tab=log&cleanLogResult=false'); + } + echo $redirect_url; + + die(); + } + } +//========================================================================================================================= + // custom data tab in edit product page in admin panel + function add_hesabix_product_data_tab($product_data_tabs) + { + $product_data_tabs['hesabix'] = array( + 'label' => __('Hesabix', 'ssbhesabix'), + 'target' => 'panel_product_data_hesabix', + ); + return $product_data_tabs; + } +//========================================================================================================================= + function add_hesabix_product_data_fields() + { + global $woocommerce, $post, $product; + + $funcs = new Ssbhesabix_Admin_Functions(); + $items = array(); + $id_product = $post->ID; +// $product = new WC_Product($id_product); + $product = wc_get_product($id_product); + + if ($product->get_status() === "auto-draft") { + ?> +
+ هنوز محصول ذخیره نشده است. +
+ پس از ذخیره محصول، در این قسمت می توانید ارتباط محصول و متغیرهای آن با حسابیکس + را مدیریت کنید. +
+ get_stock_quantity(); + $items[0]["Id"] = $id_product; + $i = 1; + + $variations = $funcs->getProductVariations($id_product); + if ($variations) { + foreach ($variations as $variation) { + $items[] = ssbhesabixItemService::mapProductVariation($product, $variation, $id_product, false); + $items[$i]["Quantity"] = $variation->get_stock_quantity(); + $items[$i]["Id"] = $variation->get_id(); + $i++; + } + } + + ?> +
+ + + + + + + + + + + + + + + + + + + + + +
نام کالاکد در حسابیکسذخیره کدحذف ارتباطبروزرسانی قیمت و موجودیقیمتموجودی
" + id="hesabix-item-" style="width: 75px;" + class="hesabix-item-code" data-id="">" + class="button hesabix-item-save">" + class="button hesabix-item-delete-link">" + class="button button-primary hesabix-item-update">">">
+ + + + + +
+ + #hesabixID { + width: 5vw; + color: #2271b1; + } + '; + return array_slice($columns, 0, 3, true) + array('hesabixID' => 'کد حسابیکس') + array_slice($columns, 3, count($columns) - 3, true); + } +//====== + function admin_products_hesabixId_column_content( $column ){ + $funcs = new Ssbhesabix_Admin_Functions(); + $items = array(); + $id_product = get_the_ID(); +// $product = new WC_Product($id_product); + $product = wc_get_product($id_product); + + $items[] = ssbhesabixItemService::mapProduct($product, $id_product, false); + $i = 1; + + $variations = $funcs->getProductVariations($id_product); + if ($variations) { + foreach ($variations as $variation) { + $items[] = ssbhesabixItemService::mapProductVariation($product, $variation, $id_product, false); + $i++; + } + } + + echo '
'; + foreach ($items as $item) { + if ( $column == 'hesabixID' ) { + $hesabixId = $item["Code"]; + echo "" . $hesabixId . " " . ""; + } + } + echo '
'; + } +//========================================================================================================================= + function adminChangeProductCodeCallback() + { + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + + $productId = (int)wc_clean($_POST['productId']); + $attributeId = (int)wc_clean($_POST['attributeId']); + if ($productId == $attributeId) $attributeId = 0; + $code = (int)wc_clean($_POST['code']); + $result = array(); + + if (!$code) { + $result["error"] = true; + $result["message"] = "کد کالا وارد نشده است."; + echo json_encode($result); + die(); + return; + } + + $wpFaService = new HesabixWpFaService(); + $wpFa = $wpFaService->getWpFaByHesabixId('product', $code); + if ($wpFa) { + $result["error"] = true; + $result["message"] = "این کد به کالای دیگری متصل است. \n" . $wpFa->idWp . " - " . $wpFa->idWpAttribute; + echo json_encode($result); + die(); + return; + } + + $api = new Ssbhesabix_Api(); + $response = $api->itemGet($code); + if (!$response->Success) { + $result["error"] = true; + $result["message"] = "کالایی با کد وارد شده در حسابیکس پیدا نشد."; + echo json_encode($result); + die(); + return; + } + + $wpFa = $wpFaService->getWpFa('product', $productId, $attributeId); + if ($wpFa) { + $wpFa->idHesabix = $code; + $wpFaService->update($wpFa); + } else { + $wpFa = new WpFa(); + $wpFa->idHesabix = $code; + $wpFa->idWp = $productId; + $wpFa->idWpAttribute = $attributeId; + $wpFa->objType = 'product'; + $wpFaService->save($wpFa); + } + $result["error"] = false; + echo json_encode($result); + die(); + } + } +//========================================================================================================================= + function adminDeleteProductLinkCallback() + { + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + $productId = wc_clean($_POST['productId']); + $attributeId = wc_clean($_POST['attributeId']); + if ($productId == $attributeId) $attributeId = 0; + $result = array(); + + $wpFaService = new HesabixWpFaService(); + $wpFa = $wpFaService->getWpFa('product', $productId, $attributeId); + if ($wpFa) { + $wpFaService->delete($wpFa); + HesabixLogService::writeLogStr("حذف ارتباط کالا. کد کالا: " . $productId . " - ". "کد متغیر:". $attributeId); + } + + $result["error"] = false; + echo json_encode($result); + die(); + } + } +//========================================================================================================================= + function adminUpdateProductCallback() + { + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + + if (get_option('ssbhesabix_item_update_price', 'no') == 'no' && + get_option('ssbhesabix_item_update_quantity', 'no') == 'no') { + $result["error"] = true; + $result["message"] = "خطا: در تنظیمات افزونه، گزینه های بروزرسانی قیمت و موجودی محصول بر اساس حسابیکس فعال نیستند."; + echo json_encode($result); + die(); + } + + $productId = wc_clean($_POST['productId']); + $attributeId = wc_clean($_POST['attributeId']); + + if (get_option('ssbhesabix_item_update_quantity', 'no') == 'yes') + update_post_meta($attributeId, '_manage_stock', 'yes'); + + if ($productId == $attributeId) $attributeId = 0; + $result = array(); + + $wpFaService = new HesabixWpFaService(); + $wpFa = $wpFaService->getWpFa('product', $productId, $attributeId); + if ($wpFa) { + + $api = new Ssbhesabix_Api(); + $warehouse = get_option('ssbhesabix_item_update_quantity_based_on', "-1"); + if ($warehouse == "-1") + $response = $api->itemGet($wpFa->idHesabix); + else { + $response = $api->itemGetQuantity($warehouse, array($wpFa->idHesabix)); + } + + if ($response->Success) { + $item = $warehouse == "-1" ? $response->Result : $response->Result[0]; + $newProps = Ssbhesabix_Admin_Functions::setItemChanges($item); + $result["error"] = false; + $result["newPrice"] = $newProps["newPrice"]; + $result["newQuantity"] = $newProps["newQuantity"]; + } else { + $result["error"] = true; + $result["message"] = "کالا در حسابیکس پیدا نشد."; + } + } + + echo json_encode($result); + die(); + } + } +//========================================================================================================================= + function adminChangeProductsCodeCallback() + { + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + $wpFaService = new HesabixWpFaService(); + + $productId = (int)wc_clean($_POST['productId']); + $itemsData = wc_clean($_POST['itemsData'], true); + $result = array(); + $codes = []; + + foreach ($itemsData as $itemData) { + $attributeId = (int)$itemData["attributeId"]; + $code = (int)$itemData["code"]; + if ($productId == $attributeId) $attributeId = 0; + $codes[] = str_pad($code, 6, "0", STR_PAD_LEFT); + + if (!$code) { + $result["error"] = true; + $result["message"] = "کد کالا وارد نشده است."; + echo json_encode($result); + die(); + return; + } + + $wpFa = $wpFaService->getWpFaByHesabixId('product', $code); + $wpFa2 = $wpFaService->getWpFa('product', $productId, $attributeId); + if ($wpFa && $wpFa2 && $wpFa->id != $wpFa2->id) { + $result["error"] = true; + $result["message"] = "این کد ($code) به کالای دیگری متصل است. \n" . $wpFa->idWp . " - " . $wpFa->idWpAttribute; + echo json_encode($result); + die(); + return; + } + } + + $api = new Ssbhesabix_Api(); + $response = $api->itemGetItemsByCodes(array('values' => $codes)); + if ($response->Success) { + $items = $response->result; + foreach ($codes as $code) { + $found = false; + foreach ($items as $item) { + if ($item->code == $code) + $found = true; + } + if (!$found) { + $result["error"] = true; + $result["message"] = "کالایی با کد $code در حسابیکس پیدا نشد."; + echo json_encode($result); + die(); + return; + } + } + } else { + $result["error"] = true; + $result["message"] = "کالایی با کد وارد شده در حسابیکس پیدا نشد."; + echo json_encode($result); + die(); + return; + } + + + foreach ($itemsData as $itemData) { + $attributeId = (int)$itemData["attributeId"]; + $code = (int)$itemData["code"]; + if ($productId == $attributeId) $attributeId = 0; + + $wpFa = $wpFaService->getWpFa('product', $productId, $attributeId); + if ($wpFa) { + $wpFa->idHesabix = $code; + $wpFaService->update($wpFa); + } else { + $wpFa = new WpFa(); + $wpFa->idHesabix = $code; + $wpFa->idWp = $productId; + $wpFa->idWpAttribute = $attributeId; + $wpFa->objType = 'product'; + $wpFaService->save($wpFa); + } + } + + $result["error"] = false; + echo json_encode($result); + die(); + } + } +//========================================================================================================================= + function adminDeleteProductsLinkCallback() + { + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + + $productId = wc_clean($_POST['productId']); + $result = array(); + + $wpFaService = new HesabixWpFaService(); + $wpFaService->deleteAll($productId); + HesabixLogService::writeLogStr("حذف ارتباط کالاها. کد کالا: " . $productId); + + $result["error"] = false; + echo json_encode($result); + die(); + } + } +//========================================================================================================================= + function adminUpdateProductAndVariationsCallback() + { + if (is_admin() && (defined('DOING_AJAX') || DOING_AJAX)) { + + if (get_option('ssbhesabix_item_update_price', 'no') == 'no' && + get_option('ssbhesabix_item_update_quantity', 'no') == 'no') { + $result["error"] = true; + $result["message"] = "خطا: در تنظیمات افزونه، گزینه های بروزرسانی قیمت و موجودی محصول بر اساس حسابیکس فعال نیستند."; + echo json_encode($result); + die(); + } + + //Call API + $api = new Ssbhesabix_Api(); + $wpFaService = new HesabixWpFaService(); + + $productId = wc_clean($_POST['productId']); + $productAndCombinations = $wpFaService->getProductAndCombinations($productId); + $result = array(); + if (count($productAndCombinations) == 0) { + $result["error"] = true; + $result["message"] = "هیچ ارتباطی پیدا نشد."; + echo json_encode($result); + die(); + } + $codes = []; + $ssbhesabix_item_update_quantity = get_option('ssbhesabix_item_update_quantity', 'no'); + foreach ($productAndCombinations as $p) { + $codes[] = str_pad($p->idHesabix, 6, "0", STR_PAD_LEFT); + + if ($ssbhesabix_item_update_quantity == 'yes') + update_post_meta($p->idWpAttribute == 0 ? $p->idWp : $p->idWpAttribute, '_manage_stock', 'yes'); + } + + $warehouse = get_option('ssbhesabix_item_update_quantity_based_on', "-1"); + if ($warehouse == "-1") + $response = $api->itemGetItemsByCodes($codes); + else { + $response = $api->itemGetQuantity($warehouse, $codes); + } + + if ($response->Success) { + $items = $warehouse == "-1" ? $response->Result->List : $response->Result; + $newData = []; + $result["error"] = false; + foreach ($items as $item) { + $newProps = Ssbhesabix_Admin_Functions::setItemChanges($item); + $wpFa = $wpFaService->getWpFaByHesabixId('product', $item->Code); + $newData[] = array("newPrice" => $newProps["newPrice"], + "newQuantity" => $newProps["newQuantity"], + "attributeId" => $wpFa->idWpAttribute > 0 ? $wpFa->idWpAttribute : $wpFa->idWp); + } + $result["newData"] = $newData; + } else { + $result["error"] = true; + $result["message"] = "کالایی با کد وارد شده در حسابیکس پیدا نشد."; + echo json_encode($result); + die(); + return; + } + + echo json_encode($result); + die(); + } + } +//========================================================================================================================= + function add_additional_fields_to_checkout( $fields ) { + $NationalCode_isActive = get_option('ssbhesabix_contact_NationalCode_checkbox_hesabix'); + $EconomicCode_isActive = get_option('ssbhesabix_contact_EconomicCode_checkbox_hesabix'); + $RegistrationNumber_isActive = get_option('ssbhesabix_contact_RegistrationNumber_checkbox_hesabix'); + $Website_isActive = get_option('ssbhesabix_contact_Website_checkbox_hesabix'); + + $NationalCode_isRequired = get_option('ssbhesabix_contact_NationalCode_isRequired_hesabix'); + $EconomicCode_isRequired = get_option('ssbhesabix_contact_EconomicCode_isRequired_hesabix'); + $RegistrationNumber_isRequired = get_option('ssbhesabix_contact_RegistrationNumber_isRequired_hesabix'); + $Website_isRequired = get_option('ssbhesabix_contact_Website_isRequired_hesabix'); + + //NationalCode + if($NationalCode_isActive == 'yes'){ + $fields['billing']['billing_hesabix_nationalcode'] = array( + 'label' => __('National code', 'ssbhesabix'), + 'placeholder' => __('please enter your National code', 'ssbhesabix'), + 'priority' => 30, + 'required' => (bool) $NationalCode_isRequired, + 'clear' => true, + 'maxlength' => 10, + ); + } + //Economic code + if($EconomicCode_isActive == 'yes'){ + $fields['billing']['billing_hesabix_economiccode'] = array( + 'label' => __('Economic code', 'ssbhesabix'), + 'placeholder' => __('please enter your Economic code', 'ssbhesabix'), + 'priority' => 31, + 'required' => (bool) $EconomicCode_isRequired, + 'clear' => true + ); + } + //Registration Number + if($RegistrationNumber_isActive == 'yes'){ + $fields['billing']['billing_hesabix_registerationnumber'] = array( + 'label' => __('Registration number', 'ssbhesabix'), + 'placeholder' => __('please enter your Registration number', 'ssbhesabix'), + 'priority' => 32, + 'required' => (bool) $RegistrationNumber_isRequired, + 'clear' => true + ); + } + //Website + if($Website_isActive == 'yes'){ + $fields['billing']['billing_hesabix_website'] = array( + 'type' => 'url', + 'label' => __('Website', 'ssbhesabix'), + 'placeholder' => __('please enter your Website address', 'ssbhesabix'), + 'priority' => 33, + 'required' => (bool) $Website_isRequired, + 'clear' => true, + ); + } + if(isset($_POST['billing_hesabix_nationalcode']) || isset($_POST['billing_hesabix_website'])) { + $func = new Ssbhesabix_Admin_Functions(); + $NationalCode = $_POST['billing_hesabix_nationalcode']; + $Website = $_POST['billing_hesabix_website']; + if($NationalCode_isRequired) { + $func->checkNationalCode($NationalCode); + } + + if($Website_isRequired) { + $func->checkWebsite($Website); + } + } + return $fields; + } +//========================================================================================================================= + function show_additional_fields_in_order_detail($order) { + //this function is used to show codes and website in woocommerce orders detail + $orderId = $order->get_id(); + $NationalCode = '_billing_hesabix_nationalcode'; + $EconomicCode = '_billing_hesabix_economiccode'; + $RegistrationNumber = '_billing_hesabix_registerationnumber'; + $Website = '_billing_hesabix_website'; + + $NationalCode_isActive = get_option('ssbhesabix_contact_NationalCode_checkbox_hesabix'); + $EconomicCode_isActive = get_option('ssbhesabix_contact_EconomicCode_checkbox_hesabix'); + $RegistrationNumber_isActive = get_option('ssbhesabix_contact_RegistrationNumber_checkbox_hesabix'); + $Website_isActive = get_option('ssbhesabix_contact_Website_checkbox_hesabix'); + + if($NationalCode_isActive == 'yes') { + echo '

' . __('National code', 'ssbhesabix') . ': ' .'
'. '' . get_post_meta( $orderId, $NationalCode, true ) . '

'; + } + + if($EconomicCode_isActive == 'yes') + echo '

' . __('Economic code', 'ssbhesabix') . ': ' .'
'. '' . get_post_meta( $orderId, $EconomicCode, true ) . '

'; + + if($RegistrationNumber_isActive == 'yes') + echo '

' . __('Registration number', 'ssbhesabix') . ': ' .'
'. '' . get_post_meta( $orderId, $RegistrationNumber, true ) . '

'; + + if($Website_isActive == 'yes') + echo '

' . __('Website', 'ssbhesabix') . ': ' .'
'. '' . get_post_meta( $orderId, $Website, true ) . '

'; + } +//========================================================================================================================= +} diff --git a/admin/css/bootstrap.css b/admin/css/bootstrap.css index 00bfac5..8e6adc8 100644 --- a/admin/css/bootstrap.css +++ b/admin/css/bootstrap.css @@ -1,10790 +1,10790 @@ -@charset "UTF-8"; -/*! - * Bootstrap v5.0.1 (https://getbootstrap.com/) - * Copyright 2011-2021 The Bootstrap Authors - * Copyright 2011-2021 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */ -:root { - --bs-blue: #0d6efd; - --bs-indigo: #6610f2; - --bs-purple: #6f42c1; - --bs-pink: #d63384; - --bs-red: #dc3545; - --bs-orange: #fd7e14; - --bs-yellow: #ffc107; - --bs-green: #198754; - --bs-teal: #20c997; - --bs-cyan: #0dcaf0; - --bs-white: #fff; - --bs-gray: #6c757d; - --bs-gray-dark: #343a40; - --bs-primary: #0d6efd; - --bs-secondary: #6c757d; - --bs-success: #198754; - --bs-info: #0dcaf0; - --bs-warning: #ffc107; - --bs-danger: #dc3545; - --bs-light: #f8f9fa; - --bs-dark: #212529; - --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); -} - -@media (prefers-reduced-motion: no-preference) { - :root { - scroll-behavior: smooth; - } -} - -.h6, .h5, .h4, .h3, .h2, .h1 { - margin-top: 0; - margin-bottom: 0.5rem; - font-weight: 500; - line-height: 1.2; -} - -.h1 { - font-size: calc(1.375rem + 1.5vw); -} -@media (min-width: 1200px) { - .h1 { - font-size: 2.5rem; - } -} - -.h2 { - font-size: calc(1.325rem + 0.9vw); -} -@media (min-width: 1200px) { - .h2 { - font-size: 2rem; - } -} - -.h3 { - font-size: calc(1.3rem + 0.6vw); -} -@media (min-width: 1200px) { - .h3 { - font-size: 1.75rem; - } -} - -.h4 { - font-size: calc(1.275rem + 0.3vw); -} -@media (min-width: 1200px) { - .h4 { - font-size: 1.5rem; - } -} - -.h5 { - font-size: 1.25rem; -} - -.h6 { - font-size: 1rem; -} - -.p { - margin-top: 0; - margin-bottom: 1rem; -} - - -abbr[title], -abbr[data-bs-original-title] { - -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; - cursor: help; - -webkit-text-decoration-skip-ink: none; - text-decoration-skip-ink: none; -} - -address { - margin-bottom: 1rem; - font-style: normal; - line-height: inherit; -} - -ol, -ul { - padding-left: 2rem; -} - -ol, -ul, -dl { - margin-top: 0; - margin-bottom: 1rem; -} - -ol ol, -ul ul, -ol ul, -ul ol { - margin-bottom: 0; -} - -dt { - font-weight: 700; -} - -dd { - margin-bottom: 0.5rem; - margin-left: 0; -} - -blockquote { - margin: 0 0 1rem; -} - -b, -strong { - font-weight: bolder; -} - -small, .small { - font-size: 0.875em; -} - -mark, .mark { - padding: 0.2em; - background-color: #fcf8e3; -} - -sub, -sup { - position: relative; - font-size: 0.75em; - line-height: 0; - vertical-align: baseline; -} - -sub { - bottom: -0.25em; -} - -sup { - top: -0.5em; -} - -a { - color: #0d6efd; - text-decoration: underline; -} -a:hover { - color: #0a58ca; -} - -a:not([href]):not([class]), a:not([href]):not([class]):hover { - color: inherit; - text-decoration: none; -} - -pre, -code, -kbd, -samp { - font-family: var(--bs-font-monospace); - font-size: 1em; - direction: ltr /* rtl:ignore */; - unicode-bidi: bidi-override; -} - -pre { - display: block; - margin-top: 0; - margin-bottom: 1rem; - overflow: auto; - font-size: 0.875em; -} -pre code { - font-size: inherit; - color: inherit; - word-break: normal; -} - -code { - font-size: 0.875em; - color: #d63384; - word-wrap: break-word; -} -a > code { - color: inherit; -} - -kbd { - padding: 0.2rem 0.4rem; - font-size: 0.875em; - color: #fff; - background-color: #212529; - border-radius: 0.2rem; -} -kbd kbd { - padding: 0; - font-size: 1em; - font-weight: 700; -} - -figure { - margin: 0 0 1rem; -} - -img, -svg { - vertical-align: middle; -} - -table { - caption-side: bottom; - border-collapse: collapse; -} - -caption { - padding-top: 0.5rem; - padding-bottom: 0.5rem; - color: #6c757d; - text-align: left; -} - -th { - text-align: inherit; - text-align: -webkit-match-parent; -} - -thead, -tbody, -tfoot, -tr, -td, -th { - border-color: inherit; - border-style: solid; - border-width: 0; -} - -label { - display: inline-block; -} - -button { - border-radius: 0; -} - -button:focus:not(:focus-visible) { - outline: 0; -} - -input, -button, -select, -optgroup, -textarea { - margin: 0; - font-family: inherit; - font-size: inherit; - line-height: inherit; -} - -button, -select { - text-transform: none; -} - -[role=button] { - cursor: pointer; -} - -select { - word-wrap: normal; -} -select:disabled { - opacity: 1; -} - -[list]::-webkit-calendar-picker-indicator { - display: none; -} - -button, -[type=button], -[type=reset], -[type=submit] { - -webkit-appearance: button; -} -button:not(:disabled), -[type=button]:not(:disabled), -[type=reset]:not(:disabled), -[type=submit]:not(:disabled) { - cursor: pointer; -} - -::-moz-focus-inner { - padding: 0; - border-style: none; -} - -textarea { - resize: vertical; -} - -fieldset { - min-width: 0; - padding: 0; - margin: 0; - border: 0; -} - -legend { - float: left; - width: 100%; - padding: 0; - margin-bottom: 0.5rem; - font-size: calc(1.275rem + 0.3vw); - line-height: inherit; -} -@media (min-width: 1200px) { - legend { - font-size: 1.5rem; - } -} -legend + * { - clear: left; -} - -::-webkit-datetime-edit-fields-wrapper, -::-webkit-datetime-edit-text, -::-webkit-datetime-edit-minute, -::-webkit-datetime-edit-hour-field, -::-webkit-datetime-edit-day-field, -::-webkit-datetime-edit-month-field, -::-webkit-datetime-edit-year-field { - padding: 0; -} - -::-webkit-inner-spin-button { - height: auto; -} - -[type=search] { - outline-offset: -2px; - -webkit-appearance: textfield; -} - -/* rtl:raw: -[type="tel"], -[type="url"], -[type="email"], -[type="number"] { - direction: ltr; -} -*/ -::-webkit-search-decoration { - -webkit-appearance: none; -} - -::-webkit-color-swatch-wrapper { - padding: 0; -} - -::file-selector-button { - font: inherit; -} - -::-webkit-file-upload-button { - font: inherit; - -webkit-appearance: button; -} - -output { - display: inline-block; -} - -iframe { - border: 0; -} - -summary { - display: list-item; - cursor: pointer; -} - -progress { - vertical-align: baseline; -} - -[hidden] { - display: none !important; -} - -.lead { - font-size: 1.25rem; - font-weight: 300; -} - -.display-1 { - font-size: calc(1.625rem + 4.5vw); - font-weight: 300; - line-height: 1.2; -} -@media (min-width: 1200px) { - .display-1 { - font-size: 5rem; - } -} - -.display-2 { - font-size: calc(1.575rem + 3.9vw); - font-weight: 300; - line-height: 1.2; -} -@media (min-width: 1200px) { - .display-2 { - font-size: 4.5rem; - } -} - -.display-3 { - font-size: calc(1.525rem + 3.3vw); - font-weight: 300; - line-height: 1.2; -} -@media (min-width: 1200px) { - .display-3 { - font-size: 4rem; - } -} - -.display-4 { - font-size: calc(1.475rem + 2.7vw); - font-weight: 300; - line-height: 1.2; -} -@media (min-width: 1200px) { - .display-4 { - font-size: 3.5rem; - } -} - -.display-5 { - font-size: calc(1.425rem + 2.1vw); - font-weight: 300; - line-height: 1.2; -} -@media (min-width: 1200px) { - .display-5 { - font-size: 3rem; - } -} - -.display-6 { - font-size: calc(1.375rem + 1.5vw); - font-weight: 300; - line-height: 1.2; -} -@media (min-width: 1200px) { - .display-6 { - font-size: 2.5rem; - } -} - -.list-unstyled { - padding-left: 0; - list-style: none; -} - -.list-inline { - padding-left: 0; - list-style: none; -} - -.list-inline-item { - display: inline-block; -} -.list-inline-item:not(:last-child) { - margin-right: 0.5rem; -} - -.initialism { - font-size: 0.875em; - text-transform: uppercase; -} - -.blockquote { - margin-bottom: 1rem; - font-size: 1.25rem; -} -.blockquote > :last-child { - margin-bottom: 0; -} - -.blockquote-footer { - margin-top: -1rem; - margin-bottom: 1rem; - font-size: 0.875em; - color: #6c757d; -} -.blockquote-footer::before { - content: "— "; -} - -.img-fluid { - max-width: 100%; - height: auto; -} - -.img-thumbnail { - padding: 0.25rem; - background-color: #fff; - border: 1px solid #dee2e6; - border-radius: 0.25rem; - max-width: 100%; - height: auto; -} - -.figure { - display: inline-block; -} - -.figure-img { - margin-bottom: 0.5rem; - line-height: 1; -} - -.figure-caption { - font-size: 0.875em; - color: #6c757d; -} - -.container, -.container-fluid, -.container-xxl, -.container-xl, -.container-lg, -.container-md, -.container-sm { - width: 100%; - padding-right: var(--bs-gutter-x, 0.75rem); - padding-left: var(--bs-gutter-x, 0.75rem); - margin-right: auto; - margin-left: auto; -} - -@media (min-width: 576px) { - .container-sm, .container { - max-width: 540px; - } -} -@media (min-width: 768px) { - .container-md, .container-sm, .container { - max-width: 720px; - } -} -@media (min-width: 992px) { - .container-lg, .container-md, .container-sm, .container { - max-width: 960px; - } -} -@media (min-width: 1200px) { - .container-xl, .container-lg, .container-md, .container-sm, .container { - max-width: 1140px; - } -} -@media (min-width: 1400px) { - .container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container { - max-width: 1320px; - } -} -.row { - --bs-gutter-x: 1.5rem; - --bs-gutter-y: 0; - display: flex; - flex-wrap: wrap; - margin-top: calc(var(--bs-gutter-y) * -1); - margin-right: calc(var(--bs-gutter-x) / -2); - margin-left: calc(var(--bs-gutter-x) / -2); -} -.row > * { - flex-shrink: 0; - width: 100%; - max-width: 100%; - padding-right: calc(var(--bs-gutter-x) / 2); - padding-left: calc(var(--bs-gutter-x) / 2); - margin-top: var(--bs-gutter-y); -} - -.col { - flex: 1 0 0%; -} - -.row-cols-auto > * { - flex: 0 0 auto; - width: auto; -} - -.row-cols-1 > * { - flex: 0 0 auto; - width: 100%; -} - -.row-cols-2 > * { - flex: 0 0 auto; - width: 50%; -} - -.row-cols-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; -} - -.row-cols-4 > * { - flex: 0 0 auto; - width: 25%; -} - -.row-cols-5 > * { - flex: 0 0 auto; - width: 20%; -} - -.row-cols-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; -} - -.col-auto { - flex: 0 0 auto; - width: auto; -} - -.col-1 { - flex: 0 0 auto; - width: 8.3333333333%; -} - -.col-2 { - flex: 0 0 auto; - width: 16.6666666667%; -} - -.col-3 { - flex: 0 0 auto; - width: 25%; -} - -.col-4 { - flex: 0 0 auto; - width: 33.3333333333%; -} - -.col-5 { - flex: 0 0 auto; - width: 41.6666666667%; -} - -.col-6 { - flex: 0 0 auto; - width: 50%; -} - -.col-7 { - flex: 0 0 auto; - width: 58.3333333333%; -} - -.col-8 { - flex: 0 0 auto; - width: 66.6666666667%; -} - -.col-9 { - flex: 0 0 auto; - width: 75%; -} - -.col-10 { - flex: 0 0 auto; - width: 83.3333333333%; -} - -.col-11 { - flex: 0 0 auto; - width: 91.6666666667%; -} - -.col-12 { - flex: 0 0 auto; - width: 100%; -} - -.offset-1 { - margin-left: 8.3333333333%; -} - -.offset-2 { - margin-left: 16.6666666667%; -} - -.offset-3 { - margin-left: 25%; -} - -.offset-4 { - margin-left: 33.3333333333%; -} - -.offset-5 { - margin-left: 41.6666666667%; -} - -.offset-6 { - margin-left: 50%; -} - -.offset-7 { - margin-left: 58.3333333333%; -} - -.offset-8 { - margin-left: 66.6666666667%; -} - -.offset-9 { - margin-left: 75%; -} - -.offset-10 { - margin-left: 83.3333333333%; -} - -.offset-11 { - margin-left: 91.6666666667%; -} - -.g-0, -.gx-0 { - --bs-gutter-x: 0; -} - -.g-0, -.gy-0 { - --bs-gutter-y: 0; -} - -.g-1, -.gx-1 { - --bs-gutter-x: 0.25rem; -} - -.g-1, -.gy-1 { - --bs-gutter-y: 0.25rem; -} - -.g-2, -.gx-2 { - --bs-gutter-x: 0.5rem; -} - -.g-2, -.gy-2 { - --bs-gutter-y: 0.5rem; -} - -.g-3, -.gx-3 { - --bs-gutter-x: 1rem; -} - -.g-3, -.gy-3 { - --bs-gutter-y: 1rem; -} - -.g-4, -.gx-4 { - --bs-gutter-x: 1.5rem; -} - -.g-4, -.gy-4 { - --bs-gutter-y: 1.5rem; -} - -.g-5, -.gx-5 { - --bs-gutter-x: 3rem; -} - -.g-5, -.gy-5 { - --bs-gutter-y: 3rem; -} - -@media (min-width: 576px) { - .col-sm { - flex: 1 0 0%; - } - - .row-cols-sm-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-sm-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-sm-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-sm-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-sm-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-sm-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-sm-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } - - .col-sm-auto { - flex: 0 0 auto; - width: auto; - } - - .col-sm-1 { - flex: 0 0 auto; - width: 8.3333333333%; - } - - .col-sm-2 { - flex: 0 0 auto; - width: 16.6666666667%; - } - - .col-sm-3 { - flex: 0 0 auto; - width: 25%; - } - - .col-sm-4 { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .col-sm-5 { - flex: 0 0 auto; - width: 41.6666666667%; - } - - .col-sm-6 { - flex: 0 0 auto; - width: 50%; - } - - .col-sm-7 { - flex: 0 0 auto; - width: 58.3333333333%; - } - - .col-sm-8 { - flex: 0 0 auto; - width: 66.6666666667%; - } - - .col-sm-9 { - flex: 0 0 auto; - width: 75%; - } - - .col-sm-10 { - flex: 0 0 auto; - width: 83.3333333333%; - } - - .col-sm-11 { - flex: 0 0 auto; - width: 91.6666666667%; - } - - .col-sm-12 { - flex: 0 0 auto; - width: 100%; - } - - .offset-sm-0 { - margin-left: 0; - } - - .offset-sm-1 { - margin-left: 8.3333333333%; - } - - .offset-sm-2 { - margin-left: 16.6666666667%; - } - - .offset-sm-3 { - margin-left: 25%; - } - - .offset-sm-4 { - margin-left: 33.3333333333%; - } - - .offset-sm-5 { - margin-left: 41.6666666667%; - } - - .offset-sm-6 { - margin-left: 50%; - } - - .offset-sm-7 { - margin-left: 58.3333333333%; - } - - .offset-sm-8 { - margin-left: 66.6666666667%; - } - - .offset-sm-9 { - margin-left: 75%; - } - - .offset-sm-10 { - margin-left: 83.3333333333%; - } - - .offset-sm-11 { - margin-left: 91.6666666667%; - } - - .g-sm-0, -.gx-sm-0 { - --bs-gutter-x: 0; - } - - .g-sm-0, -.gy-sm-0 { - --bs-gutter-y: 0; - } - - .g-sm-1, -.gx-sm-1 { - --bs-gutter-x: 0.25rem; - } - - .g-sm-1, -.gy-sm-1 { - --bs-gutter-y: 0.25rem; - } - - .g-sm-2, -.gx-sm-2 { - --bs-gutter-x: 0.5rem; - } - - .g-sm-2, -.gy-sm-2 { - --bs-gutter-y: 0.5rem; - } - - .g-sm-3, -.gx-sm-3 { - --bs-gutter-x: 1rem; - } - - .g-sm-3, -.gy-sm-3 { - --bs-gutter-y: 1rem; - } - - .g-sm-4, -.gx-sm-4 { - --bs-gutter-x: 1.5rem; - } - - .g-sm-4, -.gy-sm-4 { - --bs-gutter-y: 1.5rem; - } - - .g-sm-5, -.gx-sm-5 { - --bs-gutter-x: 3rem; - } - - .g-sm-5, -.gy-sm-5 { - --bs-gutter-y: 3rem; - } -} -@media (min-width: 768px) { - .col-md { - flex: 1 0 0%; - } - - .row-cols-md-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-md-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-md-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-md-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-md-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-md-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-md-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } - - .col-md-auto { - flex: 0 0 auto; - width: auto; - } - - .col-md-1 { - flex: 0 0 auto; - width: 8.3333333333%; - } - - .col-md-2 { - flex: 0 0 auto; - width: 16.6666666667%; - } - - .col-md-3 { - flex: 0 0 auto; - width: 25%; - } - - .col-md-4 { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .col-md-5 { - flex: 0 0 auto; - width: 41.6666666667%; - } - - .col-md-6 { - flex: 0 0 auto; - width: 50%; - } - - .col-md-7 { - flex: 0 0 auto; - width: 58.3333333333%; - } - - .col-md-8 { - flex: 0 0 auto; - width: 66.6666666667%; - } - - .col-md-9 { - flex: 0 0 auto; - width: 75%; - } - - .col-md-10 { - flex: 0 0 auto; - width: 83.3333333333%; - } - - .col-md-11 { - flex: 0 0 auto; - width: 91.6666666667%; - } - - .col-md-12 { - flex: 0 0 auto; - width: 100%; - } - - .offset-md-0 { - margin-left: 0; - } - - .offset-md-1 { - margin-left: 8.3333333333%; - } - - .offset-md-2 { - margin-left: 16.6666666667%; - } - - .offset-md-3 { - margin-left: 25%; - } - - .offset-md-4 { - margin-left: 33.3333333333%; - } - - .offset-md-5 { - margin-left: 41.6666666667%; - } - - .offset-md-6 { - margin-left: 50%; - } - - .offset-md-7 { - margin-left: 58.3333333333%; - } - - .offset-md-8 { - margin-left: 66.6666666667%; - } - - .offset-md-9 { - margin-left: 75%; - } - - .offset-md-10 { - margin-left: 83.3333333333%; - } - - .offset-md-11 { - margin-left: 91.6666666667%; - } - - .g-md-0, -.gx-md-0 { - --bs-gutter-x: 0; - } - - .g-md-0, -.gy-md-0 { - --bs-gutter-y: 0; - } - - .g-md-1, -.gx-md-1 { - --bs-gutter-x: 0.25rem; - } - - .g-md-1, -.gy-md-1 { - --bs-gutter-y: 0.25rem; - } - - .g-md-2, -.gx-md-2 { - --bs-gutter-x: 0.5rem; - } - - .g-md-2, -.gy-md-2 { - --bs-gutter-y: 0.5rem; - } - - .g-md-3, -.gx-md-3 { - --bs-gutter-x: 1rem; - } - - .g-md-3, -.gy-md-3 { - --bs-gutter-y: 1rem; - } - - .g-md-4, -.gx-md-4 { - --bs-gutter-x: 1.5rem; - } - - .g-md-4, -.gy-md-4 { - --bs-gutter-y: 1.5rem; - } - - .g-md-5, -.gx-md-5 { - --bs-gutter-x: 3rem; - } - - .g-md-5, -.gy-md-5 { - --bs-gutter-y: 3rem; - } -} -@media (min-width: 992px) { - .col-lg { - flex: 1 0 0%; - } - - .row-cols-lg-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-lg-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-lg-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-lg-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-lg-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-lg-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-lg-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } - - .col-lg-auto { - flex: 0 0 auto; - width: auto; - } - - .col-lg-1 { - flex: 0 0 auto; - width: 8.3333333333%; - } - - .col-lg-2 { - flex: 0 0 auto; - width: 16.6666666667%; - } - - .col-lg-3 { - flex: 0 0 auto; - width: 25%; - } - - .col-lg-4 { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .col-lg-5 { - flex: 0 0 auto; - width: 41.6666666667%; - } - - .col-lg-6 { - flex: 0 0 auto; - width: 50%; - } - - .col-lg-7 { - flex: 0 0 auto; - width: 58.3333333333%; - } - - .col-lg-8 { - flex: 0 0 auto; - width: 66.6666666667%; - } - - .col-lg-9 { - flex: 0 0 auto; - width: 75%; - } - - .col-lg-10 { - flex: 0 0 auto; - width: 83.3333333333%; - } - - .col-lg-11 { - flex: 0 0 auto; - width: 91.6666666667%; - } - - .col-lg-12 { - flex: 0 0 auto; - width: 100%; - } - - .offset-lg-0 { - margin-left: 0; - } - - .offset-lg-1 { - margin-left: 8.3333333333%; - } - - .offset-lg-2 { - margin-left: 16.6666666667%; - } - - .offset-lg-3 { - margin-left: 25%; - } - - .offset-lg-4 { - margin-left: 33.3333333333%; - } - - .offset-lg-5 { - margin-left: 41.6666666667%; - } - - .offset-lg-6 { - margin-left: 50%; - } - - .offset-lg-7 { - margin-left: 58.3333333333%; - } - - .offset-lg-8 { - margin-left: 66.6666666667%; - } - - .offset-lg-9 { - margin-left: 75%; - } - - .offset-lg-10 { - margin-left: 83.3333333333%; - } - - .offset-lg-11 { - margin-left: 91.6666666667%; - } - - .g-lg-0, -.gx-lg-0 { - --bs-gutter-x: 0; - } - - .g-lg-0, -.gy-lg-0 { - --bs-gutter-y: 0; - } - - .g-lg-1, -.gx-lg-1 { - --bs-gutter-x: 0.25rem; - } - - .g-lg-1, -.gy-lg-1 { - --bs-gutter-y: 0.25rem; - } - - .g-lg-2, -.gx-lg-2 { - --bs-gutter-x: 0.5rem; - } - - .g-lg-2, -.gy-lg-2 { - --bs-gutter-y: 0.5rem; - } - - .g-lg-3, -.gx-lg-3 { - --bs-gutter-x: 1rem; - } - - .g-lg-3, -.gy-lg-3 { - --bs-gutter-y: 1rem; - } - - .g-lg-4, -.gx-lg-4 { - --bs-gutter-x: 1.5rem; - } - - .g-lg-4, -.gy-lg-4 { - --bs-gutter-y: 1.5rem; - } - - .g-lg-5, -.gx-lg-5 { - --bs-gutter-x: 3rem; - } - - .g-lg-5, -.gy-lg-5 { - --bs-gutter-y: 3rem; - } -} -@media (min-width: 1200px) { - .col-xl { - flex: 1 0 0%; - } - - .row-cols-xl-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-xl-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-xl-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-xl-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-xl-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-xl-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-xl-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } - - .col-xl-auto { - flex: 0 0 auto; - width: auto; - } - - .col-xl-1 { - flex: 0 0 auto; - width: 8.3333333333%; - } - - .col-xl-2 { - flex: 0 0 auto; - width: 16.6666666667%; - } - - .col-xl-3 { - flex: 0 0 auto; - width: 25%; - } - - .col-xl-4 { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .col-xl-5 { - flex: 0 0 auto; - width: 41.6666666667%; - } - - .col-xl-6 { - flex: 0 0 auto; - width: 50%; - } - - .col-xl-7 { - flex: 0 0 auto; - width: 58.3333333333%; - } - - .col-xl-8 { - flex: 0 0 auto; - width: 66.6666666667%; - } - - .col-xl-9 { - flex: 0 0 auto; - width: 75%; - } - - .col-xl-10 { - flex: 0 0 auto; - width: 83.3333333333%; - } - - .col-xl-11 { - flex: 0 0 auto; - width: 91.6666666667%; - } - - .col-xl-12 { - flex: 0 0 auto; - width: 100%; - } - - .offset-xl-0 { - margin-left: 0; - } - - .offset-xl-1 { - margin-left: 8.3333333333%; - } - - .offset-xl-2 { - margin-left: 16.6666666667%; - } - - .offset-xl-3 { - margin-left: 25%; - } - - .offset-xl-4 { - margin-left: 33.3333333333%; - } - - .offset-xl-5 { - margin-left: 41.6666666667%; - } - - .offset-xl-6 { - margin-left: 50%; - } - - .offset-xl-7 { - margin-left: 58.3333333333%; - } - - .offset-xl-8 { - margin-left: 66.6666666667%; - } - - .offset-xl-9 { - margin-left: 75%; - } - - .offset-xl-10 { - margin-left: 83.3333333333%; - } - - .offset-xl-11 { - margin-left: 91.6666666667%; - } - - .g-xl-0, -.gx-xl-0 { - --bs-gutter-x: 0; - } - - .g-xl-0, -.gy-xl-0 { - --bs-gutter-y: 0; - } - - .g-xl-1, -.gx-xl-1 { - --bs-gutter-x: 0.25rem; - } - - .g-xl-1, -.gy-xl-1 { - --bs-gutter-y: 0.25rem; - } - - .g-xl-2, -.gx-xl-2 { - --bs-gutter-x: 0.5rem; - } - - .g-xl-2, -.gy-xl-2 { - --bs-gutter-y: 0.5rem; - } - - .g-xl-3, -.gx-xl-3 { - --bs-gutter-x: 1rem; - } - - .g-xl-3, -.gy-xl-3 { - --bs-gutter-y: 1rem; - } - - .g-xl-4, -.gx-xl-4 { - --bs-gutter-x: 1.5rem; - } - - .g-xl-4, -.gy-xl-4 { - --bs-gutter-y: 1.5rem; - } - - .g-xl-5, -.gx-xl-5 { - --bs-gutter-x: 3rem; - } - - .g-xl-5, -.gy-xl-5 { - --bs-gutter-y: 3rem; - } -} -@media (min-width: 1400px) { - .col-xxl { - flex: 1 0 0%; - } - - .row-cols-xxl-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-xxl-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-xxl-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-xxl-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-xxl-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-xxl-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-xxl-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } - - .col-xxl-auto { - flex: 0 0 auto; - width: auto; - } - - .col-xxl-1 { - flex: 0 0 auto; - width: 8.3333333333%; - } - - .col-xxl-2 { - flex: 0 0 auto; - width: 16.6666666667%; - } - - .col-xxl-3 { - flex: 0 0 auto; - width: 25%; - } - - .col-xxl-4 { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .col-xxl-5 { - flex: 0 0 auto; - width: 41.6666666667%; - } - - .col-xxl-6 { - flex: 0 0 auto; - width: 50%; - } - - .col-xxl-7 { - flex: 0 0 auto; - width: 58.3333333333%; - } - - .col-xxl-8 { - flex: 0 0 auto; - width: 66.6666666667%; - } - - .col-xxl-9 { - flex: 0 0 auto; - width: 75%; - } - - .col-xxl-10 { - flex: 0 0 auto; - width: 83.3333333333%; - } - - .col-xxl-11 { - flex: 0 0 auto; - width: 91.6666666667%; - } - - .col-xxl-12 { - flex: 0 0 auto; - width: 100%; - } - - .offset-xxl-0 { - margin-left: 0; - } - - .offset-xxl-1 { - margin-left: 8.3333333333%; - } - - .offset-xxl-2 { - margin-left: 16.6666666667%; - } - - .offset-xxl-3 { - margin-left: 25%; - } - - .offset-xxl-4 { - margin-left: 33.3333333333%; - } - - .offset-xxl-5 { - margin-left: 41.6666666667%; - } - - .offset-xxl-6 { - margin-left: 50%; - } - - .offset-xxl-7 { - margin-left: 58.3333333333%; - } - - .offset-xxl-8 { - margin-left: 66.6666666667%; - } - - .offset-xxl-9 { - margin-left: 75%; - } - - .offset-xxl-10 { - margin-left: 83.3333333333%; - } - - .offset-xxl-11 { - margin-left: 91.6666666667%; - } - - .g-xxl-0, -.gx-xxl-0 { - --bs-gutter-x: 0; - } - - .g-xxl-0, -.gy-xxl-0 { - --bs-gutter-y: 0; - } - - .g-xxl-1, -.gx-xxl-1 { - --bs-gutter-x: 0.25rem; - } - - .g-xxl-1, -.gy-xxl-1 { - --bs-gutter-y: 0.25rem; - } - - .g-xxl-2, -.gx-xxl-2 { - --bs-gutter-x: 0.5rem; - } - - .g-xxl-2, -.gy-xxl-2 { - --bs-gutter-y: 0.5rem; - } - - .g-xxl-3, -.gx-xxl-3 { - --bs-gutter-x: 1rem; - } - - .g-xxl-3, -.gy-xxl-3 { - --bs-gutter-y: 1rem; - } - - .g-xxl-4, -.gx-xxl-4 { - --bs-gutter-x: 1.5rem; - } - - .g-xxl-4, -.gy-xxl-4 { - --bs-gutter-y: 1.5rem; - } - - .g-xxl-5, -.gx-xxl-5 { - --bs-gutter-x: 3rem; - } - - .g-xxl-5, -.gy-xxl-5 { - --bs-gutter-y: 3rem; - } -} -.table { - --bs-table-bg: transparent; - --bs-table-accent-bg: transparent; - --bs-table-striped-color: #212529; - --bs-table-striped-bg: rgba(0, 0, 0, 0.05); - --bs-table-active-color: #212529; - --bs-table-active-bg: rgba(0, 0, 0, 0.1); - --bs-table-hover-color: #212529; - --bs-table-hover-bg: rgba(0, 0, 0, 0.075); - width: 100%; - margin-bottom: 1rem; - color: #212529; - vertical-align: top; - border-color: #dee2e6; -} -.table > :not(caption) > * > * { - padding: 0.5rem 0.5rem; - background-color: var(--bs-table-bg); - border-bottom-width: 1px; - box-shadow: inset 0 0 0 9999px var(--bs-table-accent-bg); -} -.table > tbody { - vertical-align: inherit; -} -.table > thead { - vertical-align: bottom; -} -.table > :not(:last-child) > :last-child > * { - border-bottom-color: currentColor; -} - -.caption-top { - caption-side: top; -} - -.table-sm > :not(caption) > * > * { - padding: 0.25rem 0.25rem; -} - -.table-bordered > :not(caption) > * { - border-width: 1px 0; -} -.table-bordered > :not(caption) > * > * { - border-width: 0 1px; -} - -.table-borderless > :not(caption) > * > * { - border-bottom-width: 0; -} - -.table-striped > tbody > tr:nth-of-type(odd) { - --bs-table-accent-bg: var(--bs-table-striped-bg); - color: var(--bs-table-striped-color); -} - -.table-active { - --bs-table-accent-bg: var(--bs-table-active-bg); - color: var(--bs-table-active-color); -} - -.table-hover > tbody > tr:hover { - --bs-table-accent-bg: var(--bs-table-hover-bg); - color: var(--bs-table-hover-color); -} - -.table-primary { - --bs-table-bg: #cfe2ff; - --bs-table-striped-bg: #c5d7f2; - --bs-table-striped-color: #000; - --bs-table-active-bg: #bacbe6; - --bs-table-active-color: #000; - --bs-table-hover-bg: #bfd1ec; - --bs-table-hover-color: #000; - color: #000; - border-color: #bacbe6; -} - -.table-secondary { - --bs-table-bg: #e2e3e5; - --bs-table-striped-bg: #d7d8da; - --bs-table-striped-color: #000; - --bs-table-active-bg: #cbccce; - --bs-table-active-color: #000; - --bs-table-hover-bg: #d1d2d4; - --bs-table-hover-color: #000; - color: #000; - border-color: #cbccce; -} - -.table-success { - --bs-table-bg: #d1e7dd; - --bs-table-striped-bg: #c7dbd2; - --bs-table-striped-color: #000; - --bs-table-active-bg: #bcd0c7; - --bs-table-active-color: #000; - --bs-table-hover-bg: #c1d6cc; - --bs-table-hover-color: #000; - color: #000; - border-color: #bcd0c7; -} - -.table-info { - --bs-table-bg: #cff4fc; - --bs-table-striped-bg: #c5e8ef; - --bs-table-striped-color: #000; - --bs-table-active-bg: #badce3; - --bs-table-active-color: #000; - --bs-table-hover-bg: #bfe2e9; - --bs-table-hover-color: #000; - color: #000; - border-color: #badce3; -} - -.table-warning { - --bs-table-bg: #fff3cd; - --bs-table-striped-bg: #f2e7c3; - --bs-table-striped-color: #000; - --bs-table-active-bg: #e6dbb9; - --bs-table-active-color: #000; - --bs-table-hover-bg: #ece1be; - --bs-table-hover-color: #000; - color: #000; - border-color: #e6dbb9; -} - -.table-danger { - --bs-table-bg: #f8d7da; - --bs-table-striped-bg: #eccccf; - --bs-table-striped-color: #000; - --bs-table-active-bg: #dfc2c4; - --bs-table-active-color: #000; - --bs-table-hover-bg: #e5c7ca; - --bs-table-hover-color: #000; - color: #000; - border-color: #dfc2c4; -} - -.table-light { - --bs-table-bg: #f8f9fa; - --bs-table-striped-bg: #ecedee; - --bs-table-striped-color: #000; - --bs-table-active-bg: #dfe0e1; - --bs-table-active-color: #000; - --bs-table-hover-bg: #e5e6e7; - --bs-table-hover-color: #000; - color: #000; - border-color: #dfe0e1; -} - -.table-dark { - --bs-table-bg: #212529; - --bs-table-striped-bg: #2c3034; - --bs-table-striped-color: #fff; - --bs-table-active-bg: #373b3e; - --bs-table-active-color: #fff; - --bs-table-hover-bg: #323539; - --bs-table-hover-color: #fff; - color: #fff; - border-color: #373b3e; -} - -.table-responsive { - overflow-x: auto; - -webkit-overflow-scrolling: touch; -} - -@media (max-width: 575.98px) { - .table-responsive-sm { - overflow-x: auto; - -webkit-overflow-scrolling: touch; - } -} -@media (max-width: 767.98px) { - .table-responsive-md { - overflow-x: auto; - -webkit-overflow-scrolling: touch; - } -} -@media (max-width: 991.98px) { - .table-responsive-lg { - overflow-x: auto; - -webkit-overflow-scrolling: touch; - } -} -@media (max-width: 1199.98px) { - .table-responsive-xl { - overflow-x: auto; - -webkit-overflow-scrolling: touch; - } -} -@media (max-width: 1399.98px) { - .table-responsive-xxl { - overflow-x: auto; - -webkit-overflow-scrolling: touch; - } -} -.form-label { - margin-bottom: 0.5rem; -} - -.col-form-label { - padding-top: calc(0.375rem + 1px); - padding-bottom: calc(0.375rem + 1px); - margin-bottom: 0; - font-size: inherit; - line-height: 1.5; -} - -.col-form-label-lg { - padding-top: calc(0.5rem + 1px); - padding-bottom: calc(0.5rem + 1px); - font-size: 1.25rem; -} - -.col-form-label-sm { - padding-top: calc(0.25rem + 1px); - padding-bottom: calc(0.25rem + 1px); - font-size: 0.875rem; -} - -.form-text { - margin-top: 0.25rem; - font-size: 0.875em; - color: #6c757d; -} - -.form-control { - display: block; - width: 100%; - padding: 0.375rem 0.75rem; - font-size: 1rem; - font-weight: 400; - line-height: 1.5; - color: #212529; - background-color: #fff; - background-clip: padding-box; - border: 1px solid #ced4da; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - border-radius: 0.25rem; - transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .form-control { - transition: none; - } -} -.form-control[type=file] { - overflow: hidden; -} -.form-control[type=file]:not(:disabled):not([readonly]) { - cursor: pointer; -} -.form-control:focus { - color: #212529; - background-color: #fff; - border-color: #86b7fe; - outline: 0; - box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); -} -.form-control::-webkit-date-and-time-value { - height: 1.5em; -} -.form-control::-moz-placeholder { - color: #6c757d; - opacity: 1; -} -.form-control::placeholder { - color: #6c757d; - opacity: 1; -} -.form-control:disabled, .form-control[readonly] { - background-color: #e9ecef; - opacity: 1; -} -.form-control::file-selector-button { - padding: 0.375rem 0.75rem; - margin: -0.375rem -0.75rem; - -webkit-margin-end: 0.75rem; - margin-inline-end: 0.75rem; - color: #212529; - background-color: #e9ecef; - pointer-events: none; - border-color: inherit; - border-style: solid; - border-width: 0; - border-inline-end-width: 1px; - border-radius: 0; - transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .form-control::file-selector-button { - transition: none; - } -} -.form-control:hover:not(:disabled):not([readonly])::file-selector-button { - background-color: #dde0e3; -} -.form-control::-webkit-file-upload-button { - padding: 0.375rem 0.75rem; - margin: -0.375rem -0.75rem; - -webkit-margin-end: 0.75rem; - margin-inline-end: 0.75rem; - color: #212529; - background-color: #e9ecef; - pointer-events: none; - border-color: inherit; - border-style: solid; - border-width: 0; - border-inline-end-width: 1px; - border-radius: 0; - -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .form-control::-webkit-file-upload-button { - -webkit-transition: none; - transition: none; - } -} -.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button { - background-color: #dde0e3; -} - -.form-control-plaintext { - display: block; - width: 100%; - padding: 0.375rem 0; - margin-bottom: 0; - line-height: 1.5; - color: #212529; - background-color: transparent; - border: solid transparent; - border-width: 1px 0; -} -.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg { - padding-right: 0; - padding-left: 0; -} - -.form-control-sm { - min-height: calc(1.5em + 0.5rem + 2px); - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - border-radius: 0.2rem; -} -.form-control-sm::file-selector-button { - padding: 0.25rem 0.5rem; - margin: -0.25rem -0.5rem; - -webkit-margin-end: 0.5rem; - margin-inline-end: 0.5rem; -} -.form-control-sm::-webkit-file-upload-button { - padding: 0.25rem 0.5rem; - margin: -0.25rem -0.5rem; - -webkit-margin-end: 0.5rem; - margin-inline-end: 0.5rem; -} - -.form-control-lg { - min-height: calc(1.5em + 1rem + 2px); - padding: 0.5rem 1rem; - font-size: 1.25rem; - border-radius: 0.3rem; -} -.form-control-lg::file-selector-button { - padding: 0.5rem 1rem; - margin: -0.5rem -1rem; - -webkit-margin-end: 1rem; - margin-inline-end: 1rem; -} -.form-control-lg::-webkit-file-upload-button { - padding: 0.5rem 1rem; - margin: -0.5rem -1rem; - -webkit-margin-end: 1rem; - margin-inline-end: 1rem; -} - -textarea.form-control { - min-height: calc(1.5em + 0.75rem + 2px); -} -textarea.form-control-sm { - min-height: calc(1.5em + 0.5rem + 2px); -} -textarea.form-control-lg { - min-height: calc(1.5em + 1rem + 2px); -} - -.form-control-color { - max-width: 3rem; - height: auto; - padding: 0.375rem; -} -.form-control-color:not(:disabled):not([readonly]) { - cursor: pointer; -} -.form-control-color::-moz-color-swatch { - height: 1.5em; - border-radius: 0.25rem; -} -.form-control-color::-webkit-color-swatch { - height: 1.5em; - border-radius: 0.25rem; -} - -.form-select { - display: block; - width: 100%; - padding: 0.375rem 2.25rem 0.375rem 0.75rem; - font-size: 1rem; - font-weight: 400; - line-height: 1.5; - color: #212529; - background-color: #fff; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"); - background-repeat: no-repeat; - background-position: right 0.75rem center; - background-size: 16px 12px; - border: 1px solid #ced4da; - border-radius: 0.25rem; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; -} -.form-select:focus { - border-color: #86b7fe; - outline: 0; - box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); -} -.form-select[multiple], .form-select[size]:not([size="1"]) { - padding-right: 0.75rem; - background-image: none; -} -.form-select:disabled { - background-color: #e9ecef; -} -.form-select:-moz-focusring { - color: transparent; - text-shadow: 0 0 0 #212529; -} - -.form-select-sm { - padding-top: 0.25rem; - padding-bottom: 0.25rem; - padding-left: 0.5rem; - font-size: 0.875rem; -} - -.form-select-lg { - padding-top: 0.5rem; - padding-bottom: 0.5rem; - padding-left: 1rem; - font-size: 1.25rem; -} - -.form-check { - display: block; - min-height: 1.5rem; - padding-left: 1.5em; - margin-bottom: 0.125rem; -} -.form-check .form-check-input { - float: left; - margin-left: -1.5em; -} - -.form-check-input { - width: 1em; - height: 1em; - margin-top: 0.25em; - vertical-align: top; - background-color: #fff; - background-repeat: no-repeat; - background-position: center; - background-size: contain; - border: 1px solid rgba(0, 0, 0, 0.25); - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-print-color-adjust: exact; - color-adjust: exact; -} -.form-check-input[type=checkbox] { - border-radius: 0.25em; -} -.form-check-input[type=radio] { - border-radius: 50%; -} -.form-check-input:active { - filter: brightness(90%); -} -.form-check-input:focus { - border-color: #86b7fe; - outline: 0; - box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); -} -.form-check-input:checked { - background-color: #0d6efd; - border-color: #0d6efd; -} -.form-check-input:checked[type=checkbox] { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e"); -} -.form-check-input:checked[type=radio] { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e"); -} -.form-check-input[type=checkbox]:indeterminate { - background-color: #0d6efd; - border-color: #0d6efd; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e"); -} -.form-check-input:disabled { - pointer-events: none; - filter: none; - opacity: 0.5; -} -.form-check-input[disabled] ~ .form-check-label, .form-check-input:disabled ~ .form-check-label { - opacity: 0.5; -} - -.form-switch { - padding-left: 2.5em; -} -.form-switch .form-check-input { - width: 2em; - margin-left: -2.5em; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e"); - background-position: left center; - border-radius: 2em; - transition: background-position 0.15s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .form-switch .form-check-input { - transition: none; - } -} -.form-switch .form-check-input:focus { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e"); -} -.form-switch .form-check-input:checked { - background-position: right center; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e"); -} - -.form-check-inline { - display: inline-block; - margin-right: 1rem; -} - -.btn-check { - position: absolute; - clip: rect(0, 0, 0, 0); - pointer-events: none; -} -.btn-check[disabled] + .btn, .btn-check:disabled + .btn { - pointer-events: none; - filter: none; - opacity: 0.65; -} - -.form-range { - width: 100%; - height: 1.5rem; - padding: 0; - background-color: transparent; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; -} -.form-range:focus { - outline: 0; -} -.form-range:focus::-webkit-slider-thumb { - box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25); -} -.form-range:focus::-moz-range-thumb { - box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25); -} -.form-range::-moz-focus-outer { - border: 0; -} -.form-range::-webkit-slider-thumb { - width: 1rem; - height: 1rem; - margin-top: -0.25rem; - background-color: #0d6efd; - border: 0; - border-radius: 1rem; - -webkit-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - -webkit-appearance: none; - appearance: none; -} -@media (prefers-reduced-motion: reduce) { - .form-range::-webkit-slider-thumb { - -webkit-transition: none; - transition: none; - } -} -.form-range::-webkit-slider-thumb:active { - background-color: #b6d4fe; -} -.form-range::-webkit-slider-runnable-track { - width: 100%; - height: 0.5rem; - color: transparent; - cursor: pointer; - background-color: #dee2e6; - border-color: transparent; - border-radius: 1rem; -} -.form-range::-moz-range-thumb { - width: 1rem; - height: 1rem; - background-color: #0d6efd; - border: 0; - border-radius: 1rem; - -moz-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - -moz-appearance: none; - appearance: none; -} -@media (prefers-reduced-motion: reduce) { - .form-range::-moz-range-thumb { - -moz-transition: none; - transition: none; - } -} -.form-range::-moz-range-thumb:active { - background-color: #b6d4fe; -} -.form-range::-moz-range-track { - width: 100%; - height: 0.5rem; - color: transparent; - cursor: pointer; - background-color: #dee2e6; - border-color: transparent; - border-radius: 1rem; -} -.form-range:disabled { - pointer-events: none; -} -.form-range:disabled::-webkit-slider-thumb { - background-color: #adb5bd; -} -.form-range:disabled::-moz-range-thumb { - background-color: #adb5bd; -} - -.form-floating { - position: relative; -} -.form-floating > .form-control, -.form-floating > .form-select { - height: calc(3.5rem + 2px); - padding: 1rem 0.75rem; -} -.form-floating > label { - position: absolute; - top: 0; - left: 0; - height: 100%; - padding: 1rem 0.75rem; - pointer-events: none; - border: 1px solid transparent; - transform-origin: 0 0; - transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .form-floating > label { - transition: none; - } -} -.form-floating > .form-control::-moz-placeholder { - color: transparent; -} -.form-floating > .form-control::placeholder { - color: transparent; -} -.form-floating > .form-control:not(:-moz-placeholder-shown) { - padding-top: 1.625rem; - padding-bottom: 0.625rem; -} -.form-floating > .form-control:focus, .form-floating > .form-control:not(:placeholder-shown) { - padding-top: 1.625rem; - padding-bottom: 0.625rem; -} -.form-floating > .form-control:-webkit-autofill { - padding-top: 1.625rem; - padding-bottom: 0.625rem; -} -.form-floating > .form-select { - padding-top: 1.625rem; - padding-bottom: 0.625rem; -} -.form-floating > .form-control:not(:-moz-placeholder-shown) ~ label { - opacity: 0.65; - transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); -} -.form-floating > .form-control:focus ~ label, -.form-floating > .form-control:not(:placeholder-shown) ~ label, -.form-floating > .form-select ~ label { - opacity: 0.65; - transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); -} -.form-floating > .form-control:-webkit-autofill ~ label { - opacity: 0.65; - transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); -} - -.input-group { - position: relative; - display: flex; - flex-wrap: wrap; - align-items: stretch; - width: 100%; -} -.input-group > .form-control, -.input-group > .form-select { - position: relative; - flex: 1 1 auto; - width: 1%; - min-width: 0; -} -.input-group > .form-control:focus, -.input-group > .form-select:focus { - z-index: 3; -} -.input-group .btn { - position: relative; - z-index: 2; -} -.input-group .btn:focus { - z-index: 3; -} - -.input-group-text { - display: flex; - align-items: center; - padding: 0.375rem 0.75rem; - font-size: 1rem; - font-weight: 400; - line-height: 1.5; - color: #212529; - text-align: center; - white-space: nowrap; - background-color: #e9ecef; - border: 1px solid #ced4da; - border-radius: 0.25rem; -} - -.input-group-lg > .form-control, -.input-group-lg > .form-select, -.input-group-lg > .input-group-text, -.input-group-lg > .btn { - padding: 0.5rem 1rem; - font-size: 1.25rem; - border-radius: 0.3rem; -} - -.input-group-sm > .form-control, -.input-group-sm > .form-select, -.input-group-sm > .input-group-text, -.input-group-sm > .btn { - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - border-radius: 0.2rem; -} - -.input-group-lg > .form-select, -.input-group-sm > .form-select { - padding-right: 3rem; -} - -.input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu), -.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n+3) { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} -.input-group.has-validation > :nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu), -.input-group.has-validation > .dropdown-toggle:nth-last-child(n+4) { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} -.input-group > :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) { - margin-left: -1px; - border-top-left-radius: 0; - border-bottom-left-radius: 0; -} - -.valid-feedback { - display: none; - width: 100%; - margin-top: 0.25rem; - font-size: 0.875em; - color: #198754; -} - -.valid-tooltip { - position: absolute; - top: 100%; - z-index: 5; - display: none; - max-width: 100%; - padding: 0.25rem 0.5rem; - margin-top: 0.1rem; - font-size: 0.875rem; - color: #fff; - background-color: rgba(25, 135, 84, 0.9); - border-radius: 0.25rem; -} - -.was-validated :valid ~ .valid-feedback, -.was-validated :valid ~ .valid-tooltip, -.is-valid ~ .valid-feedback, -.is-valid ~ .valid-tooltip { - display: block; -} - -.was-validated .form-control:valid, .form-control.is-valid { - border-color: #198754; - padding-right: calc(1.5em + 0.75rem); - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); - background-repeat: no-repeat; - background-position: right calc(0.375em + 0.1875rem) center; - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); -} -.was-validated .form-control:valid:focus, .form-control.is-valid:focus { - border-color: #198754; - box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25); -} - -.was-validated textarea.form-control:valid, textarea.form-control.is-valid { - padding-right: calc(1.5em + 0.75rem); - background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); -} - -.was-validated .form-select:valid, .form-select.is-valid { - border-color: #198754; -} -.was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size="1"], .form-select.is-valid:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size="1"] { - padding-right: 4.125rem; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); - background-position: right 0.75rem center, center right 2.25rem; - background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); -} -.was-validated .form-select:valid:focus, .form-select.is-valid:focus { - border-color: #198754; - box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25); -} - -.was-validated .form-check-input:valid, .form-check-input.is-valid { - border-color: #198754; -} -.was-validated .form-check-input:valid:checked, .form-check-input.is-valid:checked { - background-color: #198754; -} -.was-validated .form-check-input:valid:focus, .form-check-input.is-valid:focus { - box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25); -} -.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label { - color: #198754; -} - -.form-check-inline .form-check-input ~ .valid-feedback { - margin-left: 0.5em; -} - -.was-validated .input-group .form-control:valid, .input-group .form-control.is-valid, -.was-validated .input-group .form-select:valid, -.input-group .form-select.is-valid { - z-index: 1; -} -.was-validated .input-group .form-control:valid:focus, .input-group .form-control.is-valid:focus, -.was-validated .input-group .form-select:valid:focus, -.input-group .form-select.is-valid:focus { - z-index: 3; -} - -.invalid-feedback { - display: none; - width: 100%; - margin-top: 0.25rem; - font-size: 0.875em; - color: #dc3545; -} - -.invalid-tooltip { - position: absolute; - top: 100%; - z-index: 5; - display: none; - max-width: 100%; - padding: 0.25rem 0.5rem; - margin-top: 0.1rem; - font-size: 0.875rem; - color: #fff; - background-color: rgba(220, 53, 69, 0.9); - border-radius: 0.25rem; -} - -.was-validated :invalid ~ .invalid-feedback, -.was-validated :invalid ~ .invalid-tooltip, -.is-invalid ~ .invalid-feedback, -.is-invalid ~ .invalid-tooltip { - display: block; -} - -.was-validated .form-control:invalid, .form-control.is-invalid { - border-color: #dc3545; - padding-right: calc(1.5em + 0.75rem); - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); - background-repeat: no-repeat; - background-position: right calc(0.375em + 0.1875rem) center; - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); -} -.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus { - border-color: #dc3545; - box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25); -} - -.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid { - padding-right: calc(1.5em + 0.75rem); - background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); -} - -.was-validated .form-select:invalid, .form-select.is-invalid { - border-color: #dc3545; -} -.was-validated .form-select:invalid:not([multiple]):not([size]), .was-validated .form-select:invalid:not([multiple])[size="1"], .form-select.is-invalid:not([multiple]):not([size]), .form-select.is-invalid:not([multiple])[size="1"] { - padding-right: 4.125rem; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); - background-position: right 0.75rem center, center right 2.25rem; - background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); -} -.was-validated .form-select:invalid:focus, .form-select.is-invalid:focus { - border-color: #dc3545; - box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25); -} - -.was-validated .form-check-input:invalid, .form-check-input.is-invalid { - border-color: #dc3545; -} -.was-validated .form-check-input:invalid:checked, .form-check-input.is-invalid:checked { - background-color: #dc3545; -} -.was-validated .form-check-input:invalid:focus, .form-check-input.is-invalid:focus { - box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25); -} -.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label { - color: #dc3545; -} - -.form-check-inline .form-check-input ~ .invalid-feedback { - margin-left: 0.5em; -} - -.was-validated .input-group .form-control:invalid, .input-group .form-control.is-invalid, -.was-validated .input-group .form-select:invalid, -.input-group .form-select.is-invalid { - z-index: 2; -} -.was-validated .input-group .form-control:invalid:focus, .input-group .form-control.is-invalid:focus, -.was-validated .input-group .form-select:invalid:focus, -.input-group .form-select.is-invalid:focus { - z-index: 3; -} - -.btn { - display: inline-block; - font-weight: 400; - line-height: 1.5; - color: #212529; - text-align: center; - text-decoration: none; - vertical-align: middle; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; - background-color: transparent; - border: 1px solid transparent; - padding: 0.375rem 0.75rem; - font-size: 1rem; - border-radius: 0.25rem; - transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .btn { - transition: none; - } -} -.btn:hover { - color: #212529; -} -.btn-check:focus + .btn, .btn:focus { - outline: 0; - box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); -} -.btn:disabled, .btn.disabled, fieldset:disabled .btn { - pointer-events: none; - opacity: 0.65; -} - -.btn-primary { - color: #fff; - background-color: #0d6efd; - border-color: #0d6efd; -} -.btn-primary:hover { - color: #fff; - background-color: #0b5ed7; - border-color: #0a58ca; -} -.btn-check:focus + .btn-primary, .btn-primary:focus { - color: #fff; - background-color: #0b5ed7; - border-color: #0a58ca; - box-shadow: 0 0 0 0.25rem rgba(49, 132, 253, 0.5); -} -.btn-check:checked + .btn-primary, .btn-check:active + .btn-primary, .btn-primary:active, .btn-primary.active, .show > .btn-primary.dropdown-toggle { - color: #fff; - background-color: #0a58ca; - border-color: #0a53be; -} -.btn-check:checked + .btn-primary:focus, .btn-check:active + .btn-primary:focus, .btn-primary:active:focus, .btn-primary.active:focus, .show > .btn-primary.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(49, 132, 253, 0.5); -} -.btn-primary:disabled, .btn-primary.disabled { - color: #fff; - background-color: #0d6efd; - border-color: #0d6efd; -} - -.btn-secondary { - color: #fff; - background-color: #6c757d; - border-color: #6c757d; -} -.btn-secondary:hover { - color: #fff; - background-color: #5c636a; - border-color: #565e64; -} -.btn-check:focus + .btn-secondary, .btn-secondary:focus { - color: #fff; - background-color: #5c636a; - border-color: #565e64; - box-shadow: 0 0 0 0.25rem rgba(130, 138, 145, 0.5); -} -.btn-check:checked + .btn-secondary, .btn-check:active + .btn-secondary, .btn-secondary:active, .btn-secondary.active, .show > .btn-secondary.dropdown-toggle { - color: #fff; - background-color: #565e64; - border-color: #51585e; -} -.btn-check:checked + .btn-secondary:focus, .btn-check:active + .btn-secondary:focus, .btn-secondary:active:focus, .btn-secondary.active:focus, .show > .btn-secondary.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(130, 138, 145, 0.5); -} -.btn-secondary:disabled, .btn-secondary.disabled { - color: #fff; - background-color: #6c757d; - border-color: #6c757d; -} - -.btn-success { - color: #fff; - background-color: #198754; - border-color: #198754; -} -.btn-success:hover { - color: #fff; - background-color: #157347; - border-color: #146c43; -} -.btn-check:focus + .btn-success, .btn-success:focus { - color: #fff; - background-color: #157347; - border-color: #146c43; - box-shadow: 0 0 0 0.25rem rgba(60, 153, 110, 0.5); -} -.btn-check:checked + .btn-success, .btn-check:active + .btn-success, .btn-success:active, .btn-success.active, .show > .btn-success.dropdown-toggle { - color: #fff; - background-color: #146c43; - border-color: #13653f; -} -.btn-check:checked + .btn-success:focus, .btn-check:active + .btn-success:focus, .btn-success:active:focus, .btn-success.active:focus, .show > .btn-success.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(60, 153, 110, 0.5); -} -.btn-success:disabled, .btn-success.disabled { - color: #fff; - background-color: #198754; - border-color: #198754; -} - -.btn-info { - color: #000; - background-color: #0dcaf0; - border-color: #0dcaf0; -} -.btn-info:hover { - color: #000; - background-color: #31d2f2; - border-color: #25cff2; -} -.btn-check:focus + .btn-info, .btn-info:focus { - color: #000; - background-color: #31d2f2; - border-color: #25cff2; - box-shadow: 0 0 0 0.25rem rgba(11, 172, 204, 0.5); -} -.btn-check:checked + .btn-info, .btn-check:active + .btn-info, .btn-info:active, .btn-info.active, .show > .btn-info.dropdown-toggle { - color: #000; - background-color: #3dd5f3; - border-color: #25cff2; -} -.btn-check:checked + .btn-info:focus, .btn-check:active + .btn-info:focus, .btn-info:active:focus, .btn-info.active:focus, .show > .btn-info.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(11, 172, 204, 0.5); -} -.btn-info:disabled, .btn-info.disabled { - color: #000; - background-color: #0dcaf0; - border-color: #0dcaf0; -} - -.btn-warning { - color: #000; - background-color: #ffc107; - border-color: #ffc107; -} -.btn-warning:hover { - color: #000; - background-color: #ffca2c; - border-color: #ffc720; -} -.btn-check:focus + .btn-warning, .btn-warning:focus { - color: #000; - background-color: #ffca2c; - border-color: #ffc720; - box-shadow: 0 0 0 0.25rem rgba(217, 164, 6, 0.5); -} -.btn-check:checked + .btn-warning, .btn-check:active + .btn-warning, .btn-warning:active, .btn-warning.active, .show > .btn-warning.dropdown-toggle { - color: #000; - background-color: #ffcd39; - border-color: #ffc720; -} -.btn-check:checked + .btn-warning:focus, .btn-check:active + .btn-warning:focus, .btn-warning:active:focus, .btn-warning.active:focus, .show > .btn-warning.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(217, 164, 6, 0.5); -} -.btn-warning:disabled, .btn-warning.disabled { - color: #000; - background-color: #ffc107; - border-color: #ffc107; -} - -.btn-danger { - color: #fff; - background-color: #dc3545; - border-color: #dc3545; -} -.btn-danger:hover { - color: #fff; - background-color: #bb2d3b; - border-color: #b02a37; -} -.btn-check:focus + .btn-danger, .btn-danger:focus { - color: #fff; - background-color: #bb2d3b; - border-color: #b02a37; - box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5); -} -.btn-check:checked + .btn-danger, .btn-check:active + .btn-danger, .btn-danger:active, .btn-danger.active, .show > .btn-danger.dropdown-toggle { - color: #fff; - background-color: #b02a37; - border-color: #a52834; -} -.btn-check:checked + .btn-danger:focus, .btn-check:active + .btn-danger:focus, .btn-danger:active:focus, .btn-danger.active:focus, .show > .btn-danger.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5); -} -.btn-danger:disabled, .btn-danger.disabled { - color: #fff; - background-color: #dc3545; - border-color: #dc3545; -} - -.btn-light { - color: #000; - background-color: #f8f9fa; - border-color: #f8f9fa; -} -.btn-light:hover { - color: #000; - background-color: #f9fafb; - border-color: #f9fafb; -} -.btn-check:focus + .btn-light, .btn-light:focus { - color: #000; - background-color: #f9fafb; - border-color: #f9fafb; - box-shadow: 0 0 0 0.25rem rgba(211, 212, 213, 0.5); -} -.btn-check:checked + .btn-light, .btn-check:active + .btn-light, .btn-light:active, .btn-light.active, .show > .btn-light.dropdown-toggle { - color: #000; - background-color: #f9fafb; - border-color: #f9fafb; -} -.btn-check:checked + .btn-light:focus, .btn-check:active + .btn-light:focus, .btn-light:active:focus, .btn-light.active:focus, .show > .btn-light.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(211, 212, 213, 0.5); -} -.btn-light:disabled, .btn-light.disabled { - color: #000; - background-color: #f8f9fa; - border-color: #f8f9fa; -} - -.btn-dark { - color: #fff; - background-color: #212529; - border-color: #212529; -} -.btn-dark:hover { - color: #fff; - background-color: #1c1f23; - border-color: #1a1e21; -} -.btn-check:focus + .btn-dark, .btn-dark:focus { - color: #fff; - background-color: #1c1f23; - border-color: #1a1e21; - box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5); -} -.btn-check:checked + .btn-dark, .btn-check:active + .btn-dark, .btn-dark:active, .btn-dark.active, .show > .btn-dark.dropdown-toggle { - color: #fff; - background-color: #1a1e21; - border-color: #191c1f; -} -.btn-check:checked + .btn-dark:focus, .btn-check:active + .btn-dark:focus, .btn-dark:active:focus, .btn-dark.active:focus, .show > .btn-dark.dropdown-toggle:focus { - box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5); -} -.btn-dark:disabled, .btn-dark.disabled { - color: #fff; - background-color: #212529; - border-color: #212529; -} - -.btn-outline-primary { - color: #0d6efd; - border-color: #0d6efd; -} -.btn-outline-primary:hover { - color: #fff; - background-color: #0d6efd; - border-color: #0d6efd; -} -.btn-check:focus + .btn-outline-primary, .btn-outline-primary:focus { - box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.5); -} -.btn-check:checked + .btn-outline-primary, .btn-check:active + .btn-outline-primary, .btn-outline-primary:active, .btn-outline-primary.active, .btn-outline-primary.dropdown-toggle.show { - color: #fff; - background-color: #0d6efd; - border-color: #0d6efd; -} -.btn-check:checked + .btn-outline-primary:focus, .btn-check:active + .btn-outline-primary:focus, .btn-outline-primary:active:focus, .btn-outline-primary.active:focus, .btn-outline-primary.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.5); -} -.btn-outline-primary:disabled, .btn-outline-primary.disabled { - color: #0d6efd; - background-color: transparent; -} - -.btn-outline-secondary { - color: #6c757d; - border-color: #6c757d; -} -.btn-outline-secondary:hover { - color: #fff; - background-color: #6c757d; - border-color: #6c757d; -} -.btn-check:focus + .btn-outline-secondary, .btn-outline-secondary:focus { - box-shadow: 0 0 0 0.25rem rgba(108, 117, 125, 0.5); -} -.btn-check:checked + .btn-outline-secondary, .btn-check:active + .btn-outline-secondary, .btn-outline-secondary:active, .btn-outline-secondary.active, .btn-outline-secondary.dropdown-toggle.show { - color: #fff; - background-color: #6c757d; - border-color: #6c757d; -} -.btn-check:checked + .btn-outline-secondary:focus, .btn-check:active + .btn-outline-secondary:focus, .btn-outline-secondary:active:focus, .btn-outline-secondary.active:focus, .btn-outline-secondary.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(108, 117, 125, 0.5); -} -.btn-outline-secondary:disabled, .btn-outline-secondary.disabled { - color: #6c757d; - background-color: transparent; -} - -.btn-outline-success { - color: #198754; - border-color: #198754; -} -.btn-outline-success:hover { - color: #fff; - background-color: #198754; - border-color: #198754; -} -.btn-check:focus + .btn-outline-success, .btn-outline-success:focus { - box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.5); -} -.btn-check:checked + .btn-outline-success, .btn-check:active + .btn-outline-success, .btn-outline-success:active, .btn-outline-success.active, .btn-outline-success.dropdown-toggle.show { - color: #fff; - background-color: #198754; - border-color: #198754; -} -.btn-check:checked + .btn-outline-success:focus, .btn-check:active + .btn-outline-success:focus, .btn-outline-success:active:focus, .btn-outline-success.active:focus, .btn-outline-success.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.5); -} -.btn-outline-success:disabled, .btn-outline-success.disabled { - color: #198754; - background-color: transparent; -} - -.btn-outline-info { - color: #0dcaf0; - border-color: #0dcaf0; -} -.btn-outline-info:hover { - color: #000; - background-color: #0dcaf0; - border-color: #0dcaf0; -} -.btn-check:focus + .btn-outline-info, .btn-outline-info:focus { - box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.5); -} -.btn-check:checked + .btn-outline-info, .btn-check:active + .btn-outline-info, .btn-outline-info:active, .btn-outline-info.active, .btn-outline-info.dropdown-toggle.show { - color: #000; - background-color: #0dcaf0; - border-color: #0dcaf0; -} -.btn-check:checked + .btn-outline-info:focus, .btn-check:active + .btn-outline-info:focus, .btn-outline-info:active:focus, .btn-outline-info.active:focus, .btn-outline-info.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.5); -} -.btn-outline-info:disabled, .btn-outline-info.disabled { - color: #0dcaf0; - background-color: transparent; -} - -.btn-outline-warning { - color: #ffc107; - border-color: #ffc107; -} -.btn-outline-warning:hover { - color: #000; - background-color: #ffc107; - border-color: #ffc107; -} -.btn-check:focus + .btn-outline-warning, .btn-outline-warning:focus { - box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5); -} -.btn-check:checked + .btn-outline-warning, .btn-check:active + .btn-outline-warning, .btn-outline-warning:active, .btn-outline-warning.active, .btn-outline-warning.dropdown-toggle.show { - color: #000; - background-color: #ffc107; - border-color: #ffc107; -} -.btn-check:checked + .btn-outline-warning:focus, .btn-check:active + .btn-outline-warning:focus, .btn-outline-warning:active:focus, .btn-outline-warning.active:focus, .btn-outline-warning.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5); -} -.btn-outline-warning:disabled, .btn-outline-warning.disabled { - color: #ffc107; - background-color: transparent; -} - -.btn-outline-danger { - color: #dc3545; - border-color: #dc3545; -} -.btn-outline-danger:hover { - color: #fff; - background-color: #dc3545; - border-color: #dc3545; -} -.btn-check:focus + .btn-outline-danger, .btn-outline-danger:focus { - box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.5); -} -.btn-check:checked + .btn-outline-danger, .btn-check:active + .btn-outline-danger, .btn-outline-danger:active, .btn-outline-danger.active, .btn-outline-danger.dropdown-toggle.show { - color: #fff; - background-color: #dc3545; - border-color: #dc3545; -} -.btn-check:checked + .btn-outline-danger:focus, .btn-check:active + .btn-outline-danger:focus, .btn-outline-danger:active:focus, .btn-outline-danger.active:focus, .btn-outline-danger.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.5); -} -.btn-outline-danger:disabled, .btn-outline-danger.disabled { - color: #dc3545; - background-color: transparent; -} - -.btn-outline-light { - color: #f8f9fa; - border-color: #f8f9fa; -} -.btn-outline-light:hover { - color: #000; - background-color: #f8f9fa; - border-color: #f8f9fa; -} -.btn-check:focus + .btn-outline-light, .btn-outline-light:focus { - box-shadow: 0 0 0 0.25rem rgba(248, 249, 250, 0.5); -} -.btn-check:checked + .btn-outline-light, .btn-check:active + .btn-outline-light, .btn-outline-light:active, .btn-outline-light.active, .btn-outline-light.dropdown-toggle.show { - color: #000; - background-color: #f8f9fa; - border-color: #f8f9fa; -} -.btn-check:checked + .btn-outline-light:focus, .btn-check:active + .btn-outline-light:focus, .btn-outline-light:active:focus, .btn-outline-light.active:focus, .btn-outline-light.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(248, 249, 250, 0.5); -} -.btn-outline-light:disabled, .btn-outline-light.disabled { - color: #f8f9fa; - background-color: transparent; -} - -.btn-outline-dark { - color: #212529; - border-color: #212529; -} -.btn-outline-dark:hover { - color: #fff; - background-color: #212529; - border-color: #212529; -} -.btn-check:focus + .btn-outline-dark, .btn-outline-dark:focus { - box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5); -} -.btn-check:checked + .btn-outline-dark, .btn-check:active + .btn-outline-dark, .btn-outline-dark:active, .btn-outline-dark.active, .btn-outline-dark.dropdown-toggle.show { - color: #fff; - background-color: #212529; - border-color: #212529; -} -.btn-check:checked + .btn-outline-dark:focus, .btn-check:active + .btn-outline-dark:focus, .btn-outline-dark:active:focus, .btn-outline-dark.active:focus, .btn-outline-dark.dropdown-toggle.show:focus { - box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5); -} -.btn-outline-dark:disabled, .btn-outline-dark.disabled { - color: #212529; - background-color: transparent; -} - -.btn-link { - font-weight: 400; - color: #0d6efd; - text-decoration: underline; -} -.btn-link:hover { - color: #0a58ca; -} -.btn-link:disabled, .btn-link.disabled { - color: #6c757d; -} - -.btn-lg, .btn-group-lg > .btn { - padding: 0.5rem 1rem; - font-size: 1.25rem; - border-radius: 0.3rem; -} - -.btn-sm, .btn-group-sm > .btn { - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - border-radius: 0.2rem; -} - -.fade { - transition: opacity 0.15s linear; -} -@media (prefers-reduced-motion: reduce) { - .fade { - transition: none; - } -} -.fade:not(.show) { - opacity: 0; -} - -.collapse:not(.show) { - display: none; -} - -.collapsing { - height: 0; - overflow: hidden; - transition: height 0.35s ease; -} -@media (prefers-reduced-motion: reduce) { - .collapsing { - transition: none; - } -} - -.dropup, -.dropend, -.dropdown, -.dropstart { - position: relative; -} - -.dropdown-toggle { - white-space: nowrap; -} -.dropdown-toggle::after { - display: inline-block; - margin-left: 0.255em; - vertical-align: 0.255em; - content: ""; - border-top: 0.3em solid; - border-right: 0.3em solid transparent; - border-bottom: 0; - border-left: 0.3em solid transparent; -} -.dropdown-toggle:empty::after { - margin-left: 0; -} - -.dropdown-menu { - position: absolute; - z-index: 1000; - display: none; - min-width: 10rem; - padding: 0.5rem 0; - margin: 0; - font-size: 1rem; - color: #212529; - text-align: left; - list-style: none; - background-color: #fff; - background-clip: padding-box; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 0.25rem; -} -.dropdown-menu[data-bs-popper] { - top: 100%; - left: 0; - margin-top: 0.125rem; -} - -.dropdown-menu-start { - --bs-position: start; -} -.dropdown-menu-start[data-bs-popper] { - right: auto /* rtl:ignore */; - left: 0 /* rtl:ignore */; -} - -.dropdown-menu-end { - --bs-position: end; -} -.dropdown-menu-end[data-bs-popper] { - right: 0 /* rtl:ignore */; - left: auto /* rtl:ignore */; -} - -@media (min-width: 576px) { - .dropdown-menu-sm-start { - --bs-position: start; - } - .dropdown-menu-sm-start[data-bs-popper] { - right: auto /* rtl:ignore */; - left: 0 /* rtl:ignore */; - } - - .dropdown-menu-sm-end { - --bs-position: end; - } - .dropdown-menu-sm-end[data-bs-popper] { - right: 0 /* rtl:ignore */; - left: auto /* rtl:ignore */; - } -} -@media (min-width: 768px) { - .dropdown-menu-md-start { - --bs-position: start; - } - .dropdown-menu-md-start[data-bs-popper] { - right: auto /* rtl:ignore */; - left: 0 /* rtl:ignore */; - } - - .dropdown-menu-md-end { - --bs-position: end; - } - .dropdown-menu-md-end[data-bs-popper] { - right: 0 /* rtl:ignore */; - left: auto /* rtl:ignore */; - } -} -@media (min-width: 992px) { - .dropdown-menu-lg-start { - --bs-position: start; - } - .dropdown-menu-lg-start[data-bs-popper] { - right: auto /* rtl:ignore */; - left: 0 /* rtl:ignore */; - } - - .dropdown-menu-lg-end { - --bs-position: end; - } - .dropdown-menu-lg-end[data-bs-popper] { - right: 0 /* rtl:ignore */; - left: auto /* rtl:ignore */; - } -} -@media (min-width: 1200px) { - .dropdown-menu-xl-start { - --bs-position: start; - } - .dropdown-menu-xl-start[data-bs-popper] { - right: auto /* rtl:ignore */; - left: 0 /* rtl:ignore */; - } - - .dropdown-menu-xl-end { - --bs-position: end; - } - .dropdown-menu-xl-end[data-bs-popper] { - right: 0 /* rtl:ignore */; - left: auto /* rtl:ignore */; - } -} -@media (min-width: 1400px) { - .dropdown-menu-xxl-start { - --bs-position: start; - } - .dropdown-menu-xxl-start[data-bs-popper] { - right: auto /* rtl:ignore */; - left: 0 /* rtl:ignore */; - } - - .dropdown-menu-xxl-end { - --bs-position: end; - } - .dropdown-menu-xxl-end[data-bs-popper] { - right: 0 /* rtl:ignore */; - left: auto /* rtl:ignore */; - } -} -.dropup .dropdown-menu[data-bs-popper] { - top: auto; - bottom: 100%; - margin-top: 0; - margin-bottom: 0.125rem; -} -.dropup .dropdown-toggle::after { - display: inline-block; - margin-left: 0.255em; - vertical-align: 0.255em; - content: ""; - border-top: 0; - border-right: 0.3em solid transparent; - border-bottom: 0.3em solid; - border-left: 0.3em solid transparent; -} -.dropup .dropdown-toggle:empty::after { - margin-left: 0; -} - -.dropend .dropdown-menu[data-bs-popper] { - top: 0; - right: auto; - left: 100%; - margin-top: 0; - margin-left: 0.125rem; -} -.dropend .dropdown-toggle::after { - display: inline-block; - margin-left: 0.255em; - vertical-align: 0.255em; - content: ""; - border-top: 0.3em solid transparent; - border-right: 0; - border-bottom: 0.3em solid transparent; - border-left: 0.3em solid; -} -.dropend .dropdown-toggle:empty::after { - margin-left: 0; -} -.dropend .dropdown-toggle::after { - vertical-align: 0; -} - -.dropstart .dropdown-menu[data-bs-popper] { - top: 0; - right: 100%; - left: auto; - margin-top: 0; - margin-right: 0.125rem; -} -.dropstart .dropdown-toggle::after { - display: inline-block; - margin-left: 0.255em; - vertical-align: 0.255em; - content: ""; -} -.dropstart .dropdown-toggle::after { - display: none; -} -.dropstart .dropdown-toggle::before { - display: inline-block; - margin-right: 0.255em; - vertical-align: 0.255em; - content: ""; - border-top: 0.3em solid transparent; - border-right: 0.3em solid; - border-bottom: 0.3em solid transparent; -} -.dropstart .dropdown-toggle:empty::after { - margin-left: 0; -} -.dropstart .dropdown-toggle::before { - vertical-align: 0; -} - -.dropdown-divider { - height: 0; - margin: 0.5rem 0; - overflow: hidden; - border-top: 1px solid rgba(0, 0, 0, 0.15); -} - -.dropdown-item { - display: block; - padding: 0.25rem 1rem; - clear: both; - font-weight: 400; - color: #212529; - text-align: inherit; - text-decoration: none; - white-space: nowrap; - background-color: transparent; - border: 0; -} -.dropdown-item:hover, .dropdown-item:focus { - color: #1e2125; - background-color: #e9ecef; -} -.dropdown-item.active, .dropdown-item:active { - color: #fff; - text-decoration: none; - background-color: #0d6efd; -} -.dropdown-item.disabled, .dropdown-item:disabled { - color: #adb5bd; - pointer-events: none; - background-color: transparent; -} - -.dropdown-menu.show { - display: block; -} - -.dropdown-header { - display: block; - padding: 0.5rem 1rem; - margin-bottom: 0; - font-size: 0.875rem; - color: #6c757d; - white-space: nowrap; -} - -.dropdown-item-text { - display: block; - padding: 0.25rem 1rem; - color: #212529; -} - -.dropdown-menu-dark { - color: #dee2e6; - background-color: #343a40; - border-color: rgba(0, 0, 0, 0.15); -} -.dropdown-menu-dark .dropdown-item { - color: #dee2e6; -} -.dropdown-menu-dark .dropdown-item:hover, .dropdown-menu-dark .dropdown-item:focus { - color: #fff; - background-color: rgba(255, 255, 255, 0.15); -} -.dropdown-menu-dark .dropdown-item.active, .dropdown-menu-dark .dropdown-item:active { - color: #fff; - background-color: #0d6efd; -} -.dropdown-menu-dark .dropdown-item.disabled, .dropdown-menu-dark .dropdown-item:disabled { - color: #adb5bd; -} -.dropdown-menu-dark .dropdown-divider { - border-color: rgba(0, 0, 0, 0.15); -} -.dropdown-menu-dark .dropdown-item-text { - color: #dee2e6; -} -.dropdown-menu-dark .dropdown-header { - color: #adb5bd; -} - -.btn-group, -.btn-group-vertical { - position: relative; - display: inline-flex; - vertical-align: middle; -} -.btn-group > .btn, -.btn-group-vertical > .btn { - position: relative; - flex: 1 1 auto; -} -.btn-group > .btn-check:checked + .btn, -.btn-group > .btn-check:focus + .btn, -.btn-group > .btn:hover, -.btn-group > .btn:focus, -.btn-group > .btn:active, -.btn-group > .btn.active, -.btn-group-vertical > .btn-check:checked + .btn, -.btn-group-vertical > .btn-check:focus + .btn, -.btn-group-vertical > .btn:hover, -.btn-group-vertical > .btn:focus, -.btn-group-vertical > .btn:active, -.btn-group-vertical > .btn.active { - z-index: 1; -} - -.btn-toolbar { - display: flex; - flex-wrap: wrap; - justify-content: flex-start; -} -.btn-toolbar .input-group { - width: auto; -} - -.btn-group > .btn:not(:first-child), -.btn-group > .btn-group:not(:first-child) { - margin-left: -1px; -} -.btn-group > .btn:not(:last-child):not(.dropdown-toggle), -.btn-group > .btn-group:not(:last-child) > .btn { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} -.btn-group > .btn:nth-child(n+3), -.btn-group > :not(.btn-check) + .btn, -.btn-group > .btn-group:not(:first-child) > .btn { - border-top-left-radius: 0; - border-bottom-left-radius: 0; -} - -.dropdown-toggle-split { - padding-right: 0.5625rem; - padding-left: 0.5625rem; -} -.dropdown-toggle-split::after, .dropup .dropdown-toggle-split::after, .dropend .dropdown-toggle-split::after { - margin-left: 0; -} -.dropstart .dropdown-toggle-split::before { - margin-right: 0; -} - -.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split { - padding-right: 0.375rem; - padding-left: 0.375rem; -} - -.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split { - padding-right: 0.75rem; - padding-left: 0.75rem; -} - -.btn-group-vertical { - flex-direction: column; - align-items: flex-start; - justify-content: center; -} -.btn-group-vertical > .btn, -.btn-group-vertical > .btn-group { - width: 100%; -} -.btn-group-vertical > .btn:not(:first-child), -.btn-group-vertical > .btn-group:not(:first-child) { - margin-top: -1px; -} -.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle), -.btn-group-vertical > .btn-group:not(:last-child) > .btn { - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} -.btn-group-vertical > .btn ~ .btn, -.btn-group-vertical > .btn-group:not(:first-child) > .btn { - border-top-left-radius: 0; - border-top-right-radius: 0; -} - -.nav { - display: flex; - flex-wrap: wrap; - padding-left: 0; - margin-bottom: 0; - list-style: none; -} - -.nav-link { - display: block; - padding: 0.5rem 1rem; - color: #0d6efd; - text-decoration: none; - transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .nav-link { - transition: none; - } -} -.nav-link:hover, .nav-link:focus { - color: #0a58ca; -} -.nav-link.disabled { - color: #6c757d; - pointer-events: none; - cursor: default; -} - -.nav-tabs { - border-bottom: 1px solid #dee2e6; -} -.nav-tabs .nav-link { - margin-bottom: -1px; - background: none; - border: 1px solid transparent; - border-top-left-radius: 0.25rem; - border-top-right-radius: 0.25rem; -} -.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus { - border-color: #e9ecef #e9ecef #dee2e6; - isolation: isolate; -} -.nav-tabs .nav-link.disabled { - color: #6c757d; - background-color: transparent; - border-color: transparent; -} -.nav-tabs .nav-link.active, -.nav-tabs .nav-item.show .nav-link { - color: #495057; - background-color: #fff; - border-color: #dee2e6 #dee2e6 #fff; -} -.nav-tabs .dropdown-menu { - margin-top: -1px; - border-top-left-radius: 0; - border-top-right-radius: 0; -} - -.nav-pills .nav-link { - background: none; - border: 0; - border-radius: 0.25rem; -} -.nav-pills .nav-link.active, -.nav-pills .show > .nav-link { - color: #fff; - background-color: #0d6efd; -} - -.nav-fill > .nav-link, -.nav-fill .nav-item { - flex: 1 1 auto; - text-align: center; -} - -.nav-justified > .nav-link, -.nav-justified .nav-item { - flex-basis: 0; - flex-grow: 1; - text-align: center; -} - -.nav-fill .nav-item .nav-link, -.nav-justified .nav-item .nav-link { - width: 100%; -} - -.tab-content > .tab-pane { - display: none; -} -.tab-content > .active { - display: block; -} - -.navbar { - position: relative; - display: flex; - flex-wrap: wrap; - align-items: center; - justify-content: space-between; - padding-top: 0.5rem; - padding-bottom: 0.5rem; -} -.navbar > .container, -.navbar > .container-fluid, -.navbar > .container-sm, -.navbar > .container-md, -.navbar > .container-lg, -.navbar > .container-xl, -.navbar > .container-xxl { - display: flex; - flex-wrap: inherit; - align-items: center; - justify-content: space-between; -} -.navbar-brand { - padding-top: 0.3125rem; - padding-bottom: 0.3125rem; - margin-right: 1rem; - font-size: 1.25rem; - text-decoration: none; - white-space: nowrap; -} -.navbar-nav { - display: flex; - flex-direction: column; - padding-left: 0; - margin-bottom: 0; - list-style: none; -} -.navbar-nav .nav-link { - padding-right: 0; - padding-left: 0; -} -.navbar-nav .dropdown-menu { - position: static; -} - -.navbar-text { - padding-top: 0.5rem; - padding-bottom: 0.5rem; -} - -.navbar-collapse { - flex-basis: 100%; - flex-grow: 1; - align-items: center; -} - -.navbar-toggler { - padding: 0.25rem 0.75rem; - font-size: 1.25rem; - line-height: 1; - background-color: transparent; - border: 1px solid transparent; - border-radius: 0.25rem; - transition: box-shadow 0.15s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .navbar-toggler { - transition: none; - } -} -.navbar-toggler:hover { - text-decoration: none; -} -.navbar-toggler:focus { - text-decoration: none; - outline: 0; - box-shadow: 0 0 0 0.25rem; -} - -.navbar-toggler-icon { - display: inline-block; - width: 1.5em; - height: 1.5em; - vertical-align: middle; - background-repeat: no-repeat; - background-position: center; - background-size: 100%; -} - -.navbar-nav-scroll { - max-height: var(--bs-scroll-height, 75vh); - overflow-y: auto; -} - -@media (min-width: 576px) { - .navbar-expand-sm { - flex-wrap: nowrap; - justify-content: flex-start; - } - .navbar-expand-sm .navbar-nav { - flex-direction: row; - } - .navbar-expand-sm .navbar-nav .dropdown-menu { - position: absolute; - } - .navbar-expand-sm .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; - } - .navbar-expand-sm .navbar-nav-scroll { - overflow: visible; - } - .navbar-expand-sm .navbar-collapse { - display: flex !important; - flex-basis: auto; - } - .navbar-expand-sm .navbar-toggler { - display: none; - } -} -@media (min-width: 768px) { - .navbar-expand-md { - flex-wrap: nowrap; - justify-content: flex-start; - } - .navbar-expand-md .navbar-nav { - flex-direction: row; - } - .navbar-expand-md .navbar-nav .dropdown-menu { - position: absolute; - } - .navbar-expand-md .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; - } - .navbar-expand-md .navbar-nav-scroll { - overflow: visible; - } - .navbar-expand-md .navbar-collapse { - display: flex !important; - flex-basis: auto; - } - .navbar-expand-md .navbar-toggler { - display: none; - } -} -@media (min-width: 992px) { - .navbar-expand-lg { - flex-wrap: nowrap; - justify-content: flex-start; - } - .navbar-expand-lg .navbar-nav { - flex-direction: row; - } - .navbar-expand-lg .navbar-nav .dropdown-menu { - position: absolute; - } - .navbar-expand-lg .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; - } - .navbar-expand-lg .navbar-nav-scroll { - overflow: visible; - } - .navbar-expand-lg .navbar-collapse { - display: flex !important; - flex-basis: auto; - } - .navbar-expand-lg .navbar-toggler { - display: none; - } -} -@media (min-width: 1200px) { - .navbar-expand-xl { - flex-wrap: nowrap; - justify-content: flex-start; - } - .navbar-expand-xl .navbar-nav { - flex-direction: row; - } - .navbar-expand-xl .navbar-nav .dropdown-menu { - position: absolute; - } - .navbar-expand-xl .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; - } - .navbar-expand-xl .navbar-nav-scroll { - overflow: visible; - } - .navbar-expand-xl .navbar-collapse { - display: flex !important; - flex-basis: auto; - } - .navbar-expand-xl .navbar-toggler { - display: none; - } -} -@media (min-width: 1400px) { - .navbar-expand-xxl { - flex-wrap: nowrap; - justify-content: flex-start; - } - .navbar-expand-xxl .navbar-nav { - flex-direction: row; - } - .navbar-expand-xxl .navbar-nav .dropdown-menu { - position: absolute; - } - .navbar-expand-xxl .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; - } - .navbar-expand-xxl .navbar-nav-scroll { - overflow: visible; - } - .navbar-expand-xxl .navbar-collapse { - display: flex !important; - flex-basis: auto; - } - .navbar-expand-xxl .navbar-toggler { - display: none; - } -} -.navbar-expand { - flex-wrap: nowrap; - justify-content: flex-start; -} -.navbar-expand .navbar-nav { - flex-direction: row; -} -.navbar-expand .navbar-nav .dropdown-menu { - position: absolute; -} -.navbar-expand .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; -} -.navbar-expand .navbar-nav-scroll { - overflow: visible; -} -.navbar-expand .navbar-collapse { - display: flex !important; - flex-basis: auto; -} -.navbar-expand .navbar-toggler { - display: none; -} - -.navbar-light .navbar-brand { - color: rgba(0, 0, 0, 0.9); -} -.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus { - color: rgba(0, 0, 0, 0.9); -} -.navbar-light .navbar-nav .nav-link { - color: rgba(0, 0, 0, 0.55); -} -.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus { - color: rgba(0, 0, 0, 0.7); -} -.navbar-light .navbar-nav .nav-link.disabled { - color: rgba(0, 0, 0, 0.3); -} -.navbar-light .navbar-nav .show > .nav-link, -.navbar-light .navbar-nav .nav-link.active { - color: rgba(0, 0, 0, 0.9); -} -.navbar-light .navbar-toggler { - color: rgba(0, 0, 0, 0.55); - border-color: rgba(0, 0, 0, 0.1); -} -.navbar-light .navbar-toggler-icon { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); -} -.navbar-light .navbar-text { - color: rgba(0, 0, 0, 0.55); -} -.navbar-light .navbar-text a, -.navbar-light .navbar-text a:hover, -.navbar-light .navbar-text a:focus { - color: rgba(0, 0, 0, 0.9); -} - -.navbar-dark .navbar-brand { - color: #fff; -} -.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus { - color: #fff; -} -.navbar-dark .navbar-nav .nav-link { - color: rgba(255, 255, 255, 0.55); -} -.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus { - color: rgba(255, 255, 255, 0.75); -} -.navbar-dark .navbar-nav .nav-link.disabled { - color: rgba(255, 255, 255, 0.25); -} -.navbar-dark .navbar-nav .show > .nav-link, -.navbar-dark .navbar-nav .nav-link.active { - color: #fff; -} -.navbar-dark .navbar-toggler { - color: rgba(255, 255, 255, 0.55); - border-color: rgba(255, 255, 255, 0.1); -} -.navbar-dark .navbar-toggler-icon { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); -} -.navbar-dark .navbar-text { - color: rgba(255, 255, 255, 0.55); -} -.navbar-dark .navbar-text a, -.navbar-dark .navbar-text a:hover, -.navbar-dark .navbar-text a:focus { - color: #fff; -} - -.card { - position: relative; - display: flex; - flex-direction: column; - min-width: 0; - word-wrap: break-word; - background-color: #fff; - background-clip: border-box; - border: 1px solid rgba(0, 0, 0, 0.125); - border-radius: 0.25rem; -} -.card > hr { - margin-right: 0; - margin-left: 0; -} -.card > .list-group { - border-top: inherit; - border-bottom: inherit; -} -.card > .list-group:first-child { - border-top-width: 0; - border-top-left-radius: calc(0.25rem - 1px); - border-top-right-radius: calc(0.25rem - 1px); -} -.card > .list-group:last-child { - border-bottom-width: 0; - border-bottom-right-radius: calc(0.25rem - 1px); - border-bottom-left-radius: calc(0.25rem - 1px); -} -.card > .card-header + .list-group, -.card > .list-group + .card-footer { - border-top: 0; -} - -.card-body { - flex: 1 1 auto; - padding: 1rem 1rem; -} - -.card-title { - margin-bottom: 0.5rem; -} - -.card-subtitle { - margin-top: -0.25rem; - margin-bottom: 0; -} - -.card-text:last-child { - margin-bottom: 0; -} - -.card-link:hover { - text-decoration: none; -} -.card-link + .card-link { - margin-left: 1rem; -} - -.card-header { - padding: 0.5rem 1rem; - margin-bottom: 0; - background-color: rgba(0, 0, 0, 0.03); - border-bottom: 1px solid rgba(0, 0, 0, 0.125); -} -.card-header:first-child { - border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0; -} - -.card-footer { - padding: 0.5rem 1rem; - background-color: rgba(0, 0, 0, 0.03); - border-top: 1px solid rgba(0, 0, 0, 0.125); -} -.card-footer:last-child { - border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px); -} - -.card-header-tabs { - margin-right: -0.5rem; - margin-bottom: -0.5rem; - margin-left: -0.5rem; - border-bottom: 0; -} - -.card-header-pills { - margin-right: -0.5rem; - margin-left: -0.5rem; -} - -.card-img-overlay { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - padding: 1rem; - border-radius: calc(0.25rem - 1px); -} - -.card-img, -.card-img-top, -.card-img-bottom { - width: 100%; -} - -.card-img, -.card-img-top { - border-top-left-radius: calc(0.25rem - 1px); - border-top-right-radius: calc(0.25rem - 1px); -} - -.card-img, -.card-img-bottom { - border-bottom-right-radius: calc(0.25rem - 1px); - border-bottom-left-radius: calc(0.25rem - 1px); -} - -.card-group > .card { - margin-bottom: 0.75rem; -} -@media (min-width: 576px) { - .card-group { - display: flex; - flex-flow: row wrap; - } - .card-group > .card { - flex: 1 0 0%; - margin-bottom: 0; - } - .card-group > .card + .card { - margin-left: 0; - border-left: 0; - } - .card-group > .card:not(:last-child) { - border-top-right-radius: 0; - border-bottom-right-radius: 0; - } - .card-group > .card:not(:last-child) .card-img-top, -.card-group > .card:not(:last-child) .card-header { - border-top-right-radius: 0; - } - .card-group > .card:not(:last-child) .card-img-bottom, -.card-group > .card:not(:last-child) .card-footer { - border-bottom-right-radius: 0; - } - .card-group > .card:not(:first-child) { - border-top-left-radius: 0; - border-bottom-left-radius: 0; - } - .card-group > .card:not(:first-child) .card-img-top, -.card-group > .card:not(:first-child) .card-header { - border-top-left-radius: 0; - } - .card-group > .card:not(:first-child) .card-img-bottom, -.card-group > .card:not(:first-child) .card-footer { - border-bottom-left-radius: 0; - } -} - -.accordion-button { - position: relative; - display: flex; - align-items: center; - width: 100%; - padding: 1rem 1.25rem; - font-size: 1rem; - color: #212529; - text-align: left; - background-color: #fff; - border: 0; - border-radius: 0; - overflow-anchor: none; - transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease; -} -@media (prefers-reduced-motion: reduce) { - .accordion-button { - transition: none; - } -} -.accordion-button:not(.collapsed) { - color: #0c63e4; - background-color: #e7f1ff; - box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.125); -} -.accordion-button:not(.collapsed)::after { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); - transform: rotate(-180deg); -} -.accordion-button::after { - flex-shrink: 0; - width: 1.25rem; - height: 1.25rem; - margin-left: auto; - content: ""; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); - background-repeat: no-repeat; - background-size: 1.25rem; - transition: transform 0.2s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .accordion-button::after { - transition: none; - } -} -.accordion-button:hover { - z-index: 2; -} -.accordion-button:focus { - z-index: 3; - border-color: #86b7fe; - outline: 0; - box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); -} - -.accordion-header { - margin-bottom: 0; -} - -.accordion-item { - background-color: #fff; - border: 1px solid rgba(0, 0, 0, 0.125); -} -.accordion-item:first-of-type { - border-top-left-radius: 0.25rem; - border-top-right-radius: 0.25rem; -} -.accordion-item:first-of-type .accordion-button { - border-top-left-radius: calc(0.25rem - 1px); - border-top-right-radius: calc(0.25rem - 1px); -} -.accordion-item:not(:first-of-type) { - border-top: 0; -} -.accordion-item:last-of-type { - border-bottom-right-radius: 0.25rem; - border-bottom-left-radius: 0.25rem; -} -.accordion-item:last-of-type .accordion-button.collapsed { - border-bottom-right-radius: calc(0.25rem - 1px); - border-bottom-left-radius: calc(0.25rem - 1px); -} -.accordion-item:last-of-type .accordion-collapse { - border-bottom-right-radius: 0.25rem; - border-bottom-left-radius: 0.25rem; -} - -.accordion-body { - padding: 1rem 1.25rem; -} - -.accordion-flush .accordion-collapse { - border-width: 0; -} -.accordion-flush .accordion-item { - border-right: 0; - border-left: 0; - border-radius: 0; -} -.accordion-flush .accordion-item:first-child { - border-top: 0; -} -.accordion-flush .accordion-item:last-child { - border-bottom: 0; -} -.accordion-flush .accordion-item .accordion-button { - border-radius: 0; -} - -.breadcrumb { - display: flex; - flex-wrap: wrap; - padding: 0 0; - margin-bottom: 1rem; - list-style: none; -} - -.breadcrumb-item + .breadcrumb-item { - padding-left: 0.5rem; -} -.breadcrumb-item + .breadcrumb-item::before { - float: left; - padding-right: 0.5rem; - color: #6c757d; - content: var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */; -} -.breadcrumb-item.active { - color: #6c757d; -} - -.pagination { - display: flex; - padding-left: 0; - list-style: none; -} - -.page-link { - position: relative; - display: block; - color: #0d6efd; - text-decoration: none; - background-color: #fff; - border: 1px solid #dee2e6; - transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .page-link { - transition: none; - } -} -.page-link:hover { - z-index: 2; - color: #0a58ca; - background-color: #e9ecef; - border-color: #dee2e6; -} -.page-link:focus { - z-index: 3; - color: #0a58ca; - background-color: #e9ecef; - outline: 0; - box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); -} - -.page-item:not(:first-child) .page-link { - margin-left: -1px; -} -.page-item.active .page-link { - z-index: 3; - color: #fff; - background-color: #0d6efd; - border-color: #0d6efd; -} -.page-item.disabled .page-link { - color: #6c757d; - pointer-events: none; - background-color: #fff; - border-color: #dee2e6; -} - -.page-link { - padding: 0.375rem 0.75rem; -} - -.page-item:first-child .page-link { - border-top-left-radius: 0.25rem; - border-bottom-left-radius: 0.25rem; -} -.page-item:last-child .page-link { - border-top-right-radius: 0.25rem; - border-bottom-right-radius: 0.25rem; -} - -.pagination-lg .page-link { - padding: 0.75rem 1.5rem; - font-size: 1.25rem; -} -.pagination-lg .page-item:first-child .page-link { - border-top-left-radius: 0.3rem; - border-bottom-left-radius: 0.3rem; -} -.pagination-lg .page-item:last-child .page-link { - border-top-right-radius: 0.3rem; - border-bottom-right-radius: 0.3rem; -} - -.pagination-sm .page-link { - padding: 0.25rem 0.5rem; - font-size: 0.875rem; -} -.pagination-sm .page-item:first-child .page-link { - border-top-left-radius: 0.2rem; - border-bottom-left-radius: 0.2rem; -} -.pagination-sm .page-item:last-child .page-link { - border-top-right-radius: 0.2rem; - border-bottom-right-radius: 0.2rem; -} - -.badge { - display: inline-block; - padding: 0.35em 0.65em; - font-size: 0.75em; - font-weight: 700; - line-height: 1; - color: #fff; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - border-radius: 0.25rem; -} -.badge:empty { - display: none; -} - -.btn .badge { - position: relative; - top: -1px; -} - -.alert { - position: relative; - padding: 1rem 1rem; - margin-bottom: 1rem; - border: 1px solid transparent; - border-radius: 0.25rem; -} - -.alert-heading { - color: inherit; -} - -.alert-link { - font-weight: 700; -} - -.alert-dismissible { - padding-right: 3rem; -} -.alert-dismissible .btn-close { - position: absolute; - top: 0; - right: 0; - z-index: 2; - padding: 1.25rem 1rem; -} - -.alert-primary { - color: #084298; - background-color: #cfe2ff; - border-color: #b6d4fe; -} -.alert-primary .alert-link { - color: #06357a; -} - -.alert-secondary { - color: #41464b; - background-color: #e2e3e5; - border-color: #d3d6d8; -} -.alert-secondary .alert-link { - color: #34383c; -} - -.alert-success { - color: #0f5132; - background-color: #d1e7dd; - border-color: #badbcc; -} -.alert-success .alert-link { - color: #0c4128; -} - -.alert-info { - color: #055160; - background-color: #cff4fc; - border-color: #b6effb; -} -.alert-info .alert-link { - color: #04414d; -} - -.alert-warning { - color: #664d03; - background-color: #fff3cd; - border-color: #ffecb5; -} -.alert-warning .alert-link { - color: #523e02; -} - -.alert-danger { - color: #842029; - background-color: #f8d7da; - border-color: #f5c2c7; -} -.alert-danger .alert-link { - color: #6a1a21; -} - -.alert-light { - color: #636464; - background-color: #fefefe; - border-color: #fdfdfe; -} -.alert-light .alert-link { - color: #4f5050; -} - -.alert-dark { - color: #141619; - background-color: #d3d3d4; - border-color: #bcbebf; -} -.alert-dark .alert-link { - color: #101214; -} - -@-webkit-keyframes progress-bar-stripes { - 0% { - background-position-x: 1rem; - } -} - -@keyframes progress-bar-stripes { - 0% { - background-position-x: 1rem; - } -} -.progress { - display: flex; - height: 1rem; - overflow: hidden; - font-size: 0.75rem; - background-color: #e9ecef; - border-radius: 0.25rem; -} - -.progress-bar { - display: flex; - flex-direction: column; - justify-content: center; - overflow: hidden; - color: #fff; - text-align: center; - white-space: nowrap; - background-color: #0d6efd; - transition: width 0.6s ease; -} -@media (prefers-reduced-motion: reduce) { - .progress-bar { - transition: none; - } -} - -.progress-bar-striped { - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-size: 1rem 1rem; -} - -.progress-bar-animated { - -webkit-animation: 1s linear infinite progress-bar-stripes; - animation: 1s linear infinite progress-bar-stripes; -} -@media (prefers-reduced-motion: reduce) { - .progress-bar-animated { - -webkit-animation: none; - animation: none; - } -} - -.list-group { - display: flex; - flex-direction: column; - padding-left: 0; - margin-bottom: 0; - border-radius: 0.25rem; -} - -.list-group-numbered { - list-style-type: none; - counter-reset: section; -} -.list-group-numbered > li::before { - content: counters(section, ".") ". "; - counter-increment: section; -} - -.list-group-item-action { - width: 100%; - color: #495057; - text-align: inherit; -} -.list-group-item-action:hover, .list-group-item-action:focus { - z-index: 1; - color: #495057; - text-decoration: none; - background-color: #f8f9fa; -} -.list-group-item-action:active { - color: #212529; - background-color: #e9ecef; -} - -.list-group-item { - position: relative; - display: block; - padding: 0.5rem 1rem; - color: #212529; - text-decoration: none; - background-color: #fff; - border: 1px solid rgba(0, 0, 0, 0.125); -} -.list-group-item:first-child { - border-top-left-radius: inherit; - border-top-right-radius: inherit; -} -.list-group-item:last-child { - border-bottom-right-radius: inherit; - border-bottom-left-radius: inherit; -} -.list-group-item.disabled, .list-group-item:disabled { - color: #6c757d; - pointer-events: none; - background-color: #fff; -} -.list-group-item.active { - z-index: 2; - color: #fff; - background-color: #0d6efd; - border-color: #0d6efd; -} -.list-group-item + .list-group-item { - border-top-width: 0; -} -.list-group-item + .list-group-item.active { - margin-top: -1px; - border-top-width: 1px; -} - -.list-group-horizontal { - flex-direction: row; -} -.list-group-horizontal > .list-group-item:first-child { - border-bottom-left-radius: 0.25rem; - border-top-right-radius: 0; -} -.list-group-horizontal > .list-group-item:last-child { - border-top-right-radius: 0.25rem; - border-bottom-left-radius: 0; -} -.list-group-horizontal > .list-group-item.active { - margin-top: 0; -} -.list-group-horizontal > .list-group-item + .list-group-item { - border-top-width: 1px; - border-left-width: 0; -} -.list-group-horizontal > .list-group-item + .list-group-item.active { - margin-left: -1px; - border-left-width: 1px; -} - -@media (min-width: 576px) { - .list-group-horizontal-sm { - flex-direction: row; - } - .list-group-horizontal-sm > .list-group-item:first-child { - border-bottom-left-radius: 0.25rem; - border-top-right-radius: 0; - } - .list-group-horizontal-sm > .list-group-item:last-child { - border-top-right-radius: 0.25rem; - border-bottom-left-radius: 0; - } - .list-group-horizontal-sm > .list-group-item.active { - margin-top: 0; - } - .list-group-horizontal-sm > .list-group-item + .list-group-item { - border-top-width: 1px; - border-left-width: 0; - } - .list-group-horizontal-sm > .list-group-item + .list-group-item.active { - margin-left: -1px; - border-left-width: 1px; - } -} -@media (min-width: 768px) { - .list-group-horizontal-md { - flex-direction: row; - } - .list-group-horizontal-md > .list-group-item:first-child { - border-bottom-left-radius: 0.25rem; - border-top-right-radius: 0; - } - .list-group-horizontal-md > .list-group-item:last-child { - border-top-right-radius: 0.25rem; - border-bottom-left-radius: 0; - } - .list-group-horizontal-md > .list-group-item.active { - margin-top: 0; - } - .list-group-horizontal-md > .list-group-item + .list-group-item { - border-top-width: 1px; - border-left-width: 0; - } - .list-group-horizontal-md > .list-group-item + .list-group-item.active { - margin-left: -1px; - border-left-width: 1px; - } -} -@media (min-width: 992px) { - .list-group-horizontal-lg { - flex-direction: row; - } - .list-group-horizontal-lg > .list-group-item:first-child { - border-bottom-left-radius: 0.25rem; - border-top-right-radius: 0; - } - .list-group-horizontal-lg > .list-group-item:last-child { - border-top-right-radius: 0.25rem; - border-bottom-left-radius: 0; - } - .list-group-horizontal-lg > .list-group-item.active { - margin-top: 0; - } - .list-group-horizontal-lg > .list-group-item + .list-group-item { - border-top-width: 1px; - border-left-width: 0; - } - .list-group-horizontal-lg > .list-group-item + .list-group-item.active { - margin-left: -1px; - border-left-width: 1px; - } -} -@media (min-width: 1200px) { - .list-group-horizontal-xl { - flex-direction: row; - } - .list-group-horizontal-xl > .list-group-item:first-child { - border-bottom-left-radius: 0.25rem; - border-top-right-radius: 0; - } - .list-group-horizontal-xl > .list-group-item:last-child { - border-top-right-radius: 0.25rem; - border-bottom-left-radius: 0; - } - .list-group-horizontal-xl > .list-group-item.active { - margin-top: 0; - } - .list-group-horizontal-xl > .list-group-item + .list-group-item { - border-top-width: 1px; - border-left-width: 0; - } - .list-group-horizontal-xl > .list-group-item + .list-group-item.active { - margin-left: -1px; - border-left-width: 1px; - } -} -@media (min-width: 1400px) { - .list-group-horizontal-xxl { - flex-direction: row; - } - .list-group-horizontal-xxl > .list-group-item:first-child { - border-bottom-left-radius: 0.25rem; - border-top-right-radius: 0; - } - .list-group-horizontal-xxl > .list-group-item:last-child { - border-top-right-radius: 0.25rem; - border-bottom-left-radius: 0; - } - .list-group-horizontal-xxl > .list-group-item.active { - margin-top: 0; - } - .list-group-horizontal-xxl > .list-group-item + .list-group-item { - border-top-width: 1px; - border-left-width: 0; - } - .list-group-horizontal-xxl > .list-group-item + .list-group-item.active { - margin-left: -1px; - border-left-width: 1px; - } -} -.list-group-flush { - border-radius: 0; -} -.list-group-flush > .list-group-item { - border-width: 0 0 1px; -} -.list-group-flush > .list-group-item:last-child { - border-bottom-width: 0; -} - -.list-group-item-primary { - color: #084298; - background-color: #cfe2ff; -} -.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus { - color: #084298; - background-color: #bacbe6; -} -.list-group-item-primary.list-group-item-action.active { - color: #fff; - background-color: #084298; - border-color: #084298; -} - -.list-group-item-secondary { - color: #41464b; - background-color: #e2e3e5; -} -.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus { - color: #41464b; - background-color: #cbccce; -} -.list-group-item-secondary.list-group-item-action.active { - color: #fff; - background-color: #41464b; - border-color: #41464b; -} - -.list-group-item-success { - color: #0f5132; - background-color: #d1e7dd; -} -.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus { - color: #0f5132; - background-color: #bcd0c7; -} -.list-group-item-success.list-group-item-action.active { - color: #fff; - background-color: #0f5132; - border-color: #0f5132; -} - -.list-group-item-info { - color: #055160; - background-color: #cff4fc; -} -.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus { - color: #055160; - background-color: #badce3; -} -.list-group-item-info.list-group-item-action.active { - color: #fff; - background-color: #055160; - border-color: #055160; -} - -.list-group-item-warning { - color: #664d03; - background-color: #fff3cd; -} -.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus { - color: #664d03; - background-color: #e6dbb9; -} -.list-group-item-warning.list-group-item-action.active { - color: #fff; - background-color: #664d03; - border-color: #664d03; -} - -.list-group-item-danger { - color: #842029; - background-color: #f8d7da; -} -.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus { - color: #842029; - background-color: #dfc2c4; -} -.list-group-item-danger.list-group-item-action.active { - color: #fff; - background-color: #842029; - border-color: #842029; -} - -.list-group-item-light { - color: #636464; - background-color: #fefefe; -} -.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus { - color: #636464; - background-color: #e5e5e5; -} -.list-group-item-light.list-group-item-action.active { - color: #fff; - background-color: #636464; - border-color: #636464; -} - -.list-group-item-dark { - color: #141619; - background-color: #d3d3d4; -} -.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus { - color: #141619; - background-color: #bebebf; -} -.list-group-item-dark.list-group-item-action.active { - color: #fff; - background-color: #141619; - border-color: #141619; -} - -.btn-close { - box-sizing: content-box; - width: 1em; - height: 1em; - padding: 0.25em 0.25em; - color: #000; - background: transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat; - border: 0; - border-radius: 0.25rem; - opacity: 0.5; -} -.btn-close:hover { - color: #000; - text-decoration: none; - opacity: 0.75; -} -.btn-close:focus { - outline: 0; - box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); - opacity: 1; -} -.btn-close:disabled, .btn-close.disabled { - pointer-events: none; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; - opacity: 0.25; -} - -.btn-close-white { - filter: invert(1) grayscale(100%) brightness(200%); -} - -.toast { - width: 350px; - max-width: 100%; - font-size: 0.875rem; - pointer-events: auto; - background-color: rgba(255, 255, 255, 0.85); - background-clip: padding-box; - border: 1px solid rgba(0, 0, 0, 0.1); - box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); - border-radius: 0.25rem; -} -.toast:not(.showing):not(.show) { - opacity: 0; -} -.toast.hide { - display: none; -} - -.toast-container { - width: -webkit-max-content; - width: -moz-max-content; - width: max-content; - max-width: 100%; - pointer-events: none; -} -.toast-container > :not(:last-child) { - margin-bottom: 0.75rem; -} - -.toast-header { - display: flex; - align-items: center; - padding: 0.5rem 0.75rem; - color: #6c757d; - background-color: rgba(255, 255, 255, 0.85); - background-clip: padding-box; - border-bottom: 1px solid rgba(0, 0, 0, 0.05); - border-top-left-radius: calc(0.25rem - 1px); - border-top-right-radius: calc(0.25rem - 1px); -} -.toast-header .btn-close { - margin-right: -0.375rem; - margin-left: 0.75rem; -} - -.toast-body { - padding: 0.75rem; - word-wrap: break-word; -} - -.modal { - position: fixed; - top: 0; - left: 0; - z-index: 1060; - display: none; - width: 100%; - height: 100%; - overflow-x: hidden; - overflow-y: auto; - outline: 0; -} - -.modal-dialog { - position: relative; - width: auto; - margin: 0.5rem; - pointer-events: none; -} -.modal.fade .modal-dialog { - transition: transform 0.3s ease-out; - transform: translate(0, -50px); -} -@media (prefers-reduced-motion: reduce) { - .modal.fade .modal-dialog { - transition: none; - } -} -.modal.show .modal-dialog { - transform: none; -} -.modal.modal-static .modal-dialog { - transform: scale(1.02); -} - -.modal-dialog-scrollable { - height: calc(100% - 1rem); -} -.modal-dialog-scrollable .modal-content { - max-height: 100%; - overflow: hidden; -} -.modal-dialog-scrollable .modal-body { - overflow-y: auto; -} - -.modal-dialog-centered { - display: flex; - align-items: center; - min-height: calc(100% - 1rem); -} - -.modal-content { - position: relative; - display: flex; - flex-direction: column; - width: 100%; - pointer-events: auto; - background-color: #fff; - background-clip: padding-box; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 0.3rem; - outline: 0; -} - -.modal-backdrop { - position: fixed; - top: 0; - left: 0; - z-index: 1040; - width: 100vw; - height: 100vh; - background-color: #000; -} -.modal-backdrop.fade { - opacity: 0; -} -.modal-backdrop.show { - opacity: 0.5; -} - -.modal-header { - display: flex; - flex-shrink: 0; - align-items: center; - justify-content: space-between; - padding: 1rem 1rem; - border-bottom: 1px solid #dee2e6; - border-top-left-radius: calc(0.3rem - 1px); - border-top-right-radius: calc(0.3rem - 1px); -} -.modal-header .btn-close { - padding: 0.5rem 0.5rem; - margin: -0.5rem -0.5rem -0.5rem auto; -} - -.modal-title { - margin-bottom: 0; - line-height: 1.5; -} - -.modal-body { - position: relative; - flex: 1 1 auto; - padding: 1rem; -} - -.modal-footer { - display: flex; - flex-wrap: wrap; - flex-shrink: 0; - align-items: center; - justify-content: flex-end; - padding: 0.75rem; - border-top: 1px solid #dee2e6; - border-bottom-right-radius: calc(0.3rem - 1px); - border-bottom-left-radius: calc(0.3rem - 1px); -} -.modal-footer > * { - margin: 0.25rem; -} - -@media (min-width: 576px) { - .modal-dialog { - max-width: 500px; - margin: 1.75rem auto; - } - - .modal-dialog-scrollable { - height: calc(100% - 3.5rem); - } - - .modal-dialog-centered { - min-height: calc(100% - 3.5rem); - } - - .modal-sm { - max-width: 300px; - } -} -@media (min-width: 992px) { - .modal-lg, -.modal-xl { - max-width: 800px; - } -} -@media (min-width: 1200px) { - .modal-xl { - max-width: 1140px; - } -} -.modal-fullscreen { - width: 100vw; - max-width: none; - height: 100%; - margin: 0; -} -.modal-fullscreen .modal-content { - height: 100%; - border: 0; - border-radius: 0; -} -.modal-fullscreen .modal-header { - border-radius: 0; -} -.modal-fullscreen .modal-body { - overflow-y: auto; -} -.modal-fullscreen .modal-footer { - border-radius: 0; -} - -@media (max-width: 575.98px) { - .modal-fullscreen-sm-down { - width: 100vw; - max-width: none; - height: 100%; - margin: 0; - } - .modal-fullscreen-sm-down .modal-content { - height: 100%; - border: 0; - border-radius: 0; - } - .modal-fullscreen-sm-down .modal-header { - border-radius: 0; - } - .modal-fullscreen-sm-down .modal-body { - overflow-y: auto; - } - .modal-fullscreen-sm-down .modal-footer { - border-radius: 0; - } -} -@media (max-width: 767.98px) { - .modal-fullscreen-md-down { - width: 100vw; - max-width: none; - height: 100%; - margin: 0; - } - .modal-fullscreen-md-down .modal-content { - height: 100%; - border: 0; - border-radius: 0; - } - .modal-fullscreen-md-down .modal-header { - border-radius: 0; - } - .modal-fullscreen-md-down .modal-body { - overflow-y: auto; - } - .modal-fullscreen-md-down .modal-footer { - border-radius: 0; - } -} -@media (max-width: 991.98px) { - .modal-fullscreen-lg-down { - width: 100vw; - max-width: none; - height: 100%; - margin: 0; - } - .modal-fullscreen-lg-down .modal-content { - height: 100%; - border: 0; - border-radius: 0; - } - .modal-fullscreen-lg-down .modal-header { - border-radius: 0; - } - .modal-fullscreen-lg-down .modal-body { - overflow-y: auto; - } - .modal-fullscreen-lg-down .modal-footer { - border-radius: 0; - } -} -@media (max-width: 1199.98px) { - .modal-fullscreen-xl-down { - width: 100vw; - max-width: none; - height: 100%; - margin: 0; - } - .modal-fullscreen-xl-down .modal-content { - height: 100%; - border: 0; - border-radius: 0; - } - .modal-fullscreen-xl-down .modal-header { - border-radius: 0; - } - .modal-fullscreen-xl-down .modal-body { - overflow-y: auto; - } - .modal-fullscreen-xl-down .modal-footer { - border-radius: 0; - } -} -@media (max-width: 1399.98px) { - .modal-fullscreen-xxl-down { - width: 100vw; - max-width: none; - height: 100%; - margin: 0; - } - .modal-fullscreen-xxl-down .modal-content { - height: 100%; - border: 0; - border-radius: 0; - } - .modal-fullscreen-xxl-down .modal-header { - border-radius: 0; - } - .modal-fullscreen-xxl-down .modal-body { - overflow-y: auto; - } - .modal-fullscreen-xxl-down .modal-footer { - border-radius: 0; - } -} -.tooltip { - position: absolute; - z-index: 1080; - display: block; - margin: 0; - font-family: var(--bs-font-sans-serif); - font-style: normal; - font-weight: 400; - line-height: 1.5; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - letter-spacing: normal; - word-break: normal; - word-spacing: normal; - white-space: normal; - line-break: auto; - font-size: 0.875rem; - word-wrap: break-word; - opacity: 0; -} -.tooltip.show { - opacity: 0.9; -} -.tooltip .tooltip-arrow { - position: absolute; - display: block; - width: 0.8rem; - height: 0.4rem; -} -.tooltip .tooltip-arrow::before { - position: absolute; - content: ""; - border-color: transparent; - border-style: solid; -} - -.bs-tooltip-top, .bs-tooltip-auto[data-popper-placement^=top] { - padding: 0.4rem 0; -} -.bs-tooltip-top .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow { - bottom: 0; -} -.bs-tooltip-top .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before { - top: -1px; - border-width: 0.4rem 0.4rem 0; - border-top-color: #000; -} - -.bs-tooltip-end, .bs-tooltip-auto[data-popper-placement^=right] { - padding: 0 0.4rem; -} -.bs-tooltip-end .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow { - left: 0; - width: 0.4rem; - height: 0.8rem; -} -.bs-tooltip-end .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before { - right: -1px; - border-width: 0.4rem 0.4rem 0.4rem 0; - border-right-color: #000; -} - -.bs-tooltip-bottom, .bs-tooltip-auto[data-popper-placement^=bottom] { - padding: 0.4rem 0; -} -.bs-tooltip-bottom .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow { - top: 0; -} -.bs-tooltip-bottom .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before { - bottom: -1px; - border-width: 0 0.4rem 0.4rem; - border-bottom-color: #000; -} - -.bs-tooltip-start, .bs-tooltip-auto[data-popper-placement^=left] { - padding: 0 0.4rem; -} -.bs-tooltip-start .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow { - right: 0; - width: 0.4rem; - height: 0.8rem; -} -.bs-tooltip-start .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before { - left: -1px; - border-width: 0.4rem 0 0.4rem 0.4rem; - border-left-color: #000; -} - -.tooltip-inner { - max-width: 200px; - padding: 0.25rem 0.5rem; - color: #fff; - text-align: center; - background-color: #000; - border-radius: 0.25rem; -} - -.popover { - position: absolute; - top: 0; - left: 0 /* rtl:ignore */; - z-index: 1070; - display: block; - max-width: 276px; - font-family: var(--bs-font-sans-serif); - font-style: normal; - font-weight: 400; - line-height: 1.5; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - letter-spacing: normal; - word-break: normal; - word-spacing: normal; - white-space: normal; - line-break: auto; - font-size: 0.875rem; - word-wrap: break-word; - background-color: #fff; - background-clip: padding-box; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 0.3rem; -} -.popover .popover-arrow { - position: absolute; - display: block; - width: 1rem; - height: 0.5rem; -} -.popover .popover-arrow::before, .popover .popover-arrow::after { - position: absolute; - display: block; - content: ""; - border-color: transparent; - border-style: solid; -} - -.bs-popover-top > .popover-arrow, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow { - bottom: calc(-0.5rem - 1px); -} -.bs-popover-top > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before { - bottom: 0; - border-width: 0.5rem 0.5rem 0; - border-top-color: rgba(0, 0, 0, 0.25); -} -.bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after { - bottom: 1px; - border-width: 0.5rem 0.5rem 0; - border-top-color: #fff; -} - -.bs-popover-end > .popover-arrow, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow { - left: calc(-0.5rem - 1px); - width: 0.5rem; - height: 1rem; -} -.bs-popover-end > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before { - left: 0; - border-width: 0.5rem 0.5rem 0.5rem 0; - border-right-color: rgba(0, 0, 0, 0.25); -} -.bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after { - left: 1px; - border-width: 0.5rem 0.5rem 0.5rem 0; - border-right-color: #fff; -} - -.bs-popover-bottom > .popover-arrow, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow { - top: calc(-0.5rem - 1px); -} -.bs-popover-bottom > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before { - top: 0; - border-width: 0 0.5rem 0.5rem 0.5rem; - border-bottom-color: rgba(0, 0, 0, 0.25); -} -.bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after { - top: 1px; - border-width: 0 0.5rem 0.5rem 0.5rem; - border-bottom-color: #fff; -} -.bs-popover-bottom .popover-header::before, .bs-popover-auto[data-popper-placement^=bottom] .popover-header::before { - position: absolute; - top: 0; - left: 50%; - display: block; - width: 1rem; - margin-left: -0.5rem; - content: ""; - border-bottom: 1px solid #f0f0f0; -} - -.bs-popover-start > .popover-arrow, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow { - right: calc(-0.5rem - 1px); - width: 0.5rem; - height: 1rem; -} -.bs-popover-start > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before { - right: 0; - border-width: 0.5rem 0 0.5rem 0.5rem; - border-left-color: rgba(0, 0, 0, 0.25); -} -.bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after { - right: 1px; - border-width: 0.5rem 0 0.5rem 0.5rem; - border-left-color: #fff; -} - -.popover-header { - padding: 0.5rem 1rem; - margin-bottom: 0; - font-size: 1rem; - background-color: #f0f0f0; - border-bottom: 1px solid #d8d8d8; - border-top-left-radius: calc(0.3rem - 1px); - border-top-right-radius: calc(0.3rem - 1px); -} -.popover-header:empty { - display: none; -} - -.popover-body { - padding: 1rem 1rem; - color: #212529; -} - -.carousel { - position: relative; -} - -.carousel.pointer-event { - touch-action: pan-y; -} - -.carousel-inner { - position: relative; - width: 100%; - overflow: hidden; -} -.carousel-inner::after { - display: block; - clear: both; - content: ""; -} - -.carousel-item { - position: relative; - display: none; - float: left; - width: 100%; - margin-right: -100%; - -webkit-backface-visibility: hidden; - backface-visibility: hidden; - transition: transform 0.6s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .carousel-item { - transition: none; - } -} - -.carousel-item.active, -.carousel-item-next, -.carousel-item-prev { - display: block; -} - -/* rtl:begin:ignore */ -.carousel-item-next:not(.carousel-item-start), -.active.carousel-item-end { - transform: translateX(100%); -} - -.carousel-item-prev:not(.carousel-item-end), -.active.carousel-item-start { - transform: translateX(-100%); -} - -/* rtl:end:ignore */ -.carousel-fade .carousel-item { - opacity: 0; - transition-property: opacity; - transform: none; -} -.carousel-fade .carousel-item.active, -.carousel-fade .carousel-item-next.carousel-item-start, -.carousel-fade .carousel-item-prev.carousel-item-end { - z-index: 1; - opacity: 1; -} -.carousel-fade .active.carousel-item-start, -.carousel-fade .active.carousel-item-end { - z-index: 0; - opacity: 0; - transition: opacity 0s 0.6s; -} -@media (prefers-reduced-motion: reduce) { - .carousel-fade .active.carousel-item-start, -.carousel-fade .active.carousel-item-end { - transition: none; - } -} - -.carousel-control-prev, -.carousel-control-next { - position: absolute; - top: 0; - bottom: 0; - z-index: 1; - display: flex; - align-items: center; - justify-content: center; - width: 15%; - padding: 0; - color: #fff; - text-align: center; - background: none; - border: 0; - opacity: 0.5; - transition: opacity 0.15s ease; -} -@media (prefers-reduced-motion: reduce) { - .carousel-control-prev, -.carousel-control-next { - transition: none; - } -} -.carousel-control-prev:hover, .carousel-control-prev:focus, -.carousel-control-next:hover, -.carousel-control-next:focus { - color: #fff; - text-decoration: none; - outline: 0; - opacity: 0.9; -} - -.carousel-control-prev { - left: 0; -} - -.carousel-control-next { - right: 0; -} - -.carousel-control-prev-icon, -.carousel-control-next-icon { - display: inline-block; - width: 2rem; - height: 2rem; - background-repeat: no-repeat; - background-position: 50%; - background-size: 100% 100%; -} - -/* rtl:options: { - "autoRename": true, - "stringMap":[ { - "name" : "prev-next", - "search" : "prev", - "replace" : "next" - } ] -} */ -.carousel-control-prev-icon { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e"); -} - -.carousel-control-next-icon { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); -} - -.carousel-indicators { - position: absolute; - right: 0; - bottom: 0; - left: 0; - z-index: 2; - display: flex; - justify-content: center; - padding: 0; - margin-right: 15%; - margin-bottom: 1rem; - margin-left: 15%; - list-style: none; -} -.carousel-indicators [data-bs-target] { - box-sizing: content-box; - flex: 0 1 auto; - width: 30px; - height: 3px; - padding: 0; - margin-right: 3px; - margin-left: 3px; - text-indent: -999px; - cursor: pointer; - background-color: #fff; - background-clip: padding-box; - border: 0; - border-top: 10px solid transparent; - border-bottom: 10px solid transparent; - opacity: 0.5; - transition: opacity 0.6s ease; -} -@media (prefers-reduced-motion: reduce) { - .carousel-indicators [data-bs-target] { - transition: none; - } -} -.carousel-indicators .active { - opacity: 1; -} - -.carousel-caption { - position: absolute; - right: 15%; - bottom: 1.25rem; - left: 15%; - padding-top: 1.25rem; - padding-bottom: 1.25rem; - color: #fff; - text-align: center; -} - -.carousel-dark .carousel-control-prev-icon, -.carousel-dark .carousel-control-next-icon { - filter: invert(1) grayscale(100); -} -.carousel-dark .carousel-indicators [data-bs-target] { - background-color: #000; -} -.carousel-dark .carousel-caption { - color: #000; -} - -@-webkit-keyframes spinner-border { - to { - transform: rotate(360deg) /* rtl:ignore */; - } -} - -@keyframes spinner-border { - to { - transform: rotate(360deg) /* rtl:ignore */; - } -} -.spinner-border { - display: inline-block; - width: 2rem; - height: 2rem; - vertical-align: -0.125em; - border: 0.25em solid currentColor; - border-right-color: transparent; - border-radius: 50%; - -webkit-animation: 0.75s linear infinite spinner-border; - animation: 0.75s linear infinite spinner-border; -} - -.spinner-border-sm { - width: 1rem; - height: 1rem; - border-width: 0.2em; -} - -@-webkit-keyframes spinner-grow { - 0% { - transform: scale(0); - } - 50% { - opacity: 1; - transform: none; - } -} - -@keyframes spinner-grow { - 0% { - transform: scale(0); - } - 50% { - opacity: 1; - transform: none; - } -} -.spinner-grow { - display: inline-block; - width: 2rem; - height: 2rem; - vertical-align: -0.125em; - background-color: currentColor; - border-radius: 50%; - opacity: 0; - -webkit-animation: 0.75s linear infinite spinner-grow; - animation: 0.75s linear infinite spinner-grow; -} - -.spinner-grow-sm { - width: 1rem; - height: 1rem; -} - -@media (prefers-reduced-motion: reduce) { - .spinner-border, -.spinner-grow { - -webkit-animation-duration: 1.5s; - animation-duration: 1.5s; - } -} -.offcanvas { - position: fixed; - bottom: 0; - z-index: 1050; - display: flex; - flex-direction: column; - max-width: 100%; - visibility: hidden; - background-color: #fff; - background-clip: padding-box; - outline: 0; - transition: transform 0.3s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .offcanvas { - transition: none; - } -} - -.offcanvas-header { - display: flex; - align-items: center; - justify-content: space-between; - padding: 1rem 1rem; -} -.offcanvas-header .btn-close { - padding: 0.5rem 0.5rem; - margin: -0.5rem -0.5rem -0.5rem auto; -} - -.offcanvas-title { - margin-bottom: 0; - line-height: 1.5; -} - -.offcanvas-body { - flex-grow: 1; - padding: 1rem 1rem; - overflow-y: auto; -} - -.offcanvas-start { - top: 0; - left: 0; - width: 400px; - border-right: 1px solid rgba(0, 0, 0, 0.2); - transform: translateX(-100%); -} - -.offcanvas-end { - top: 0; - right: 0; - width: 400px; - border-left: 1px solid rgba(0, 0, 0, 0.2); - transform: translateX(100%); -} - -.offcanvas-top { - top: 0; - right: 0; - left: 0; - height: 30vh; - max-height: 100%; - border-bottom: 1px solid rgba(0, 0, 0, 0.2); - transform: translateY(-100%); -} - -.offcanvas-bottom { - right: 0; - left: 0; - height: 30vh; - max-height: 100%; - border-top: 1px solid rgba(0, 0, 0, 0.2); - transform: translateY(100%); -} - -.offcanvas.show { - transform: none; -} - -.clearfix::after { - display: block; - clear: both; - content: ""; -} - -.link-primary { - color: #0d6efd; -} -.link-primary:hover, .link-primary:focus { - color: #0a58ca; -} - -.link-secondary { - color: #6c757d; -} -.link-secondary:hover, .link-secondary:focus { - color: #565e64; -} - -.link-success { - color: #198754; -} -.link-success:hover, .link-success:focus { - color: #146c43; -} - -.link-info { - color: #0dcaf0; -} -.link-info:hover, .link-info:focus { - color: #3dd5f3; -} - -.link-warning { - color: #ffc107; -} -.link-warning:hover, .link-warning:focus { - color: #ffcd39; -} - -.link-danger { - color: #dc3545; -} -.link-danger:hover, .link-danger:focus { - color: #b02a37; -} - -.link-light { - color: #f8f9fa; -} -.link-light:hover, .link-light:focus { - color: #f9fafb; -} - -.link-dark { - color: #212529; -} -.link-dark:hover, .link-dark:focus { - color: #1a1e21; -} - -.ratio { - position: relative; - width: 100%; -} -.ratio::before { - display: block; - padding-top: var(--bs-aspect-ratio); - content: ""; -} -.ratio > * { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; -} - -.ratio-1x1 { - --bs-aspect-ratio: 100%; -} - -.ratio-4x3 { - --bs-aspect-ratio: calc(3 / 4 * 100%); -} - -.ratio-16x9 { - --bs-aspect-ratio: calc(9 / 16 * 100%); -} - -.ratio-21x9 { - --bs-aspect-ratio: calc(9 / 21 * 100%); -} - -.fixed-top { - position: fixed; - top: 0; - right: 0; - left: 0; - z-index: 1030; -} - -.fixed-bottom { - position: fixed; - right: 0; - bottom: 0; - left: 0; - z-index: 1030; -} - -.sticky-top { - position: -webkit-sticky; - position: sticky; - top: 0; - z-index: 1020; -} - -@media (min-width: 576px) { - .sticky-sm-top { - position: -webkit-sticky; - position: sticky; - top: 0; - z-index: 1020; - } -} -@media (min-width: 768px) { - .sticky-md-top { - position: -webkit-sticky; - position: sticky; - top: 0; - z-index: 1020; - } -} -@media (min-width: 992px) { - .sticky-lg-top { - position: -webkit-sticky; - position: sticky; - top: 0; - z-index: 1020; - } -} -@media (min-width: 1200px) { - .sticky-xl-top { - position: -webkit-sticky; - position: sticky; - top: 0; - z-index: 1020; - } -} -@media (min-width: 1400px) { - .sticky-xxl-top { - position: -webkit-sticky; - position: sticky; - top: 0; - z-index: 1020; - } -} -.visually-hidden, -.visually-hidden-focusable:not(:focus):not(:focus-within) { - position: absolute !important; - width: 1px !important; - height: 1px !important; - padding: 0 !important; - margin: -1px !important; - overflow: hidden !important; - clip: rect(0, 0, 0, 0) !important; - white-space: nowrap !important; - border: 0 !important; -} - -.stretched-link::after { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1; - content: ""; -} - -.text-truncate { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.align-baseline { - vertical-align: baseline !important; -} - -.align-top { - vertical-align: top !important; -} - -.align-middle { - vertical-align: middle !important; -} - -.align-bottom { - vertical-align: bottom !important; -} - -.align-text-bottom { - vertical-align: text-bottom !important; -} - -.align-text-top { - vertical-align: text-top !important; -} - -.float-start { - float: left !important; -} - -.float-end { - float: right !important; -} - -.float-none { - float: none !important; -} - -.overflow-auto { - overflow: auto !important; -} - -.overflow-hidden { - overflow: hidden !important; -} - -.overflow-visible { - overflow: visible !important; -} - -.overflow-scroll { - overflow: scroll !important; -} - -.d-inline { - display: inline !important; -} - -.d-inline-block { - display: inline-block !important; -} - -.d-block { - display: block !important; -} - -.d-grid { - display: grid !important; -} - -.d-table { - display: table !important; -} - -.d-table-row { - display: table-row !important; -} - -.d-table-cell { - display: table-cell !important; -} - -.d-flex { - display: flex !important; -} - -.d-inline-flex { - display: inline-flex !important; -} - -.d-none { - display: none !important; -} - -.shadow { - box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important; -} - -.shadow-sm { - box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important; -} - -.shadow-lg { - box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important; -} - -.shadow-none { - box-shadow: none !important; -} - -.position-static { - position: static !important; -} - -.position-relative { - position: relative !important; -} - -.position-absolute { - position: absolute !important; -} - -.position-fixed { - position: fixed !important; -} - -.position-sticky { - position: -webkit-sticky !important; - position: sticky !important; -} - -.top-0 { - top: 0 !important; -} - -.top-50 { - top: 50% !important; -} - -.top-100 { - top: 100% !important; -} - -.bottom-0 { - bottom: 0 !important; -} - -.bottom-50 { - bottom: 50% !important; -} - -.bottom-100 { - bottom: 100% !important; -} - -.start-0 { - left: 0 !important; -} - -.start-50 { - left: 50% !important; -} - -.start-100 { - left: 100% !important; -} - -.end-0 { - right: 0 !important; -} - -.end-50 { - right: 50% !important; -} - -.end-100 { - right: 100% !important; -} - -.translate-middle { - transform: translate(-50%, -50%) !important; -} - -.translate-middle-x { - transform: translateX(-50%) !important; -} - -.translate-middle-y { - transform: translateY(-50%) !important; -} - -.border { - border: 1px solid #dee2e6 !important; -} - -.border-0 { - border: 0 !important; -} - -.border-top { - border-top: 1px solid #dee2e6 !important; -} - -.border-top-0 { - border-top: 0 !important; -} - -.border-end { - border-right: 1px solid #dee2e6 !important; -} - -.border-end-0 { - border-right: 0 !important; -} - -.border-bottom { - border-bottom: 1px solid #dee2e6 !important; -} - -.border-bottom-0 { - border-bottom: 0 !important; -} - -.border-start { - border-left: 1px solid #dee2e6 !important; -} - -.border-start-0 { - border-left: 0 !important; -} - -.border-primary { - border-color: #0d6efd !important; -} - -.border-secondary { - border-color: #6c757d !important; -} - -.border-success { - border-color: #198754 !important; -} - -.border-info { - border-color: #0dcaf0 !important; -} - -.border-warning { - border-color: #ffc107 !important; -} - -.border-danger { - border-color: #dc3545 !important; -} - -.border-light { - border-color: #f8f9fa !important; -} - -.border-dark { - border-color: #212529 !important; -} - -.border-white { - border-color: #fff !important; -} - -.border-1 { - border-width: 1px !important; -} - -.border-2 { - border-width: 2px !important; -} - -.border-3 { - border-width: 3px !important; -} - -.border-4 { - border-width: 4px !important; -} - -.border-5 { - border-width: 5px !important; -} - -.w-25 { - width: 25% !important; -} - -.w-50 { - width: 50% !important; -} - -.w-75 { - width: 75% !important; -} - -.w-100 { - width: 100% !important; -} - -.w-auto { - width: auto !important; -} - -.mw-100 { - max-width: 100% !important; -} - -.vw-100 { - width: 100vw !important; -} - -.min-vw-100 { - min-width: 100vw !important; -} - -.h-25 { - height: 25% !important; -} - -.h-50 { - height: 50% !important; -} - -.h-75 { - height: 75% !important; -} - -.h-100 { - height: 100% !important; -} - -.h-auto { - height: auto !important; -} - -.mh-100 { - max-height: 100% !important; -} - -.vh-100 { - height: 100vh !important; -} - -.min-vh-100 { - min-height: 100vh !important; -} - -.flex-fill { - flex: 1 1 auto !important; -} - -.flex-row { - flex-direction: row !important; -} - -.flex-column { - flex-direction: column !important; -} - -.flex-row-reverse { - flex-direction: row-reverse !important; -} - -.flex-column-reverse { - flex-direction: column-reverse !important; -} - -.flex-grow-0 { - flex-grow: 0 !important; -} - -.flex-grow-1 { - flex-grow: 1 !important; -} - -.flex-shrink-0 { - flex-shrink: 0 !important; -} - -.flex-shrink-1 { - flex-shrink: 1 !important; -} - -.flex-wrap { - flex-wrap: wrap !important; -} - -.flex-nowrap { - flex-wrap: nowrap !important; -} - -.flex-wrap-reverse { - flex-wrap: wrap-reverse !important; -} - -.gap-0 { - gap: 0 !important; -} - -.gap-1 { - gap: 0.25rem !important; -} - -.gap-2 { - gap: 0.5rem !important; -} - -.gap-3 { - gap: 1rem !important; -} - -.gap-4 { - gap: 1.5rem !important; -} - -.gap-5 { - gap: 3rem !important; -} - -.justify-content-start { - justify-content: flex-start !important; -} - -.justify-content-end { - justify-content: flex-end !important; -} - -.justify-content-center { - justify-content: center !important; -} - -.justify-content-between { - justify-content: space-between !important; -} - -.justify-content-around { - justify-content: space-around !important; -} - -.justify-content-evenly { - justify-content: space-evenly !important; -} - -.align-items-start { - align-items: flex-start !important; -} - -.align-items-end { - align-items: flex-end !important; -} - -.align-items-center { - align-items: center !important; -} - -.align-items-baseline { - align-items: baseline !important; -} - -.align-items-stretch { - align-items: stretch !important; -} - -.align-content-start { - align-content: flex-start !important; -} - -.align-content-end { - align-content: flex-end !important; -} - -.align-content-center { - align-content: center !important; -} - -.align-content-between { - align-content: space-between !important; -} - -.align-content-around { - align-content: space-around !important; -} - -.align-content-stretch { - align-content: stretch !important; -} - -.align-self-auto { - align-self: auto !important; -} - -.align-self-start { - align-self: flex-start !important; -} - -.align-self-end { - align-self: flex-end !important; -} - -.align-self-center { - align-self: center !important; -} - -.align-self-baseline { - align-self: baseline !important; -} - -.align-self-stretch { - align-self: stretch !important; -} - -.order-first { - order: -1 !important; -} - -.order-0 { - order: 0 !important; -} - -.order-1 { - order: 1 !important; -} - -.order-2 { - order: 2 !important; -} - -.order-3 { - order: 3 !important; -} - -.order-4 { - order: 4 !important; -} - -.order-5 { - order: 5 !important; -} - -.order-last { - order: 6 !important; -} - -.m-0 { - margin: 0 !important; -} - -.m-1 { - margin: 0.25rem !important; -} - -.m-2 { - margin: 0.5rem !important; -} - -.m-3 { - margin: 1rem !important; -} - -.m-4 { - margin: 1.5rem !important; -} - -.m-5 { - margin: 3rem !important; -} - -.m-auto { - margin: auto !important; -} - -.mx-0 { - margin-right: 0 !important; - margin-left: 0 !important; -} - -.mx-1 { - margin-right: 0.25rem !important; - margin-left: 0.25rem !important; -} - -.mx-2 { - margin-right: 0.5rem !important; - margin-left: 0.5rem !important; -} - -.mx-3 { - margin-right: 1rem !important; - margin-left: 1rem !important; -} - -.mx-4 { - margin-right: 1.5rem !important; - margin-left: 1.5rem !important; -} - -.mx-5 { - margin-right: 3rem !important; - margin-left: 3rem !important; -} - -.mx-auto { - margin-right: auto !important; - margin-left: auto !important; -} - -.my-0 { - margin-top: 0 !important; - margin-bottom: 0 !important; -} - -.my-1 { - margin-top: 0.25rem !important; - margin-bottom: 0.25rem !important; -} - -.my-2 { - margin-top: 0.5rem !important; - margin-bottom: 0.5rem !important; -} - -.my-3 { - margin-top: 1rem !important; - margin-bottom: 1rem !important; -} - -.my-4 { - margin-top: 1.5rem !important; - margin-bottom: 1.5rem !important; -} - -.my-5 { - margin-top: 3rem !important; - margin-bottom: 3rem !important; -} - -.my-auto { - margin-top: auto !important; - margin-bottom: auto !important; -} - -.mt-0 { - margin-top: 0 !important; -} - -.mt-1 { - margin-top: 0.25rem !important; -} - -.mt-2 { - margin-top: 0.5rem !important; -} - -.mt-3 { - margin-top: 1rem !important; -} - -.mt-4 { - margin-top: 1.5rem !important; -} - -.mt-5 { - margin-top: 3rem !important; -} - -.mt-auto { - margin-top: auto !important; -} - -.me-0 { - margin-right: 0 !important; -} - -.me-1 { - margin-right: 0.25rem !important; -} - -.me-2 { - margin-right: 0.5rem !important; -} - -.me-3 { - margin-right: 1rem !important; -} - -.me-4 { - margin-right: 1.5rem !important; -} - -.me-5 { - margin-right: 3rem !important; -} - -.me-auto { - margin-right: auto !important; -} - -.mb-0 { - margin-bottom: 0 !important; -} - -.mb-1 { - margin-bottom: 0.25rem !important; -} - -.mb-2 { - margin-bottom: 0.5rem !important; -} - -.mb-3 { - margin-bottom: 1rem !important; -} - -.mb-4 { - margin-bottom: 1.5rem !important; -} - -.mb-5 { - margin-bottom: 3rem !important; -} - -.mb-auto { - margin-bottom: auto !important; -} - -.ms-0 { - margin-left: 0 !important; -} - -.ms-1 { - margin-left: 0.25rem !important; -} - -.ms-2 { - margin-left: 0.5rem !important; -} - -.ms-3 { - margin-left: 1rem !important; -} - -.ms-4 { - margin-left: 1.5rem !important; -} - -.ms-5 { - margin-left: 3rem !important; -} - -.ms-auto { - margin-left: auto !important; -} - -.p-0 { - padding: 0 !important; -} - -.p-1 { - padding: 0.25rem !important; -} - -.p-2 { - padding: 0.5rem !important; -} - -.p-3 { - padding: 1rem !important; -} - -.p-4 { - padding: 1.5rem !important; -} - -.p-5 { - padding: 3rem !important; -} - -.px-0 { - padding-right: 0 !important; - padding-left: 0 !important; -} - -.px-1 { - padding-right: 0.25rem !important; - padding-left: 0.25rem !important; -} - -.px-2 { - padding-right: 0.5rem !important; - padding-left: 0.5rem !important; -} - -.px-3 { - padding-right: 1rem !important; - padding-left: 1rem !important; -} - -.px-4 { - padding-right: 1.5rem !important; - padding-left: 1.5rem !important; -} - -.px-5 { - padding-right: 3rem !important; - padding-left: 3rem !important; -} - -.py-0 { - padding-top: 0 !important; - padding-bottom: 0 !important; -} - -.py-1 { - padding-top: 0.25rem !important; - padding-bottom: 0.25rem !important; -} - -.py-2 { - padding-top: 0.5rem !important; - padding-bottom: 0.5rem !important; -} - -.py-3 { - padding-top: 1rem !important; - padding-bottom: 1rem !important; -} - -.py-4 { - padding-top: 1.5rem !important; - padding-bottom: 1.5rem !important; -} - -.py-5 { - padding-top: 3rem !important; - padding-bottom: 3rem !important; -} - -.pt-0 { - padding-top: 0 !important; -} - -.pt-1 { - padding-top: 0.25rem !important; -} - -.pt-2 { - padding-top: 0.5rem !important; -} - -.pt-3 { - padding-top: 1rem !important; -} - -.pt-4 { - padding-top: 1.5rem !important; -} - -.pt-5 { - padding-top: 3rem !important; -} - -.pe-0 { - padding-right: 0 !important; -} - -.pe-1 { - padding-right: 0.25rem !important; -} - -.pe-2 { - padding-right: 0.5rem !important; -} - -.pe-3 { - padding-right: 1rem !important; -} - -.pe-4 { - padding-right: 1.5rem !important; -} - -.pe-5 { - padding-right: 3rem !important; -} - -.pb-0 { - padding-bottom: 0 !important; -} - -.pb-1 { - padding-bottom: 0.25rem !important; -} - -.pb-2 { - padding-bottom: 0.5rem !important; -} - -.pb-3 { - padding-bottom: 1rem !important; -} - -.pb-4 { - padding-bottom: 1.5rem !important; -} - -.pb-5 { - padding-bottom: 3rem !important; -} - -.ps-0 { - padding-left: 0 !important; -} - -.ps-1 { - padding-left: 0.25rem !important; -} - -.ps-2 { - padding-left: 0.5rem !important; -} - -.ps-3 { - padding-left: 1rem !important; -} - -.ps-4 { - padding-left: 1.5rem !important; -} - -.ps-5 { - padding-left: 3rem !important; -} - -.font-monospace { - font-family: var(--bs-font-monospace) !important; -} - -.fs-1 { - font-size: calc(1.375rem + 1.5vw) !important; -} - -.fs-2 { - font-size: calc(1.325rem + 0.9vw) !important; -} - -.fs-3 { - font-size: calc(1.3rem + 0.6vw) !important; -} - -.fs-4 { - font-size: calc(1.275rem + 0.3vw) !important; -} - -.fs-5 { - font-size: 1.25rem !important; -} - -.fs-6 { - font-size: 1rem !important; -} - -.fst-italic { - font-style: italic !important; -} - -.fst-normal { - font-style: normal !important; -} - -.fw-light { - font-weight: 300 !important; -} - -.fw-lighter { - font-weight: lighter !important; -} - -.fw-normal { - font-weight: 400 !important; -} - -.fw-bold { - font-weight: 700 !important; -} - -.fw-bolder { - font-weight: bolder !important; -} - -.lh-1 { - line-height: 1 !important; -} - -.lh-sm { - line-height: 1.25 !important; -} - -.lh-base { - line-height: 1.5 !important; -} - -.lh-lg { - line-height: 2 !important; -} - -.text-start { - text-align: left !important; -} - -.text-end { - text-align: right !important; -} - -.text-center { - text-align: center !important; -} - -.text-decoration-none { - text-decoration: none !important; -} - -.text-decoration-underline { - text-decoration: underline !important; -} - -.text-decoration-line-through { - text-decoration: line-through !important; -} - -.text-lowercase { - text-transform: lowercase !important; -} - -.text-uppercase { - text-transform: uppercase !important; -} - -.text-capitalize { - text-transform: capitalize !important; -} - -.text-wrap { - white-space: normal !important; -} - -.text-nowrap { - white-space: nowrap !important; -} - -/* rtl:begin:remove */ -.text-break { - word-wrap: break-word !important; - word-break: break-word !important; -} - -/* rtl:end:remove */ -.text-primary { - color: #0d6efd !important; -} - -.text-secondary { - color: #6c757d !important; -} - -.text-success { - color: #198754 !important; -} - -.text-info { - color: #0dcaf0 !important; -} - -.text-warning { - color: #ffc107 !important; -} - -.text-danger { - color: #dc3545 !important; -} - -.text-light { - color: #f8f9fa !important; -} - -.text-dark { - color: #212529 !important; -} - -.text-white { - color: #fff !important; -} - -.text-body { - color: #212529 !important; -} - -.text-muted { - color: #6c757d !important; -} - -.text-black-50 { - color: rgba(0, 0, 0, 0.5) !important; -} - -.text-white-50 { - color: rgba(255, 255, 255, 0.5) !important; -} - -.text-reset { - color: inherit !important; -} - -.bg-primary { - background-color: #0d6efd !important; -} - -.bg-secondary { - background-color: #6c757d !important; -} - -.bg-success { - background-color: #198754 !important; -} - -.bg-info { - background-color: #0dcaf0 !important; -} - -.bg-warning { - background-color: #ffc107 !important; -} - -.bg-danger { - background-color: #dc3545 !important; -} - -.bg-light { - background-color: #f8f9fa !important; -} - -.bg-dark { - background-color: #212529 !important; -} - -.bg-body { - background-color: #fff !important; -} - -.bg-white { - background-color: #fff !important; -} - -.bg-transparent { - background-color: transparent !important; -} - -.bg-gradient { - background-image: var(--bs-gradient) !important; -} - -.user-select-all { - -webkit-user-select: all !important; - -moz-user-select: all !important; - user-select: all !important; -} - -.user-select-auto { - -webkit-user-select: auto !important; - -moz-user-select: auto !important; - user-select: auto !important; -} - -.user-select-none { - -webkit-user-select: none !important; - -moz-user-select: none !important; - user-select: none !important; -} - -.pe-none { - pointer-events: none !important; -} - -.pe-auto { - pointer-events: auto !important; -} - -.rounded { - border-radius: 0.25rem !important; -} - -.rounded-0 { - border-radius: 0 !important; -} - -.rounded-1 { - border-radius: 0.2rem !important; -} - -.rounded-2 { - border-radius: 0.25rem !important; -} - -.rounded-3 { - border-radius: 0.3rem !important; -} - -.rounded-circle { - border-radius: 50% !important; -} - -.rounded-pill { - border-radius: 50rem !important; -} - -.rounded-top { - border-top-left-radius: 0.25rem !important; - border-top-right-radius: 0.25rem !important; -} - -.rounded-end { - border-top-right-radius: 0.25rem !important; - border-bottom-right-radius: 0.25rem !important; -} - -.rounded-bottom { - border-bottom-right-radius: 0.25rem !important; - border-bottom-left-radius: 0.25rem !important; -} - -.rounded-start { - border-bottom-left-radius: 0.25rem !important; - border-top-left-radius: 0.25rem !important; -} - -.visible { - visibility: visible !important; -} - -.invisible { - visibility: hidden !important; -} - -@media (min-width: 576px) { - .float-sm-start { - float: left !important; - } - - .float-sm-end { - float: right !important; - } - - .float-sm-none { - float: none !important; - } - - .d-sm-inline { - display: inline !important; - } - - .d-sm-inline-block { - display: inline-block !important; - } - - .d-sm-block { - display: block !important; - } - - .d-sm-grid { - display: grid !important; - } - - .d-sm-table { - display: table !important; - } - - .d-sm-table-row { - display: table-row !important; - } - - .d-sm-table-cell { - display: table-cell !important; - } - - .d-sm-flex { - display: flex !important; - } - - .d-sm-inline-flex { - display: inline-flex !important; - } - - .d-sm-none { - display: none !important; - } - - .flex-sm-fill { - flex: 1 1 auto !important; - } - - .flex-sm-row { - flex-direction: row !important; - } - - .flex-sm-column { - flex-direction: column !important; - } - - .flex-sm-row-reverse { - flex-direction: row-reverse !important; - } - - .flex-sm-column-reverse { - flex-direction: column-reverse !important; - } - - .flex-sm-grow-0 { - flex-grow: 0 !important; - } - - .flex-sm-grow-1 { - flex-grow: 1 !important; - } - - .flex-sm-shrink-0 { - flex-shrink: 0 !important; - } - - .flex-sm-shrink-1 { - flex-shrink: 1 !important; - } - - .flex-sm-wrap { - flex-wrap: wrap !important; - } - - .flex-sm-nowrap { - flex-wrap: nowrap !important; - } - - .flex-sm-wrap-reverse { - flex-wrap: wrap-reverse !important; - } - - .gap-sm-0 { - gap: 0 !important; - } - - .gap-sm-1 { - gap: 0.25rem !important; - } - - .gap-sm-2 { - gap: 0.5rem !important; - } - - .gap-sm-3 { - gap: 1rem !important; - } - - .gap-sm-4 { - gap: 1.5rem !important; - } - - .gap-sm-5 { - gap: 3rem !important; - } - - .justify-content-sm-start { - justify-content: flex-start !important; - } - - .justify-content-sm-end { - justify-content: flex-end !important; - } - - .justify-content-sm-center { - justify-content: center !important; - } - - .justify-content-sm-between { - justify-content: space-between !important; - } - - .justify-content-sm-around { - justify-content: space-around !important; - } - - .justify-content-sm-evenly { - justify-content: space-evenly !important; - } - - .align-items-sm-start { - align-items: flex-start !important; - } - - .align-items-sm-end { - align-items: flex-end !important; - } - - .align-items-sm-center { - align-items: center !important; - } - - .align-items-sm-baseline { - align-items: baseline !important; - } - - .align-items-sm-stretch { - align-items: stretch !important; - } - - .align-content-sm-start { - align-content: flex-start !important; - } - - .align-content-sm-end { - align-content: flex-end !important; - } - - .align-content-sm-center { - align-content: center !important; - } - - .align-content-sm-between { - align-content: space-between !important; - } - - .align-content-sm-around { - align-content: space-around !important; - } - - .align-content-sm-stretch { - align-content: stretch !important; - } - - .align-self-sm-auto { - align-self: auto !important; - } - - .align-self-sm-start { - align-self: flex-start !important; - } - - .align-self-sm-end { - align-self: flex-end !important; - } - - .align-self-sm-center { - align-self: center !important; - } - - .align-self-sm-baseline { - align-self: baseline !important; - } - - .align-self-sm-stretch { - align-self: stretch !important; - } - - .order-sm-first { - order: -1 !important; - } - - .order-sm-0 { - order: 0 !important; - } - - .order-sm-1 { - order: 1 !important; - } - - .order-sm-2 { - order: 2 !important; - } - - .order-sm-3 { - order: 3 !important; - } - - .order-sm-4 { - order: 4 !important; - } - - .order-sm-5 { - order: 5 !important; - } - - .order-sm-last { - order: 6 !important; - } - - .m-sm-0 { - margin: 0 !important; - } - - .m-sm-1 { - margin: 0.25rem !important; - } - - .m-sm-2 { - margin: 0.5rem !important; - } - - .m-sm-3 { - margin: 1rem !important; - } - - .m-sm-4 { - margin: 1.5rem !important; - } - - .m-sm-5 { - margin: 3rem !important; - } - - .m-sm-auto { - margin: auto !important; - } - - .mx-sm-0 { - margin-right: 0 !important; - margin-left: 0 !important; - } - - .mx-sm-1 { - margin-right: 0.25rem !important; - margin-left: 0.25rem !important; - } - - .mx-sm-2 { - margin-right: 0.5rem !important; - margin-left: 0.5rem !important; - } - - .mx-sm-3 { - margin-right: 1rem !important; - margin-left: 1rem !important; - } - - .mx-sm-4 { - margin-right: 1.5rem !important; - margin-left: 1.5rem !important; - } - - .mx-sm-5 { - margin-right: 3rem !important; - margin-left: 3rem !important; - } - - .mx-sm-auto { - margin-right: auto !important; - margin-left: auto !important; - } - - .my-sm-0 { - margin-top: 0 !important; - margin-bottom: 0 !important; - } - - .my-sm-1 { - margin-top: 0.25rem !important; - margin-bottom: 0.25rem !important; - } - - .my-sm-2 { - margin-top: 0.5rem !important; - margin-bottom: 0.5rem !important; - } - - .my-sm-3 { - margin-top: 1rem !important; - margin-bottom: 1rem !important; - } - - .my-sm-4 { - margin-top: 1.5rem !important; - margin-bottom: 1.5rem !important; - } - - .my-sm-5 { - margin-top: 3rem !important; - margin-bottom: 3rem !important; - } - - .my-sm-auto { - margin-top: auto !important; - margin-bottom: auto !important; - } - - .mt-sm-0 { - margin-top: 0 !important; - } - - .mt-sm-1 { - margin-top: 0.25rem !important; - } - - .mt-sm-2 { - margin-top: 0.5rem !important; - } - - .mt-sm-3 { - margin-top: 1rem !important; - } - - .mt-sm-4 { - margin-top: 1.5rem !important; - } - - .mt-sm-5 { - margin-top: 3rem !important; - } - - .mt-sm-auto { - margin-top: auto !important; - } - - .me-sm-0 { - margin-right: 0 !important; - } - - .me-sm-1 { - margin-right: 0.25rem !important; - } - - .me-sm-2 { - margin-right: 0.5rem !important; - } - - .me-sm-3 { - margin-right: 1rem !important; - } - - .me-sm-4 { - margin-right: 1.5rem !important; - } - - .me-sm-5 { - margin-right: 3rem !important; - } - - .me-sm-auto { - margin-right: auto !important; - } - - .mb-sm-0 { - margin-bottom: 0 !important; - } - - .mb-sm-1 { - margin-bottom: 0.25rem !important; - } - - .mb-sm-2 { - margin-bottom: 0.5rem !important; - } - - .mb-sm-3 { - margin-bottom: 1rem !important; - } - - .mb-sm-4 { - margin-bottom: 1.5rem !important; - } - - .mb-sm-5 { - margin-bottom: 3rem !important; - } - - .mb-sm-auto { - margin-bottom: auto !important; - } - - .ms-sm-0 { - margin-left: 0 !important; - } - - .ms-sm-1 { - margin-left: 0.25rem !important; - } - - .ms-sm-2 { - margin-left: 0.5rem !important; - } - - .ms-sm-3 { - margin-left: 1rem !important; - } - - .ms-sm-4 { - margin-left: 1.5rem !important; - } - - .ms-sm-5 { - margin-left: 3rem !important; - } - - .ms-sm-auto { - margin-left: auto !important; - } - - .p-sm-0 { - padding: 0 !important; - } - - .p-sm-1 { - padding: 0.25rem !important; - } - - .p-sm-2 { - padding: 0.5rem !important; - } - - .p-sm-3 { - padding: 1rem !important; - } - - .p-sm-4 { - padding: 1.5rem !important; - } - - .p-sm-5 { - padding: 3rem !important; - } - - .px-sm-0 { - padding-right: 0 !important; - padding-left: 0 !important; - } - - .px-sm-1 { - padding-right: 0.25rem !important; - padding-left: 0.25rem !important; - } - - .px-sm-2 { - padding-right: 0.5rem !important; - padding-left: 0.5rem !important; - } - - .px-sm-3 { - padding-right: 1rem !important; - padding-left: 1rem !important; - } - - .px-sm-4 { - padding-right: 1.5rem !important; - padding-left: 1.5rem !important; - } - - .px-sm-5 { - padding-right: 3rem !important; - padding-left: 3rem !important; - } - - .py-sm-0 { - padding-top: 0 !important; - padding-bottom: 0 !important; - } - - .py-sm-1 { - padding-top: 0.25rem !important; - padding-bottom: 0.25rem !important; - } - - .py-sm-2 { - padding-top: 0.5rem !important; - padding-bottom: 0.5rem !important; - } - - .py-sm-3 { - padding-top: 1rem !important; - padding-bottom: 1rem !important; - } - - .py-sm-4 { - padding-top: 1.5rem !important; - padding-bottom: 1.5rem !important; - } - - .py-sm-5 { - padding-top: 3rem !important; - padding-bottom: 3rem !important; - } - - .pt-sm-0 { - padding-top: 0 !important; - } - - .pt-sm-1 { - padding-top: 0.25rem !important; - } - - .pt-sm-2 { - padding-top: 0.5rem !important; - } - - .pt-sm-3 { - padding-top: 1rem !important; - } - - .pt-sm-4 { - padding-top: 1.5rem !important; - } - - .pt-sm-5 { - padding-top: 3rem !important; - } - - .pe-sm-0 { - padding-right: 0 !important; - } - - .pe-sm-1 { - padding-right: 0.25rem !important; - } - - .pe-sm-2 { - padding-right: 0.5rem !important; - } - - .pe-sm-3 { - padding-right: 1rem !important; - } - - .pe-sm-4 { - padding-right: 1.5rem !important; - } - - .pe-sm-5 { - padding-right: 3rem !important; - } - - .pb-sm-0 { - padding-bottom: 0 !important; - } - - .pb-sm-1 { - padding-bottom: 0.25rem !important; - } - - .pb-sm-2 { - padding-bottom: 0.5rem !important; - } - - .pb-sm-3 { - padding-bottom: 1rem !important; - } - - .pb-sm-4 { - padding-bottom: 1.5rem !important; - } - - .pb-sm-5 { - padding-bottom: 3rem !important; - } - - .ps-sm-0 { - padding-left: 0 !important; - } - - .ps-sm-1 { - padding-left: 0.25rem !important; - } - - .ps-sm-2 { - padding-left: 0.5rem !important; - } - - .ps-sm-3 { - padding-left: 1rem !important; - } - - .ps-sm-4 { - padding-left: 1.5rem !important; - } - - .ps-sm-5 { - padding-left: 3rem !important; - } - - .text-sm-start { - text-align: left !important; - } - - .text-sm-end { - text-align: right !important; - } - - .text-sm-center { - text-align: center !important; - } -} -@media (min-width: 768px) { - .float-md-start { - float: left !important; - } - - .float-md-end { - float: right !important; - } - - .float-md-none { - float: none !important; - } - - .d-md-inline { - display: inline !important; - } - - .d-md-inline-block { - display: inline-block !important; - } - - .d-md-block { - display: block !important; - } - - .d-md-grid { - display: grid !important; - } - - .d-md-table { - display: table !important; - } - - .d-md-table-row { - display: table-row !important; - } - - .d-md-table-cell { - display: table-cell !important; - } - - .d-md-flex { - display: flex !important; - } - - .d-md-inline-flex { - display: inline-flex !important; - } - - .d-md-none { - display: none !important; - } - - .flex-md-fill { - flex: 1 1 auto !important; - } - - .flex-md-row { - flex-direction: row !important; - } - - .flex-md-column { - flex-direction: column !important; - } - - .flex-md-row-reverse { - flex-direction: row-reverse !important; - } - - .flex-md-column-reverse { - flex-direction: column-reverse !important; - } - - .flex-md-grow-0 { - flex-grow: 0 !important; - } - - .flex-md-grow-1 { - flex-grow: 1 !important; - } - - .flex-md-shrink-0 { - flex-shrink: 0 !important; - } - - .flex-md-shrink-1 { - flex-shrink: 1 !important; - } - - .flex-md-wrap { - flex-wrap: wrap !important; - } - - .flex-md-nowrap { - flex-wrap: nowrap !important; - } - - .flex-md-wrap-reverse { - flex-wrap: wrap-reverse !important; - } - - .gap-md-0 { - gap: 0 !important; - } - - .gap-md-1 { - gap: 0.25rem !important; - } - - .gap-md-2 { - gap: 0.5rem !important; - } - - .gap-md-3 { - gap: 1rem !important; - } - - .gap-md-4 { - gap: 1.5rem !important; - } - - .gap-md-5 { - gap: 3rem !important; - } - - .justify-content-md-start { - justify-content: flex-start !important; - } - - .justify-content-md-end { - justify-content: flex-end !important; - } - - .justify-content-md-center { - justify-content: center !important; - } - - .justify-content-md-between { - justify-content: space-between !important; - } - - .justify-content-md-around { - justify-content: space-around !important; - } - - .justify-content-md-evenly { - justify-content: space-evenly !important; - } - - .align-items-md-start { - align-items: flex-start !important; - } - - .align-items-md-end { - align-items: flex-end !important; - } - - .align-items-md-center { - align-items: center !important; - } - - .align-items-md-baseline { - align-items: baseline !important; - } - - .align-items-md-stretch { - align-items: stretch !important; - } - - .align-content-md-start { - align-content: flex-start !important; - } - - .align-content-md-end { - align-content: flex-end !important; - } - - .align-content-md-center { - align-content: center !important; - } - - .align-content-md-between { - align-content: space-between !important; - } - - .align-content-md-around { - align-content: space-around !important; - } - - .align-content-md-stretch { - align-content: stretch !important; - } - - .align-self-md-auto { - align-self: auto !important; - } - - .align-self-md-start { - align-self: flex-start !important; - } - - .align-self-md-end { - align-self: flex-end !important; - } - - .align-self-md-center { - align-self: center !important; - } - - .align-self-md-baseline { - align-self: baseline !important; - } - - .align-self-md-stretch { - align-self: stretch !important; - } - - .order-md-first { - order: -1 !important; - } - - .order-md-0 { - order: 0 !important; - } - - .order-md-1 { - order: 1 !important; - } - - .order-md-2 { - order: 2 !important; - } - - .order-md-3 { - order: 3 !important; - } - - .order-md-4 { - order: 4 !important; - } - - .order-md-5 { - order: 5 !important; - } - - .order-md-last { - order: 6 !important; - } - - .m-md-0 { - margin: 0 !important; - } - - .m-md-1 { - margin: 0.25rem !important; - } - - .m-md-2 { - margin: 0.5rem !important; - } - - .m-md-3 { - margin: 1rem !important; - } - - .m-md-4 { - margin: 1.5rem !important; - } - - .m-md-5 { - margin: 3rem !important; - } - - .m-md-auto { - margin: auto !important; - } - - .mx-md-0 { - margin-right: 0 !important; - margin-left: 0 !important; - } - - .mx-md-1 { - margin-right: 0.25rem !important; - margin-left: 0.25rem !important; - } - - .mx-md-2 { - margin-right: 0.5rem !important; - margin-left: 0.5rem !important; - } - - .mx-md-3 { - margin-right: 1rem !important; - margin-left: 1rem !important; - } - - .mx-md-4 { - margin-right: 1.5rem !important; - margin-left: 1.5rem !important; - } - - .mx-md-5 { - margin-right: 3rem !important; - margin-left: 3rem !important; - } - - .mx-md-auto { - margin-right: auto !important; - margin-left: auto !important; - } - - .my-md-0 { - margin-top: 0 !important; - margin-bottom: 0 !important; - } - - .my-md-1 { - margin-top: 0.25rem !important; - margin-bottom: 0.25rem !important; - } - - .my-md-2 { - margin-top: 0.5rem !important; - margin-bottom: 0.5rem !important; - } - - .my-md-3 { - margin-top: 1rem !important; - margin-bottom: 1rem !important; - } - - .my-md-4 { - margin-top: 1.5rem !important; - margin-bottom: 1.5rem !important; - } - - .my-md-5 { - margin-top: 3rem !important; - margin-bottom: 3rem !important; - } - - .my-md-auto { - margin-top: auto !important; - margin-bottom: auto !important; - } - - .mt-md-0 { - margin-top: 0 !important; - } - - .mt-md-1 { - margin-top: 0.25rem !important; - } - - .mt-md-2 { - margin-top: 0.5rem !important; - } - - .mt-md-3 { - margin-top: 1rem !important; - } - - .mt-md-4 { - margin-top: 1.5rem !important; - } - - .mt-md-5 { - margin-top: 3rem !important; - } - - .mt-md-auto { - margin-top: auto !important; - } - - .me-md-0 { - margin-right: 0 !important; - } - - .me-md-1 { - margin-right: 0.25rem !important; - } - - .me-md-2 { - margin-right: 0.5rem !important; - } - - .me-md-3 { - margin-right: 1rem !important; - } - - .me-md-4 { - margin-right: 1.5rem !important; - } - - .me-md-5 { - margin-right: 3rem !important; - } - - .me-md-auto { - margin-right: auto !important; - } - - .mb-md-0 { - margin-bottom: 0 !important; - } - - .mb-md-1 { - margin-bottom: 0.25rem !important; - } - - .mb-md-2 { - margin-bottom: 0.5rem !important; - } - - .mb-md-3 { - margin-bottom: 1rem !important; - } - - .mb-md-4 { - margin-bottom: 1.5rem !important; - } - - .mb-md-5 { - margin-bottom: 3rem !important; - } - - .mb-md-auto { - margin-bottom: auto !important; - } - - .ms-md-0 { - margin-left: 0 !important; - } - - .ms-md-1 { - margin-left: 0.25rem !important; - } - - .ms-md-2 { - margin-left: 0.5rem !important; - } - - .ms-md-3 { - margin-left: 1rem !important; - } - - .ms-md-4 { - margin-left: 1.5rem !important; - } - - .ms-md-5 { - margin-left: 3rem !important; - } - - .ms-md-auto { - margin-left: auto !important; - } - - .p-md-0 { - padding: 0 !important; - } - - .p-md-1 { - padding: 0.25rem !important; - } - - .p-md-2 { - padding: 0.5rem !important; - } - - .p-md-3 { - padding: 1rem !important; - } - - .p-md-4 { - padding: 1.5rem !important; - } - - .p-md-5 { - padding: 3rem !important; - } - - .px-md-0 { - padding-right: 0 !important; - padding-left: 0 !important; - } - - .px-md-1 { - padding-right: 0.25rem !important; - padding-left: 0.25rem !important; - } - - .px-md-2 { - padding-right: 0.5rem !important; - padding-left: 0.5rem !important; - } - - .px-md-3 { - padding-right: 1rem !important; - padding-left: 1rem !important; - } - - .px-md-4 { - padding-right: 1.5rem !important; - padding-left: 1.5rem !important; - } - - .px-md-5 { - padding-right: 3rem !important; - padding-left: 3rem !important; - } - - .py-md-0 { - padding-top: 0 !important; - padding-bottom: 0 !important; - } - - .py-md-1 { - padding-top: 0.25rem !important; - padding-bottom: 0.25rem !important; - } - - .py-md-2 { - padding-top: 0.5rem !important; - padding-bottom: 0.5rem !important; - } - - .py-md-3 { - padding-top: 1rem !important; - padding-bottom: 1rem !important; - } - - .py-md-4 { - padding-top: 1.5rem !important; - padding-bottom: 1.5rem !important; - } - - .py-md-5 { - padding-top: 3rem !important; - padding-bottom: 3rem !important; - } - - .pt-md-0 { - padding-top: 0 !important; - } - - .pt-md-1 { - padding-top: 0.25rem !important; - } - - .pt-md-2 { - padding-top: 0.5rem !important; - } - - .pt-md-3 { - padding-top: 1rem !important; - } - - .pt-md-4 { - padding-top: 1.5rem !important; - } - - .pt-md-5 { - padding-top: 3rem !important; - } - - .pe-md-0 { - padding-right: 0 !important; - } - - .pe-md-1 { - padding-right: 0.25rem !important; - } - - .pe-md-2 { - padding-right: 0.5rem !important; - } - - .pe-md-3 { - padding-right: 1rem !important; - } - - .pe-md-4 { - padding-right: 1.5rem !important; - } - - .pe-md-5 { - padding-right: 3rem !important; - } - - .pb-md-0 { - padding-bottom: 0 !important; - } - - .pb-md-1 { - padding-bottom: 0.25rem !important; - } - - .pb-md-2 { - padding-bottom: 0.5rem !important; - } - - .pb-md-3 { - padding-bottom: 1rem !important; - } - - .pb-md-4 { - padding-bottom: 1.5rem !important; - } - - .pb-md-5 { - padding-bottom: 3rem !important; - } - - .ps-md-0 { - padding-left: 0 !important; - } - - .ps-md-1 { - padding-left: 0.25rem !important; - } - - .ps-md-2 { - padding-left: 0.5rem !important; - } - - .ps-md-3 { - padding-left: 1rem !important; - } - - .ps-md-4 { - padding-left: 1.5rem !important; - } - - .ps-md-5 { - padding-left: 3rem !important; - } - - .text-md-start { - text-align: left !important; - } - - .text-md-end { - text-align: right !important; - } - - .text-md-center { - text-align: center !important; - } -} -@media (min-width: 992px) { - .float-lg-start { - float: left !important; - } - - .float-lg-end { - float: right !important; - } - - .float-lg-none { - float: none !important; - } - - .d-lg-inline { - display: inline !important; - } - - .d-lg-inline-block { - display: inline-block !important; - } - - .d-lg-block { - display: block !important; - } - - .d-lg-grid { - display: grid !important; - } - - .d-lg-table { - display: table !important; - } - - .d-lg-table-row { - display: table-row !important; - } - - .d-lg-table-cell { - display: table-cell !important; - } - - .d-lg-flex { - display: flex !important; - } - - .d-lg-inline-flex { - display: inline-flex !important; - } - - .d-lg-none { - display: none !important; - } - - .flex-lg-fill { - flex: 1 1 auto !important; - } - - .flex-lg-row { - flex-direction: row !important; - } - - .flex-lg-column { - flex-direction: column !important; - } - - .flex-lg-row-reverse { - flex-direction: row-reverse !important; - } - - .flex-lg-column-reverse { - flex-direction: column-reverse !important; - } - - .flex-lg-grow-0 { - flex-grow: 0 !important; - } - - .flex-lg-grow-1 { - flex-grow: 1 !important; - } - - .flex-lg-shrink-0 { - flex-shrink: 0 !important; - } - - .flex-lg-shrink-1 { - flex-shrink: 1 !important; - } - - .flex-lg-wrap { - flex-wrap: wrap !important; - } - - .flex-lg-nowrap { - flex-wrap: nowrap !important; - } - - .flex-lg-wrap-reverse { - flex-wrap: wrap-reverse !important; - } - - .gap-lg-0 { - gap: 0 !important; - } - - .gap-lg-1 { - gap: 0.25rem !important; - } - - .gap-lg-2 { - gap: 0.5rem !important; - } - - .gap-lg-3 { - gap: 1rem !important; - } - - .gap-lg-4 { - gap: 1.5rem !important; - } - - .gap-lg-5 { - gap: 3rem !important; - } - - .justify-content-lg-start { - justify-content: flex-start !important; - } - - .justify-content-lg-end { - justify-content: flex-end !important; - } - - .justify-content-lg-center { - justify-content: center !important; - } - - .justify-content-lg-between { - justify-content: space-between !important; - } - - .justify-content-lg-around { - justify-content: space-around !important; - } - - .justify-content-lg-evenly { - justify-content: space-evenly !important; - } - - .align-items-lg-start { - align-items: flex-start !important; - } - - .align-items-lg-end { - align-items: flex-end !important; - } - - .align-items-lg-center { - align-items: center !important; - } - - .align-items-lg-baseline { - align-items: baseline !important; - } - - .align-items-lg-stretch { - align-items: stretch !important; - } - - .align-content-lg-start { - align-content: flex-start !important; - } - - .align-content-lg-end { - align-content: flex-end !important; - } - - .align-content-lg-center { - align-content: center !important; - } - - .align-content-lg-between { - align-content: space-between !important; - } - - .align-content-lg-around { - align-content: space-around !important; - } - - .align-content-lg-stretch { - align-content: stretch !important; - } - - .align-self-lg-auto { - align-self: auto !important; - } - - .align-self-lg-start { - align-self: flex-start !important; - } - - .align-self-lg-end { - align-self: flex-end !important; - } - - .align-self-lg-center { - align-self: center !important; - } - - .align-self-lg-baseline { - align-self: baseline !important; - } - - .align-self-lg-stretch { - align-self: stretch !important; - } - - .order-lg-first { - order: -1 !important; - } - - .order-lg-0 { - order: 0 !important; - } - - .order-lg-1 { - order: 1 !important; - } - - .order-lg-2 { - order: 2 !important; - } - - .order-lg-3 { - order: 3 !important; - } - - .order-lg-4 { - order: 4 !important; - } - - .order-lg-5 { - order: 5 !important; - } - - .order-lg-last { - order: 6 !important; - } - - .m-lg-0 { - margin: 0 !important; - } - - .m-lg-1 { - margin: 0.25rem !important; - } - - .m-lg-2 { - margin: 0.5rem !important; - } - - .m-lg-3 { - margin: 1rem !important; - } - - .m-lg-4 { - margin: 1.5rem !important; - } - - .m-lg-5 { - margin: 3rem !important; - } - - .m-lg-auto { - margin: auto !important; - } - - .mx-lg-0 { - margin-right: 0 !important; - margin-left: 0 !important; - } - - .mx-lg-1 { - margin-right: 0.25rem !important; - margin-left: 0.25rem !important; - } - - .mx-lg-2 { - margin-right: 0.5rem !important; - margin-left: 0.5rem !important; - } - - .mx-lg-3 { - margin-right: 1rem !important; - margin-left: 1rem !important; - } - - .mx-lg-4 { - margin-right: 1.5rem !important; - margin-left: 1.5rem !important; - } - - .mx-lg-5 { - margin-right: 3rem !important; - margin-left: 3rem !important; - } - - .mx-lg-auto { - margin-right: auto !important; - margin-left: auto !important; - } - - .my-lg-0 { - margin-top: 0 !important; - margin-bottom: 0 !important; - } - - .my-lg-1 { - margin-top: 0.25rem !important; - margin-bottom: 0.25rem !important; - } - - .my-lg-2 { - margin-top: 0.5rem !important; - margin-bottom: 0.5rem !important; - } - - .my-lg-3 { - margin-top: 1rem !important; - margin-bottom: 1rem !important; - } - - .my-lg-4 { - margin-top: 1.5rem !important; - margin-bottom: 1.5rem !important; - } - - .my-lg-5 { - margin-top: 3rem !important; - margin-bottom: 3rem !important; - } - - .my-lg-auto { - margin-top: auto !important; - margin-bottom: auto !important; - } - - .mt-lg-0 { - margin-top: 0 !important; - } - - .mt-lg-1 { - margin-top: 0.25rem !important; - } - - .mt-lg-2 { - margin-top: 0.5rem !important; - } - - .mt-lg-3 { - margin-top: 1rem !important; - } - - .mt-lg-4 { - margin-top: 1.5rem !important; - } - - .mt-lg-5 { - margin-top: 3rem !important; - } - - .mt-lg-auto { - margin-top: auto !important; - } - - .me-lg-0 { - margin-right: 0 !important; - } - - .me-lg-1 { - margin-right: 0.25rem !important; - } - - .me-lg-2 { - margin-right: 0.5rem !important; - } - - .me-lg-3 { - margin-right: 1rem !important; - } - - .me-lg-4 { - margin-right: 1.5rem !important; - } - - .me-lg-5 { - margin-right: 3rem !important; - } - - .me-lg-auto { - margin-right: auto !important; - } - - .mb-lg-0 { - margin-bottom: 0 !important; - } - - .mb-lg-1 { - margin-bottom: 0.25rem !important; - } - - .mb-lg-2 { - margin-bottom: 0.5rem !important; - } - - .mb-lg-3 { - margin-bottom: 1rem !important; - } - - .mb-lg-4 { - margin-bottom: 1.5rem !important; - } - - .mb-lg-5 { - margin-bottom: 3rem !important; - } - - .mb-lg-auto { - margin-bottom: auto !important; - } - - .ms-lg-0 { - margin-left: 0 !important; - } - - .ms-lg-1 { - margin-left: 0.25rem !important; - } - - .ms-lg-2 { - margin-left: 0.5rem !important; - } - - .ms-lg-3 { - margin-left: 1rem !important; - } - - .ms-lg-4 { - margin-left: 1.5rem !important; - } - - .ms-lg-5 { - margin-left: 3rem !important; - } - - .ms-lg-auto { - margin-left: auto !important; - } - - .p-lg-0 { - padding: 0 !important; - } - - .p-lg-1 { - padding: 0.25rem !important; - } - - .p-lg-2 { - padding: 0.5rem !important; - } - - .p-lg-3 { - padding: 1rem !important; - } - - .p-lg-4 { - padding: 1.5rem !important; - } - - .p-lg-5 { - padding: 3rem !important; - } - - .px-lg-0 { - padding-right: 0 !important; - padding-left: 0 !important; - } - - .px-lg-1 { - padding-right: 0.25rem !important; - padding-left: 0.25rem !important; - } - - .px-lg-2 { - padding-right: 0.5rem !important; - padding-left: 0.5rem !important; - } - - .px-lg-3 { - padding-right: 1rem !important; - padding-left: 1rem !important; - } - - .px-lg-4 { - padding-right: 1.5rem !important; - padding-left: 1.5rem !important; - } - - .px-lg-5 { - padding-right: 3rem !important; - padding-left: 3rem !important; - } - - .py-lg-0 { - padding-top: 0 !important; - padding-bottom: 0 !important; - } - - .py-lg-1 { - padding-top: 0.25rem !important; - padding-bottom: 0.25rem !important; - } - - .py-lg-2 { - padding-top: 0.5rem !important; - padding-bottom: 0.5rem !important; - } - - .py-lg-3 { - padding-top: 1rem !important; - padding-bottom: 1rem !important; - } - - .py-lg-4 { - padding-top: 1.5rem !important; - padding-bottom: 1.5rem !important; - } - - .py-lg-5 { - padding-top: 3rem !important; - padding-bottom: 3rem !important; - } - - .pt-lg-0 { - padding-top: 0 !important; - } - - .pt-lg-1 { - padding-top: 0.25rem !important; - } - - .pt-lg-2 { - padding-top: 0.5rem !important; - } - - .pt-lg-3 { - padding-top: 1rem !important; - } - - .pt-lg-4 { - padding-top: 1.5rem !important; - } - - .pt-lg-5 { - padding-top: 3rem !important; - } - - .pe-lg-0 { - padding-right: 0 !important; - } - - .pe-lg-1 { - padding-right: 0.25rem !important; - } - - .pe-lg-2 { - padding-right: 0.5rem !important; - } - - .pe-lg-3 { - padding-right: 1rem !important; - } - - .pe-lg-4 { - padding-right: 1.5rem !important; - } - - .pe-lg-5 { - padding-right: 3rem !important; - } - - .pb-lg-0 { - padding-bottom: 0 !important; - } - - .pb-lg-1 { - padding-bottom: 0.25rem !important; - } - - .pb-lg-2 { - padding-bottom: 0.5rem !important; - } - - .pb-lg-3 { - padding-bottom: 1rem !important; - } - - .pb-lg-4 { - padding-bottom: 1.5rem !important; - } - - .pb-lg-5 { - padding-bottom: 3rem !important; - } - - .ps-lg-0 { - padding-left: 0 !important; - } - - .ps-lg-1 { - padding-left: 0.25rem !important; - } - - .ps-lg-2 { - padding-left: 0.5rem !important; - } - - .ps-lg-3 { - padding-left: 1rem !important; - } - - .ps-lg-4 { - padding-left: 1.5rem !important; - } - - .ps-lg-5 { - padding-left: 3rem !important; - } - - .text-lg-start { - text-align: left !important; - } - - .text-lg-end { - text-align: right !important; - } - - .text-lg-center { - text-align: center !important; - } -} -@media (min-width: 1200px) { - .float-xl-start { - float: left !important; - } - - .float-xl-end { - float: right !important; - } - - .float-xl-none { - float: none !important; - } - - .d-xl-inline { - display: inline !important; - } - - .d-xl-inline-block { - display: inline-block !important; - } - - .d-xl-block { - display: block !important; - } - - .d-xl-grid { - display: grid !important; - } - - .d-xl-table { - display: table !important; - } - - .d-xl-table-row { - display: table-row !important; - } - - .d-xl-table-cell { - display: table-cell !important; - } - - .d-xl-flex { - display: flex !important; - } - - .d-xl-inline-flex { - display: inline-flex !important; - } - - .d-xl-none { - display: none !important; - } - - .flex-xl-fill { - flex: 1 1 auto !important; - } - - .flex-xl-row { - flex-direction: row !important; - } - - .flex-xl-column { - flex-direction: column !important; - } - - .flex-xl-row-reverse { - flex-direction: row-reverse !important; - } - - .flex-xl-column-reverse { - flex-direction: column-reverse !important; - } - - .flex-xl-grow-0 { - flex-grow: 0 !important; - } - - .flex-xl-grow-1 { - flex-grow: 1 !important; - } - - .flex-xl-shrink-0 { - flex-shrink: 0 !important; - } - - .flex-xl-shrink-1 { - flex-shrink: 1 !important; - } - - .flex-xl-wrap { - flex-wrap: wrap !important; - } - - .flex-xl-nowrap { - flex-wrap: nowrap !important; - } - - .flex-xl-wrap-reverse { - flex-wrap: wrap-reverse !important; - } - - .gap-xl-0 { - gap: 0 !important; - } - - .gap-xl-1 { - gap: 0.25rem !important; - } - - .gap-xl-2 { - gap: 0.5rem !important; - } - - .gap-xl-3 { - gap: 1rem !important; - } - - .gap-xl-4 { - gap: 1.5rem !important; - } - - .gap-xl-5 { - gap: 3rem !important; - } - - .justify-content-xl-start { - justify-content: flex-start !important; - } - - .justify-content-xl-end { - justify-content: flex-end !important; - } - - .justify-content-xl-center { - justify-content: center !important; - } - - .justify-content-xl-between { - justify-content: space-between !important; - } - - .justify-content-xl-around { - justify-content: space-around !important; - } - - .justify-content-xl-evenly { - justify-content: space-evenly !important; - } - - .align-items-xl-start { - align-items: flex-start !important; - } - - .align-items-xl-end { - align-items: flex-end !important; - } - - .align-items-xl-center { - align-items: center !important; - } - - .align-items-xl-baseline { - align-items: baseline !important; - } - - .align-items-xl-stretch { - align-items: stretch !important; - } - - .align-content-xl-start { - align-content: flex-start !important; - } - - .align-content-xl-end { - align-content: flex-end !important; - } - - .align-content-xl-center { - align-content: center !important; - } - - .align-content-xl-between { - align-content: space-between !important; - } - - .align-content-xl-around { - align-content: space-around !important; - } - - .align-content-xl-stretch { - align-content: stretch !important; - } - - .align-self-xl-auto { - align-self: auto !important; - } - - .align-self-xl-start { - align-self: flex-start !important; - } - - .align-self-xl-end { - align-self: flex-end !important; - } - - .align-self-xl-center { - align-self: center !important; - } - - .align-self-xl-baseline { - align-self: baseline !important; - } - - .align-self-xl-stretch { - align-self: stretch !important; - } - - .order-xl-first { - order: -1 !important; - } - - .order-xl-0 { - order: 0 !important; - } - - .order-xl-1 { - order: 1 !important; - } - - .order-xl-2 { - order: 2 !important; - } - - .order-xl-3 { - order: 3 !important; - } - - .order-xl-4 { - order: 4 !important; - } - - .order-xl-5 { - order: 5 !important; - } - - .order-xl-last { - order: 6 !important; - } - - .m-xl-0 { - margin: 0 !important; - } - - .m-xl-1 { - margin: 0.25rem !important; - } - - .m-xl-2 { - margin: 0.5rem !important; - } - - .m-xl-3 { - margin: 1rem !important; - } - - .m-xl-4 { - margin: 1.5rem !important; - } - - .m-xl-5 { - margin: 3rem !important; - } - - .m-xl-auto { - margin: auto !important; - } - - .mx-xl-0 { - margin-right: 0 !important; - margin-left: 0 !important; - } - - .mx-xl-1 { - margin-right: 0.25rem !important; - margin-left: 0.25rem !important; - } - - .mx-xl-2 { - margin-right: 0.5rem !important; - margin-left: 0.5rem !important; - } - - .mx-xl-3 { - margin-right: 1rem !important; - margin-left: 1rem !important; - } - - .mx-xl-4 { - margin-right: 1.5rem !important; - margin-left: 1.5rem !important; - } - - .mx-xl-5 { - margin-right: 3rem !important; - margin-left: 3rem !important; - } - - .mx-xl-auto { - margin-right: auto !important; - margin-left: auto !important; - } - - .my-xl-0 { - margin-top: 0 !important; - margin-bottom: 0 !important; - } - - .my-xl-1 { - margin-top: 0.25rem !important; - margin-bottom: 0.25rem !important; - } - - .my-xl-2 { - margin-top: 0.5rem !important; - margin-bottom: 0.5rem !important; - } - - .my-xl-3 { - margin-top: 1rem !important; - margin-bottom: 1rem !important; - } - - .my-xl-4 { - margin-top: 1.5rem !important; - margin-bottom: 1.5rem !important; - } - - .my-xl-5 { - margin-top: 3rem !important; - margin-bottom: 3rem !important; - } - - .my-xl-auto { - margin-top: auto !important; - margin-bottom: auto !important; - } - - .mt-xl-0 { - margin-top: 0 !important; - } - - .mt-xl-1 { - margin-top: 0.25rem !important; - } - - .mt-xl-2 { - margin-top: 0.5rem !important; - } - - .mt-xl-3 { - margin-top: 1rem !important; - } - - .mt-xl-4 { - margin-top: 1.5rem !important; - } - - .mt-xl-5 { - margin-top: 3rem !important; - } - - .mt-xl-auto { - margin-top: auto !important; - } - - .me-xl-0 { - margin-right: 0 !important; - } - - .me-xl-1 { - margin-right: 0.25rem !important; - } - - .me-xl-2 { - margin-right: 0.5rem !important; - } - - .me-xl-3 { - margin-right: 1rem !important; - } - - .me-xl-4 { - margin-right: 1.5rem !important; - } - - .me-xl-5 { - margin-right: 3rem !important; - } - - .me-xl-auto { - margin-right: auto !important; - } - - .mb-xl-0 { - margin-bottom: 0 !important; - } - - .mb-xl-1 { - margin-bottom: 0.25rem !important; - } - - .mb-xl-2 { - margin-bottom: 0.5rem !important; - } - - .mb-xl-3 { - margin-bottom: 1rem !important; - } - - .mb-xl-4 { - margin-bottom: 1.5rem !important; - } - - .mb-xl-5 { - margin-bottom: 3rem !important; - } - - .mb-xl-auto { - margin-bottom: auto !important; - } - - .ms-xl-0 { - margin-left: 0 !important; - } - - .ms-xl-1 { - margin-left: 0.25rem !important; - } - - .ms-xl-2 { - margin-left: 0.5rem !important; - } - - .ms-xl-3 { - margin-left: 1rem !important; - } - - .ms-xl-4 { - margin-left: 1.5rem !important; - } - - .ms-xl-5 { - margin-left: 3rem !important; - } - - .ms-xl-auto { - margin-left: auto !important; - } - - .p-xl-0 { - padding: 0 !important; - } - - .p-xl-1 { - padding: 0.25rem !important; - } - - .p-xl-2 { - padding: 0.5rem !important; - } - - .p-xl-3 { - padding: 1rem !important; - } - - .p-xl-4 { - padding: 1.5rem !important; - } - - .p-xl-5 { - padding: 3rem !important; - } - - .px-xl-0 { - padding-right: 0 !important; - padding-left: 0 !important; - } - - .px-xl-1 { - padding-right: 0.25rem !important; - padding-left: 0.25rem !important; - } - - .px-xl-2 { - padding-right: 0.5rem !important; - padding-left: 0.5rem !important; - } - - .px-xl-3 { - padding-right: 1rem !important; - padding-left: 1rem !important; - } - - .px-xl-4 { - padding-right: 1.5rem !important; - padding-left: 1.5rem !important; - } - - .px-xl-5 { - padding-right: 3rem !important; - padding-left: 3rem !important; - } - - .py-xl-0 { - padding-top: 0 !important; - padding-bottom: 0 !important; - } - - .py-xl-1 { - padding-top: 0.25rem !important; - padding-bottom: 0.25rem !important; - } - - .py-xl-2 { - padding-top: 0.5rem !important; - padding-bottom: 0.5rem !important; - } - - .py-xl-3 { - padding-top: 1rem !important; - padding-bottom: 1rem !important; - } - - .py-xl-4 { - padding-top: 1.5rem !important; - padding-bottom: 1.5rem !important; - } - - .py-xl-5 { - padding-top: 3rem !important; - padding-bottom: 3rem !important; - } - - .pt-xl-0 { - padding-top: 0 !important; - } - - .pt-xl-1 { - padding-top: 0.25rem !important; - } - - .pt-xl-2 { - padding-top: 0.5rem !important; - } - - .pt-xl-3 { - padding-top: 1rem !important; - } - - .pt-xl-4 { - padding-top: 1.5rem !important; - } - - .pt-xl-5 { - padding-top: 3rem !important; - } - - .pe-xl-0 { - padding-right: 0 !important; - } - - .pe-xl-1 { - padding-right: 0.25rem !important; - } - - .pe-xl-2 { - padding-right: 0.5rem !important; - } - - .pe-xl-3 { - padding-right: 1rem !important; - } - - .pe-xl-4 { - padding-right: 1.5rem !important; - } - - .pe-xl-5 { - padding-right: 3rem !important; - } - - .pb-xl-0 { - padding-bottom: 0 !important; - } - - .pb-xl-1 { - padding-bottom: 0.25rem !important; - } - - .pb-xl-2 { - padding-bottom: 0.5rem !important; - } - - .pb-xl-3 { - padding-bottom: 1rem !important; - } - - .pb-xl-4 { - padding-bottom: 1.5rem !important; - } - - .pb-xl-5 { - padding-bottom: 3rem !important; - } - - .ps-xl-0 { - padding-left: 0 !important; - } - - .ps-xl-1 { - padding-left: 0.25rem !important; - } - - .ps-xl-2 { - padding-left: 0.5rem !important; - } - - .ps-xl-3 { - padding-left: 1rem !important; - } - - .ps-xl-4 { - padding-left: 1.5rem !important; - } - - .ps-xl-5 { - padding-left: 3rem !important; - } - - .text-xl-start { - text-align: left !important; - } - - .text-xl-end { - text-align: right !important; - } - - .text-xl-center { - text-align: center !important; - } -} -@media (min-width: 1400px) { - .float-xxl-start { - float: left !important; - } - - .float-xxl-end { - float: right !important; - } - - .float-xxl-none { - float: none !important; - } - - .d-xxl-inline { - display: inline !important; - } - - .d-xxl-inline-block { - display: inline-block !important; - } - - .d-xxl-block { - display: block !important; - } - - .d-xxl-grid { - display: grid !important; - } - - .d-xxl-table { - display: table !important; - } - - .d-xxl-table-row { - display: table-row !important; - } - - .d-xxl-table-cell { - display: table-cell !important; - } - - .d-xxl-flex { - display: flex !important; - } - - .d-xxl-inline-flex { - display: inline-flex !important; - } - - .d-xxl-none { - display: none !important; - } - - .flex-xxl-fill { - flex: 1 1 auto !important; - } - - .flex-xxl-row { - flex-direction: row !important; - } - - .flex-xxl-column { - flex-direction: column !important; - } - - .flex-xxl-row-reverse { - flex-direction: row-reverse !important; - } - - .flex-xxl-column-reverse { - flex-direction: column-reverse !important; - } - - .flex-xxl-grow-0 { - flex-grow: 0 !important; - } - - .flex-xxl-grow-1 { - flex-grow: 1 !important; - } - - .flex-xxl-shrink-0 { - flex-shrink: 0 !important; - } - - .flex-xxl-shrink-1 { - flex-shrink: 1 !important; - } - - .flex-xxl-wrap { - flex-wrap: wrap !important; - } - - .flex-xxl-nowrap { - flex-wrap: nowrap !important; - } - - .flex-xxl-wrap-reverse { - flex-wrap: wrap-reverse !important; - } - - .gap-xxl-0 { - gap: 0 !important; - } - - .gap-xxl-1 { - gap: 0.25rem !important; - } - - .gap-xxl-2 { - gap: 0.5rem !important; - } - - .gap-xxl-3 { - gap: 1rem !important; - } - - .gap-xxl-4 { - gap: 1.5rem !important; - } - - .gap-xxl-5 { - gap: 3rem !important; - } - - .justify-content-xxl-start { - justify-content: flex-start !important; - } - - .justify-content-xxl-end { - justify-content: flex-end !important; - } - - .justify-content-xxl-center { - justify-content: center !important; - } - - .justify-content-xxl-between { - justify-content: space-between !important; - } - - .justify-content-xxl-around { - justify-content: space-around !important; - } - - .justify-content-xxl-evenly { - justify-content: space-evenly !important; - } - - .align-items-xxl-start { - align-items: flex-start !important; - } - - .align-items-xxl-end { - align-items: flex-end !important; - } - - .align-items-xxl-center { - align-items: center !important; - } - - .align-items-xxl-baseline { - align-items: baseline !important; - } - - .align-items-xxl-stretch { - align-items: stretch !important; - } - - .align-content-xxl-start { - align-content: flex-start !important; - } - - .align-content-xxl-end { - align-content: flex-end !important; - } - - .align-content-xxl-center { - align-content: center !important; - } - - .align-content-xxl-between { - align-content: space-between !important; - } - - .align-content-xxl-around { - align-content: space-around !important; - } - - .align-content-xxl-stretch { - align-content: stretch !important; - } - - .align-self-xxl-auto { - align-self: auto !important; - } - - .align-self-xxl-start { - align-self: flex-start !important; - } - - .align-self-xxl-end { - align-self: flex-end !important; - } - - .align-self-xxl-center { - align-self: center !important; - } - - .align-self-xxl-baseline { - align-self: baseline !important; - } - - .align-self-xxl-stretch { - align-self: stretch !important; - } - - .order-xxl-first { - order: -1 !important; - } - - .order-xxl-0 { - order: 0 !important; - } - - .order-xxl-1 { - order: 1 !important; - } - - .order-xxl-2 { - order: 2 !important; - } - - .order-xxl-3 { - order: 3 !important; - } - - .order-xxl-4 { - order: 4 !important; - } - - .order-xxl-5 { - order: 5 !important; - } - - .order-xxl-last { - order: 6 !important; - } - - .m-xxl-0 { - margin: 0 !important; - } - - .m-xxl-1 { - margin: 0.25rem !important; - } - - .m-xxl-2 { - margin: 0.5rem !important; - } - - .m-xxl-3 { - margin: 1rem !important; - } - - .m-xxl-4 { - margin: 1.5rem !important; - } - - .m-xxl-5 { - margin: 3rem !important; - } - - .m-xxl-auto { - margin: auto !important; - } - - .mx-xxl-0 { - margin-right: 0 !important; - margin-left: 0 !important; - } - - .mx-xxl-1 { - margin-right: 0.25rem !important; - margin-left: 0.25rem !important; - } - - .mx-xxl-2 { - margin-right: 0.5rem !important; - margin-left: 0.5rem !important; - } - - .mx-xxl-3 { - margin-right: 1rem !important; - margin-left: 1rem !important; - } - - .mx-xxl-4 { - margin-right: 1.5rem !important; - margin-left: 1.5rem !important; - } - - .mx-xxl-5 { - margin-right: 3rem !important; - margin-left: 3rem !important; - } - - .mx-xxl-auto { - margin-right: auto !important; - margin-left: auto !important; - } - - .my-xxl-0 { - margin-top: 0 !important; - margin-bottom: 0 !important; - } - - .my-xxl-1 { - margin-top: 0.25rem !important; - margin-bottom: 0.25rem !important; - } - - .my-xxl-2 { - margin-top: 0.5rem !important; - margin-bottom: 0.5rem !important; - } - - .my-xxl-3 { - margin-top: 1rem !important; - margin-bottom: 1rem !important; - } - - .my-xxl-4 { - margin-top: 1.5rem !important; - margin-bottom: 1.5rem !important; - } - - .my-xxl-5 { - margin-top: 3rem !important; - margin-bottom: 3rem !important; - } - - .my-xxl-auto { - margin-top: auto !important; - margin-bottom: auto !important; - } - - .mt-xxl-0 { - margin-top: 0 !important; - } - - .mt-xxl-1 { - margin-top: 0.25rem !important; - } - - .mt-xxl-2 { - margin-top: 0.5rem !important; - } - - .mt-xxl-3 { - margin-top: 1rem !important; - } - - .mt-xxl-4 { - margin-top: 1.5rem !important; - } - - .mt-xxl-5 { - margin-top: 3rem !important; - } - - .mt-xxl-auto { - margin-top: auto !important; - } - - .me-xxl-0 { - margin-right: 0 !important; - } - - .me-xxl-1 { - margin-right: 0.25rem !important; - } - - .me-xxl-2 { - margin-right: 0.5rem !important; - } - - .me-xxl-3 { - margin-right: 1rem !important; - } - - .me-xxl-4 { - margin-right: 1.5rem !important; - } - - .me-xxl-5 { - margin-right: 3rem !important; - } - - .me-xxl-auto { - margin-right: auto !important; - } - - .mb-xxl-0 { - margin-bottom: 0 !important; - } - - .mb-xxl-1 { - margin-bottom: 0.25rem !important; - } - - .mb-xxl-2 { - margin-bottom: 0.5rem !important; - } - - .mb-xxl-3 { - margin-bottom: 1rem !important; - } - - .mb-xxl-4 { - margin-bottom: 1.5rem !important; - } - - .mb-xxl-5 { - margin-bottom: 3rem !important; - } - - .mb-xxl-auto { - margin-bottom: auto !important; - } - - .ms-xxl-0 { - margin-left: 0 !important; - } - - .ms-xxl-1 { - margin-left: 0.25rem !important; - } - - .ms-xxl-2 { - margin-left: 0.5rem !important; - } - - .ms-xxl-3 { - margin-left: 1rem !important; - } - - .ms-xxl-4 { - margin-left: 1.5rem !important; - } - - .ms-xxl-5 { - margin-left: 3rem !important; - } - - .ms-xxl-auto { - margin-left: auto !important; - } - - .p-xxl-0 { - padding: 0 !important; - } - - .p-xxl-1 { - padding: 0.25rem !important; - } - - .p-xxl-2 { - padding: 0.5rem !important; - } - - .p-xxl-3 { - padding: 1rem !important; - } - - .p-xxl-4 { - padding: 1.5rem !important; - } - - .p-xxl-5 { - padding: 3rem !important; - } - - .px-xxl-0 { - padding-right: 0 !important; - padding-left: 0 !important; - } - - .px-xxl-1 { - padding-right: 0.25rem !important; - padding-left: 0.25rem !important; - } - - .px-xxl-2 { - padding-right: 0.5rem !important; - padding-left: 0.5rem !important; - } - - .px-xxl-3 { - padding-right: 1rem !important; - padding-left: 1rem !important; - } - - .px-xxl-4 { - padding-right: 1.5rem !important; - padding-left: 1.5rem !important; - } - - .px-xxl-5 { - padding-right: 3rem !important; - padding-left: 3rem !important; - } - - .py-xxl-0 { - padding-top: 0 !important; - padding-bottom: 0 !important; - } - - .py-xxl-1 { - padding-top: 0.25rem !important; - padding-bottom: 0.25rem !important; - } - - .py-xxl-2 { - padding-top: 0.5rem !important; - padding-bottom: 0.5rem !important; - } - - .py-xxl-3 { - padding-top: 1rem !important; - padding-bottom: 1rem !important; - } - - .py-xxl-4 { - padding-top: 1.5rem !important; - padding-bottom: 1.5rem !important; - } - - .py-xxl-5 { - padding-top: 3rem !important; - padding-bottom: 3rem !important; - } - - .pt-xxl-0 { - padding-top: 0 !important; - } - - .pt-xxl-1 { - padding-top: 0.25rem !important; - } - - .pt-xxl-2 { - padding-top: 0.5rem !important; - } - - .pt-xxl-3 { - padding-top: 1rem !important; - } - - .pt-xxl-4 { - padding-top: 1.5rem !important; - } - - .pt-xxl-5 { - padding-top: 3rem !important; - } - - .pe-xxl-0 { - padding-right: 0 !important; - } - - .pe-xxl-1 { - padding-right: 0.25rem !important; - } - - .pe-xxl-2 { - padding-right: 0.5rem !important; - } - - .pe-xxl-3 { - padding-right: 1rem !important; - } - - .pe-xxl-4 { - padding-right: 1.5rem !important; - } - - .pe-xxl-5 { - padding-right: 3rem !important; - } - - .pb-xxl-0 { - padding-bottom: 0 !important; - } - - .pb-xxl-1 { - padding-bottom: 0.25rem !important; - } - - .pb-xxl-2 { - padding-bottom: 0.5rem !important; - } - - .pb-xxl-3 { - padding-bottom: 1rem !important; - } - - .pb-xxl-4 { - padding-bottom: 1.5rem !important; - } - - .pb-xxl-5 { - padding-bottom: 3rem !important; - } - - .ps-xxl-0 { - padding-left: 0 !important; - } - - .ps-xxl-1 { - padding-left: 0.25rem !important; - } - - .ps-xxl-2 { - padding-left: 0.5rem !important; - } - - .ps-xxl-3 { - padding-left: 1rem !important; - } - - .ps-xxl-4 { - padding-left: 1.5rem !important; - } - - .ps-xxl-5 { - padding-left: 3rem !important; - } - - .text-xxl-start { - text-align: left !important; - } - - .text-xxl-end { - text-align: right !important; - } - - .text-xxl-center { - text-align: center !important; - } -} -@media (min-width: 1200px) { - .fs-1 { - font-size: 2.5rem !important; - } - - .fs-2 { - font-size: 2rem !important; - } - - .fs-3 { - font-size: 1.75rem !important; - } - - .fs-4 { - font-size: 1.5rem !important; - } -} -@media print { - .d-print-inline { - display: inline !important; - } - - .d-print-inline-block { - display: inline-block !important; - } - - .d-print-block { - display: block !important; - } - - .d-print-grid { - display: grid !important; - } - - .d-print-table { - display: table !important; - } - - .d-print-table-row { - display: table-row !important; - } - - .d-print-table-cell { - display: table-cell !important; - } - - .d-print-flex { - display: flex !important; - } - - .d-print-inline-flex { - display: inline-flex !important; - } - - .d-print-none { - display: none !important; - } -} - +@charset "UTF-8"; +/*! + * Bootstrap v5.0.1 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +:root { + --bs-blue: #0d6efd; + --bs-indigo: #6610f2; + --bs-purple: #6f42c1; + --bs-pink: #d63384; + --bs-red: #dc3545; + --bs-orange: #fd7e14; + --bs-yellow: #ffc107; + --bs-green: #198754; + --bs-teal: #20c997; + --bs-cyan: #0dcaf0; + --bs-white: #fff; + --bs-gray: #6c757d; + --bs-gray-dark: #343a40; + --bs-primary: #0d6efd; + --bs-secondary: #6c757d; + --bs-success: #198754; + --bs-info: #0dcaf0; + --bs-warning: #ffc107; + --bs-danger: #dc3545; + --bs-light: #f8f9fa; + --bs-dark: #212529; + --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); +} + +@media (prefers-reduced-motion: no-preference) { + :root { + scroll-behavior: smooth; + } +} + +.h6, .h5, .h4, .h3, .h2, .h1 { + margin-top: 0; + margin-bottom: 0.5rem; + font-weight: 500; + line-height: 1.2; +} + +.h1 { + font-size: calc(1.375rem + 1.5vw); +} +@media (min-width: 1200px) { + .h1 { + font-size: 2.5rem; + } +} + +.h2 { + font-size: calc(1.325rem + 0.9vw); +} +@media (min-width: 1200px) { + .h2 { + font-size: 2rem; + } +} + +.h3 { + font-size: calc(1.3rem + 0.6vw); +} +@media (min-width: 1200px) { + .h3 { + font-size: 1.75rem; + } +} + +.h4 { + font-size: calc(1.275rem + 0.3vw); +} +@media (min-width: 1200px) { + .h4 { + font-size: 1.5rem; + } +} + +.h5 { + font-size: 1.25rem; +} + +.h6 { + font-size: 1rem; +} + +.p { + margin-top: 0; + margin-bottom: 1rem; +} + + +abbr[title], +abbr[data-bs-original-title] { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + cursor: help; + -webkit-text-decoration-skip-ink: none; + text-decoration-skip-ink: none; +} + +address { + margin-bottom: 1rem; + font-style: normal; + line-height: inherit; +} + +ol, +ul { + padding-left: 2rem; +} + +ol, +ul, +dl { + margin-top: 0; + margin-bottom: 1rem; +} + +ol ol, +ul ul, +ol ul, +ul ol { + margin-bottom: 0; +} + +dt { + font-weight: 700; +} + +dd { + margin-bottom: 0.5rem; + margin-left: 0; +} + +blockquote { + margin: 0 0 1rem; +} + +b, +strong { + font-weight: bolder; +} + +small, .small { + font-size: 0.875em; +} + +mark, .mark { + padding: 0.2em; + background-color: #fcf8e3; +} + +sub, +sup { + position: relative; + font-size: 0.75em; + line-height: 0; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +a { + color: #0d6efd; + text-decoration: underline; +} +a:hover { + color: #0a58ca; +} + +a:not([href]):not([class]), a:not([href]):not([class]):hover { + color: inherit; + text-decoration: none; +} + +pre, +code, +kbd, +samp { + font-family: var(--bs-font-monospace); + font-size: 1em; + direction: ltr /* rtl:ignore */; + unicode-bidi: bidi-override; +} + +pre { + display: block; + margin-top: 0; + margin-bottom: 1rem; + overflow: auto; + font-size: 0.875em; +} +pre code { + font-size: inherit; + color: inherit; + word-break: normal; +} + +code { + font-size: 0.875em; + color: #d63384; + word-wrap: break-word; +} +a > code { + color: inherit; +} + +kbd { + padding: 0.2rem 0.4rem; + font-size: 0.875em; + color: #fff; + background-color: #212529; + border-radius: 0.2rem; +} +kbd kbd { + padding: 0; + font-size: 1em; + font-weight: 700; +} + +figure { + margin: 0 0 1rem; +} + +img, +svg { + vertical-align: middle; +} + +table { + caption-side: bottom; + border-collapse: collapse; +} + +caption { + padding-top: 0.5rem; + padding-bottom: 0.5rem; + color: #6c757d; + text-align: left; +} + +th { + text-align: inherit; + text-align: -webkit-match-parent; +} + +thead, +tbody, +tfoot, +tr, +td, +th { + border-color: inherit; + border-style: solid; + border-width: 0; +} + +label { + display: inline-block; +} + +button { + border-radius: 0; +} + +button:focus:not(:focus-visible) { + outline: 0; +} + +input, +button, +select, +optgroup, +textarea { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +button, +select { + text-transform: none; +} + +[role=button] { + cursor: pointer; +} + +select { + word-wrap: normal; +} +select:disabled { + opacity: 1; +} + +[list]::-webkit-calendar-picker-indicator { + display: none; +} + +button, +[type=button], +[type=reset], +[type=submit] { + -webkit-appearance: button; +} +button:not(:disabled), +[type=button]:not(:disabled), +[type=reset]:not(:disabled), +[type=submit]:not(:disabled) { + cursor: pointer; +} + +::-moz-focus-inner { + padding: 0; + border-style: none; +} + +textarea { + resize: vertical; +} + +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} + +legend { + float: left; + width: 100%; + padding: 0; + margin-bottom: 0.5rem; + font-size: calc(1.275rem + 0.3vw); + line-height: inherit; +} +@media (min-width: 1200px) { + legend { + font-size: 1.5rem; + } +} +legend + * { + clear: left; +} + +::-webkit-datetime-edit-fields-wrapper, +::-webkit-datetime-edit-text, +::-webkit-datetime-edit-minute, +::-webkit-datetime-edit-hour-field, +::-webkit-datetime-edit-day-field, +::-webkit-datetime-edit-month-field, +::-webkit-datetime-edit-year-field { + padding: 0; +} + +::-webkit-inner-spin-button { + height: auto; +} + +[type=search] { + outline-offset: -2px; + -webkit-appearance: textfield; +} + +/* rtl:raw: +[type="tel"], +[type="url"], +[type="email"], +[type="number"] { + direction: ltr; +} +*/ +::-webkit-search-decoration { + -webkit-appearance: none; +} + +::-webkit-color-swatch-wrapper { + padding: 0; +} + +::file-selector-button { + font: inherit; +} + +::-webkit-file-upload-button { + font: inherit; + -webkit-appearance: button; +} + +output { + display: inline-block; +} + +iframe { + border: 0; +} + +summary { + display: list-item; + cursor: pointer; +} + +progress { + vertical-align: baseline; +} + +[hidden] { + display: none !important; +} + +.lead { + font-size: 1.25rem; + font-weight: 300; +} + +.display-1 { + font-size: calc(1.625rem + 4.5vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-1 { + font-size: 5rem; + } +} + +.display-2 { + font-size: calc(1.575rem + 3.9vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-2 { + font-size: 4.5rem; + } +} + +.display-3 { + font-size: calc(1.525rem + 3.3vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-3 { + font-size: 4rem; + } +} + +.display-4 { + font-size: calc(1.475rem + 2.7vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-4 { + font-size: 3.5rem; + } +} + +.display-5 { + font-size: calc(1.425rem + 2.1vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-5 { + font-size: 3rem; + } +} + +.display-6 { + font-size: calc(1.375rem + 1.5vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-6 { + font-size: 2.5rem; + } +} + +.list-unstyled { + padding-left: 0; + list-style: none; +} + +.list-inline { + padding-left: 0; + list-style: none; +} + +.list-inline-item { + display: inline-block; +} +.list-inline-item:not(:last-child) { + margin-right: 0.5rem; +} + +.initialism { + font-size: 0.875em; + text-transform: uppercase; +} + +.blockquote { + margin-bottom: 1rem; + font-size: 1.25rem; +} +.blockquote > :last-child { + margin-bottom: 0; +} + +.blockquote-footer { + margin-top: -1rem; + margin-bottom: 1rem; + font-size: 0.875em; + color: #6c757d; +} +.blockquote-footer::before { + content: "— "; +} + +.img-fluid { + max-width: 100%; + height: auto; +} + +.img-thumbnail { + padding: 0.25rem; + background-color: #fff; + border: 1px solid #dee2e6; + border-radius: 0.25rem; + max-width: 100%; + height: auto; +} + +.figure { + display: inline-block; +} + +.figure-img { + margin-bottom: 0.5rem; + line-height: 1; +} + +.figure-caption { + font-size: 0.875em; + color: #6c757d; +} + +.container, +.container-fluid, +.container-xxl, +.container-xl, +.container-lg, +.container-md, +.container-sm { + width: 100%; + padding-right: var(--bs-gutter-x, 0.75rem); + padding-left: var(--bs-gutter-x, 0.75rem); + margin-right: auto; + margin-left: auto; +} + +@media (min-width: 576px) { + .container-sm, .container { + max-width: 540px; + } +} +@media (min-width: 768px) { + .container-md, .container-sm, .container { + max-width: 720px; + } +} +@media (min-width: 992px) { + .container-lg, .container-md, .container-sm, .container { + max-width: 960px; + } +} +@media (min-width: 1200px) { + .container-xl, .container-lg, .container-md, .container-sm, .container { + max-width: 1140px; + } +} +@media (min-width: 1400px) { + .container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container { + max-width: 1320px; + } +} +.row { + --bs-gutter-x: 1.5rem; + --bs-gutter-y: 0; + display: flex; + flex-wrap: wrap; + margin-top: calc(var(--bs-gutter-y) * -1); + margin-right: calc(var(--bs-gutter-x) / -2); + margin-left: calc(var(--bs-gutter-x) / -2); +} +.row > * { + flex-shrink: 0; + width: 100%; + max-width: 100%; + padding-right: calc(var(--bs-gutter-x) / 2); + padding-left: calc(var(--bs-gutter-x) / 2); + margin-top: var(--bs-gutter-y); +} + +.col { + flex: 1 0 0%; +} + +.row-cols-auto > * { + flex: 0 0 auto; + width: auto; +} + +.row-cols-1 > * { + flex: 0 0 auto; + width: 100%; +} + +.row-cols-2 > * { + flex: 0 0 auto; + width: 50%; +} + +.row-cols-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; +} + +.row-cols-4 > * { + flex: 0 0 auto; + width: 25%; +} + +.row-cols-5 > * { + flex: 0 0 auto; + width: 20%; +} + +.row-cols-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; +} + +.col-auto { + flex: 0 0 auto; + width: auto; +} + +.col-1 { + flex: 0 0 auto; + width: 8.3333333333%; +} + +.col-2 { + flex: 0 0 auto; + width: 16.6666666667%; +} + +.col-3 { + flex: 0 0 auto; + width: 25%; +} + +.col-4 { + flex: 0 0 auto; + width: 33.3333333333%; +} + +.col-5 { + flex: 0 0 auto; + width: 41.6666666667%; +} + +.col-6 { + flex: 0 0 auto; + width: 50%; +} + +.col-7 { + flex: 0 0 auto; + width: 58.3333333333%; +} + +.col-8 { + flex: 0 0 auto; + width: 66.6666666667%; +} + +.col-9 { + flex: 0 0 auto; + width: 75%; +} + +.col-10 { + flex: 0 0 auto; + width: 83.3333333333%; +} + +.col-11 { + flex: 0 0 auto; + width: 91.6666666667%; +} + +.col-12 { + flex: 0 0 auto; + width: 100%; +} + +.offset-1 { + margin-left: 8.3333333333%; +} + +.offset-2 { + margin-left: 16.6666666667%; +} + +.offset-3 { + margin-left: 25%; +} + +.offset-4 { + margin-left: 33.3333333333%; +} + +.offset-5 { + margin-left: 41.6666666667%; +} + +.offset-6 { + margin-left: 50%; +} + +.offset-7 { + margin-left: 58.3333333333%; +} + +.offset-8 { + margin-left: 66.6666666667%; +} + +.offset-9 { + margin-left: 75%; +} + +.offset-10 { + margin-left: 83.3333333333%; +} + +.offset-11 { + margin-left: 91.6666666667%; +} + +.g-0, +.gx-0 { + --bs-gutter-x: 0; +} + +.g-0, +.gy-0 { + --bs-gutter-y: 0; +} + +.g-1, +.gx-1 { + --bs-gutter-x: 0.25rem; +} + +.g-1, +.gy-1 { + --bs-gutter-y: 0.25rem; +} + +.g-2, +.gx-2 { + --bs-gutter-x: 0.5rem; +} + +.g-2, +.gy-2 { + --bs-gutter-y: 0.5rem; +} + +.g-3, +.gx-3 { + --bs-gutter-x: 1rem; +} + +.g-3, +.gy-3 { + --bs-gutter-y: 1rem; +} + +.g-4, +.gx-4 { + --bs-gutter-x: 1.5rem; +} + +.g-4, +.gy-4 { + --bs-gutter-y: 1.5rem; +} + +.g-5, +.gx-5 { + --bs-gutter-x: 3rem; +} + +.g-5, +.gy-5 { + --bs-gutter-y: 3rem; +} + +@media (min-width: 576px) { + .col-sm { + flex: 1 0 0%; + } + + .row-cols-sm-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-sm-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-sm-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-sm-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-sm-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-sm-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-sm-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-sm-auto { + flex: 0 0 auto; + width: auto; + } + + .col-sm-1 { + flex: 0 0 auto; + width: 8.3333333333%; + } + + .col-sm-2 { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-sm-3 { + flex: 0 0 auto; + width: 25%; + } + + .col-sm-4 { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .col-sm-5 { + flex: 0 0 auto; + width: 41.6666666667%; + } + + .col-sm-6 { + flex: 0 0 auto; + width: 50%; + } + + .col-sm-7 { + flex: 0 0 auto; + width: 58.3333333333%; + } + + .col-sm-8 { + flex: 0 0 auto; + width: 66.6666666667%; + } + + .col-sm-9 { + flex: 0 0 auto; + width: 75%; + } + + .col-sm-10 { + flex: 0 0 auto; + width: 83.3333333333%; + } + + .col-sm-11 { + flex: 0 0 auto; + width: 91.6666666667%; + } + + .col-sm-12 { + flex: 0 0 auto; + width: 100%; + } + + .offset-sm-0 { + margin-left: 0; + } + + .offset-sm-1 { + margin-left: 8.3333333333%; + } + + .offset-sm-2 { + margin-left: 16.6666666667%; + } + + .offset-sm-3 { + margin-left: 25%; + } + + .offset-sm-4 { + margin-left: 33.3333333333%; + } + + .offset-sm-5 { + margin-left: 41.6666666667%; + } + + .offset-sm-6 { + margin-left: 50%; + } + + .offset-sm-7 { + margin-left: 58.3333333333%; + } + + .offset-sm-8 { + margin-left: 66.6666666667%; + } + + .offset-sm-9 { + margin-left: 75%; + } + + .offset-sm-10 { + margin-left: 83.3333333333%; + } + + .offset-sm-11 { + margin-left: 91.6666666667%; + } + + .g-sm-0, +.gx-sm-0 { + --bs-gutter-x: 0; + } + + .g-sm-0, +.gy-sm-0 { + --bs-gutter-y: 0; + } + + .g-sm-1, +.gx-sm-1 { + --bs-gutter-x: 0.25rem; + } + + .g-sm-1, +.gy-sm-1 { + --bs-gutter-y: 0.25rem; + } + + .g-sm-2, +.gx-sm-2 { + --bs-gutter-x: 0.5rem; + } + + .g-sm-2, +.gy-sm-2 { + --bs-gutter-y: 0.5rem; + } + + .g-sm-3, +.gx-sm-3 { + --bs-gutter-x: 1rem; + } + + .g-sm-3, +.gy-sm-3 { + --bs-gutter-y: 1rem; + } + + .g-sm-4, +.gx-sm-4 { + --bs-gutter-x: 1.5rem; + } + + .g-sm-4, +.gy-sm-4 { + --bs-gutter-y: 1.5rem; + } + + .g-sm-5, +.gx-sm-5 { + --bs-gutter-x: 3rem; + } + + .g-sm-5, +.gy-sm-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 768px) { + .col-md { + flex: 1 0 0%; + } + + .row-cols-md-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-md-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-md-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-md-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-md-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-md-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-md-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-md-auto { + flex: 0 0 auto; + width: auto; + } + + .col-md-1 { + flex: 0 0 auto; + width: 8.3333333333%; + } + + .col-md-2 { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-md-3 { + flex: 0 0 auto; + width: 25%; + } + + .col-md-4 { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .col-md-5 { + flex: 0 0 auto; + width: 41.6666666667%; + } + + .col-md-6 { + flex: 0 0 auto; + width: 50%; + } + + .col-md-7 { + flex: 0 0 auto; + width: 58.3333333333%; + } + + .col-md-8 { + flex: 0 0 auto; + width: 66.6666666667%; + } + + .col-md-9 { + flex: 0 0 auto; + width: 75%; + } + + .col-md-10 { + flex: 0 0 auto; + width: 83.3333333333%; + } + + .col-md-11 { + flex: 0 0 auto; + width: 91.6666666667%; + } + + .col-md-12 { + flex: 0 0 auto; + width: 100%; + } + + .offset-md-0 { + margin-left: 0; + } + + .offset-md-1 { + margin-left: 8.3333333333%; + } + + .offset-md-2 { + margin-left: 16.6666666667%; + } + + .offset-md-3 { + margin-left: 25%; + } + + .offset-md-4 { + margin-left: 33.3333333333%; + } + + .offset-md-5 { + margin-left: 41.6666666667%; + } + + .offset-md-6 { + margin-left: 50%; + } + + .offset-md-7 { + margin-left: 58.3333333333%; + } + + .offset-md-8 { + margin-left: 66.6666666667%; + } + + .offset-md-9 { + margin-left: 75%; + } + + .offset-md-10 { + margin-left: 83.3333333333%; + } + + .offset-md-11 { + margin-left: 91.6666666667%; + } + + .g-md-0, +.gx-md-0 { + --bs-gutter-x: 0; + } + + .g-md-0, +.gy-md-0 { + --bs-gutter-y: 0; + } + + .g-md-1, +.gx-md-1 { + --bs-gutter-x: 0.25rem; + } + + .g-md-1, +.gy-md-1 { + --bs-gutter-y: 0.25rem; + } + + .g-md-2, +.gx-md-2 { + --bs-gutter-x: 0.5rem; + } + + .g-md-2, +.gy-md-2 { + --bs-gutter-y: 0.5rem; + } + + .g-md-3, +.gx-md-3 { + --bs-gutter-x: 1rem; + } + + .g-md-3, +.gy-md-3 { + --bs-gutter-y: 1rem; + } + + .g-md-4, +.gx-md-4 { + --bs-gutter-x: 1.5rem; + } + + .g-md-4, +.gy-md-4 { + --bs-gutter-y: 1.5rem; + } + + .g-md-5, +.gx-md-5 { + --bs-gutter-x: 3rem; + } + + .g-md-5, +.gy-md-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 992px) { + .col-lg { + flex: 1 0 0%; + } + + .row-cols-lg-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-lg-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-lg-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-lg-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-lg-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-lg-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-lg-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-lg-auto { + flex: 0 0 auto; + width: auto; + } + + .col-lg-1 { + flex: 0 0 auto; + width: 8.3333333333%; + } + + .col-lg-2 { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-lg-3 { + flex: 0 0 auto; + width: 25%; + } + + .col-lg-4 { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .col-lg-5 { + flex: 0 0 auto; + width: 41.6666666667%; + } + + .col-lg-6 { + flex: 0 0 auto; + width: 50%; + } + + .col-lg-7 { + flex: 0 0 auto; + width: 58.3333333333%; + } + + .col-lg-8 { + flex: 0 0 auto; + width: 66.6666666667%; + } + + .col-lg-9 { + flex: 0 0 auto; + width: 75%; + } + + .col-lg-10 { + flex: 0 0 auto; + width: 83.3333333333%; + } + + .col-lg-11 { + flex: 0 0 auto; + width: 91.6666666667%; + } + + .col-lg-12 { + flex: 0 0 auto; + width: 100%; + } + + .offset-lg-0 { + margin-left: 0; + } + + .offset-lg-1 { + margin-left: 8.3333333333%; + } + + .offset-lg-2 { + margin-left: 16.6666666667%; + } + + .offset-lg-3 { + margin-left: 25%; + } + + .offset-lg-4 { + margin-left: 33.3333333333%; + } + + .offset-lg-5 { + margin-left: 41.6666666667%; + } + + .offset-lg-6 { + margin-left: 50%; + } + + .offset-lg-7 { + margin-left: 58.3333333333%; + } + + .offset-lg-8 { + margin-left: 66.6666666667%; + } + + .offset-lg-9 { + margin-left: 75%; + } + + .offset-lg-10 { + margin-left: 83.3333333333%; + } + + .offset-lg-11 { + margin-left: 91.6666666667%; + } + + .g-lg-0, +.gx-lg-0 { + --bs-gutter-x: 0; + } + + .g-lg-0, +.gy-lg-0 { + --bs-gutter-y: 0; + } + + .g-lg-1, +.gx-lg-1 { + --bs-gutter-x: 0.25rem; + } + + .g-lg-1, +.gy-lg-1 { + --bs-gutter-y: 0.25rem; + } + + .g-lg-2, +.gx-lg-2 { + --bs-gutter-x: 0.5rem; + } + + .g-lg-2, +.gy-lg-2 { + --bs-gutter-y: 0.5rem; + } + + .g-lg-3, +.gx-lg-3 { + --bs-gutter-x: 1rem; + } + + .g-lg-3, +.gy-lg-3 { + --bs-gutter-y: 1rem; + } + + .g-lg-4, +.gx-lg-4 { + --bs-gutter-x: 1.5rem; + } + + .g-lg-4, +.gy-lg-4 { + --bs-gutter-y: 1.5rem; + } + + .g-lg-5, +.gx-lg-5 { + --bs-gutter-x: 3rem; + } + + .g-lg-5, +.gy-lg-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 1200px) { + .col-xl { + flex: 1 0 0%; + } + + .row-cols-xl-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-xl-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-xl-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-xl-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-xl-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-xl-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-xl-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-xl-auto { + flex: 0 0 auto; + width: auto; + } + + .col-xl-1 { + flex: 0 0 auto; + width: 8.3333333333%; + } + + .col-xl-2 { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-xl-3 { + flex: 0 0 auto; + width: 25%; + } + + .col-xl-4 { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .col-xl-5 { + flex: 0 0 auto; + width: 41.6666666667%; + } + + .col-xl-6 { + flex: 0 0 auto; + width: 50%; + } + + .col-xl-7 { + flex: 0 0 auto; + width: 58.3333333333%; + } + + .col-xl-8 { + flex: 0 0 auto; + width: 66.6666666667%; + } + + .col-xl-9 { + flex: 0 0 auto; + width: 75%; + } + + .col-xl-10 { + flex: 0 0 auto; + width: 83.3333333333%; + } + + .col-xl-11 { + flex: 0 0 auto; + width: 91.6666666667%; + } + + .col-xl-12 { + flex: 0 0 auto; + width: 100%; + } + + .offset-xl-0 { + margin-left: 0; + } + + .offset-xl-1 { + margin-left: 8.3333333333%; + } + + .offset-xl-2 { + margin-left: 16.6666666667%; + } + + .offset-xl-3 { + margin-left: 25%; + } + + .offset-xl-4 { + margin-left: 33.3333333333%; + } + + .offset-xl-5 { + margin-left: 41.6666666667%; + } + + .offset-xl-6 { + margin-left: 50%; + } + + .offset-xl-7 { + margin-left: 58.3333333333%; + } + + .offset-xl-8 { + margin-left: 66.6666666667%; + } + + .offset-xl-9 { + margin-left: 75%; + } + + .offset-xl-10 { + margin-left: 83.3333333333%; + } + + .offset-xl-11 { + margin-left: 91.6666666667%; + } + + .g-xl-0, +.gx-xl-0 { + --bs-gutter-x: 0; + } + + .g-xl-0, +.gy-xl-0 { + --bs-gutter-y: 0; + } + + .g-xl-1, +.gx-xl-1 { + --bs-gutter-x: 0.25rem; + } + + .g-xl-1, +.gy-xl-1 { + --bs-gutter-y: 0.25rem; + } + + .g-xl-2, +.gx-xl-2 { + --bs-gutter-x: 0.5rem; + } + + .g-xl-2, +.gy-xl-2 { + --bs-gutter-y: 0.5rem; + } + + .g-xl-3, +.gx-xl-3 { + --bs-gutter-x: 1rem; + } + + .g-xl-3, +.gy-xl-3 { + --bs-gutter-y: 1rem; + } + + .g-xl-4, +.gx-xl-4 { + --bs-gutter-x: 1.5rem; + } + + .g-xl-4, +.gy-xl-4 { + --bs-gutter-y: 1.5rem; + } + + .g-xl-5, +.gx-xl-5 { + --bs-gutter-x: 3rem; + } + + .g-xl-5, +.gy-xl-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 1400px) { + .col-xxl { + flex: 1 0 0%; + } + + .row-cols-xxl-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-xxl-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-xxl-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-xxl-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-xxl-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-xxl-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-xxl-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-xxl-auto { + flex: 0 0 auto; + width: auto; + } + + .col-xxl-1 { + flex: 0 0 auto; + width: 8.3333333333%; + } + + .col-xxl-2 { + flex: 0 0 auto; + width: 16.6666666667%; + } + + .col-xxl-3 { + flex: 0 0 auto; + width: 25%; + } + + .col-xxl-4 { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .col-xxl-5 { + flex: 0 0 auto; + width: 41.6666666667%; + } + + .col-xxl-6 { + flex: 0 0 auto; + width: 50%; + } + + .col-xxl-7 { + flex: 0 0 auto; + width: 58.3333333333%; + } + + .col-xxl-8 { + flex: 0 0 auto; + width: 66.6666666667%; + } + + .col-xxl-9 { + flex: 0 0 auto; + width: 75%; + } + + .col-xxl-10 { + flex: 0 0 auto; + width: 83.3333333333%; + } + + .col-xxl-11 { + flex: 0 0 auto; + width: 91.6666666667%; + } + + .col-xxl-12 { + flex: 0 0 auto; + width: 100%; + } + + .offset-xxl-0 { + margin-left: 0; + } + + .offset-xxl-1 { + margin-left: 8.3333333333%; + } + + .offset-xxl-2 { + margin-left: 16.6666666667%; + } + + .offset-xxl-3 { + margin-left: 25%; + } + + .offset-xxl-4 { + margin-left: 33.3333333333%; + } + + .offset-xxl-5 { + margin-left: 41.6666666667%; + } + + .offset-xxl-6 { + margin-left: 50%; + } + + .offset-xxl-7 { + margin-left: 58.3333333333%; + } + + .offset-xxl-8 { + margin-left: 66.6666666667%; + } + + .offset-xxl-9 { + margin-left: 75%; + } + + .offset-xxl-10 { + margin-left: 83.3333333333%; + } + + .offset-xxl-11 { + margin-left: 91.6666666667%; + } + + .g-xxl-0, +.gx-xxl-0 { + --bs-gutter-x: 0; + } + + .g-xxl-0, +.gy-xxl-0 { + --bs-gutter-y: 0; + } + + .g-xxl-1, +.gx-xxl-1 { + --bs-gutter-x: 0.25rem; + } + + .g-xxl-1, +.gy-xxl-1 { + --bs-gutter-y: 0.25rem; + } + + .g-xxl-2, +.gx-xxl-2 { + --bs-gutter-x: 0.5rem; + } + + .g-xxl-2, +.gy-xxl-2 { + --bs-gutter-y: 0.5rem; + } + + .g-xxl-3, +.gx-xxl-3 { + --bs-gutter-x: 1rem; + } + + .g-xxl-3, +.gy-xxl-3 { + --bs-gutter-y: 1rem; + } + + .g-xxl-4, +.gx-xxl-4 { + --bs-gutter-x: 1.5rem; + } + + .g-xxl-4, +.gy-xxl-4 { + --bs-gutter-y: 1.5rem; + } + + .g-xxl-5, +.gx-xxl-5 { + --bs-gutter-x: 3rem; + } + + .g-xxl-5, +.gy-xxl-5 { + --bs-gutter-y: 3rem; + } +} +.table { + --bs-table-bg: transparent; + --bs-table-accent-bg: transparent; + --bs-table-striped-color: #212529; + --bs-table-striped-bg: rgba(0, 0, 0, 0.05); + --bs-table-active-color: #212529; + --bs-table-active-bg: rgba(0, 0, 0, 0.1); + --bs-table-hover-color: #212529; + --bs-table-hover-bg: rgba(0, 0, 0, 0.075); + width: 100%; + margin-bottom: 1rem; + color: #212529; + vertical-align: top; + border-color: #dee2e6; +} +.table > :not(caption) > * > * { + padding: 0.5rem 0.5rem; + background-color: var(--bs-table-bg); + border-bottom-width: 1px; + box-shadow: inset 0 0 0 9999px var(--bs-table-accent-bg); +} +.table > tbody { + vertical-align: inherit; +} +.table > thead { + vertical-align: bottom; +} +.table > :not(:last-child) > :last-child > * { + border-bottom-color: currentColor; +} + +.caption-top { + caption-side: top; +} + +.table-sm > :not(caption) > * > * { + padding: 0.25rem 0.25rem; +} + +.table-bordered > :not(caption) > * { + border-width: 1px 0; +} +.table-bordered > :not(caption) > * > * { + border-width: 0 1px; +} + +.table-borderless > :not(caption) > * > * { + border-bottom-width: 0; +} + +.table-striped > tbody > tr:nth-of-type(odd) { + --bs-table-accent-bg: var(--bs-table-striped-bg); + color: var(--bs-table-striped-color); +} + +.table-active { + --bs-table-accent-bg: var(--bs-table-active-bg); + color: var(--bs-table-active-color); +} + +.table-hover > tbody > tr:hover { + --bs-table-accent-bg: var(--bs-table-hover-bg); + color: var(--bs-table-hover-color); +} + +.table-primary { + --bs-table-bg: #cfe2ff; + --bs-table-striped-bg: #c5d7f2; + --bs-table-striped-color: #000; + --bs-table-active-bg: #bacbe6; + --bs-table-active-color: #000; + --bs-table-hover-bg: #bfd1ec; + --bs-table-hover-color: #000; + color: #000; + border-color: #bacbe6; +} + +.table-secondary { + --bs-table-bg: #e2e3e5; + --bs-table-striped-bg: #d7d8da; + --bs-table-striped-color: #000; + --bs-table-active-bg: #cbccce; + --bs-table-active-color: #000; + --bs-table-hover-bg: #d1d2d4; + --bs-table-hover-color: #000; + color: #000; + border-color: #cbccce; +} + +.table-success { + --bs-table-bg: #d1e7dd; + --bs-table-striped-bg: #c7dbd2; + --bs-table-striped-color: #000; + --bs-table-active-bg: #bcd0c7; + --bs-table-active-color: #000; + --bs-table-hover-bg: #c1d6cc; + --bs-table-hover-color: #000; + color: #000; + border-color: #bcd0c7; +} + +.table-info { + --bs-table-bg: #cff4fc; + --bs-table-striped-bg: #c5e8ef; + --bs-table-striped-color: #000; + --bs-table-active-bg: #badce3; + --bs-table-active-color: #000; + --bs-table-hover-bg: #bfe2e9; + --bs-table-hover-color: #000; + color: #000; + border-color: #badce3; +} + +.table-warning { + --bs-table-bg: #fff3cd; + --bs-table-striped-bg: #f2e7c3; + --bs-table-striped-color: #000; + --bs-table-active-bg: #e6dbb9; + --bs-table-active-color: #000; + --bs-table-hover-bg: #ece1be; + --bs-table-hover-color: #000; + color: #000; + border-color: #e6dbb9; +} + +.table-danger { + --bs-table-bg: #f8d7da; + --bs-table-striped-bg: #eccccf; + --bs-table-striped-color: #000; + --bs-table-active-bg: #dfc2c4; + --bs-table-active-color: #000; + --bs-table-hover-bg: #e5c7ca; + --bs-table-hover-color: #000; + color: #000; + border-color: #dfc2c4; +} + +.table-light { + --bs-table-bg: #f8f9fa; + --bs-table-striped-bg: #ecedee; + --bs-table-striped-color: #000; + --bs-table-active-bg: #dfe0e1; + --bs-table-active-color: #000; + --bs-table-hover-bg: #e5e6e7; + --bs-table-hover-color: #000; + color: #000; + border-color: #dfe0e1; +} + +.table-dark { + --bs-table-bg: #212529; + --bs-table-striped-bg: #2c3034; + --bs-table-striped-color: #fff; + --bs-table-active-bg: #373b3e; + --bs-table-active-color: #fff; + --bs-table-hover-bg: #323539; + --bs-table-hover-color: #fff; + color: #fff; + border-color: #373b3e; +} + +.table-responsive { + overflow-x: auto; + -webkit-overflow-scrolling: touch; +} + +@media (max-width: 575.98px) { + .table-responsive-sm { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 767.98px) { + .table-responsive-md { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 991.98px) { + .table-responsive-lg { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 1199.98px) { + .table-responsive-xl { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 1399.98px) { + .table-responsive-xxl { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +.form-label { + margin-bottom: 0.5rem; +} + +.col-form-label { + padding-top: calc(0.375rem + 1px); + padding-bottom: calc(0.375rem + 1px); + margin-bottom: 0; + font-size: inherit; + line-height: 1.5; +} + +.col-form-label-lg { + padding-top: calc(0.5rem + 1px); + padding-bottom: calc(0.5rem + 1px); + font-size: 1.25rem; +} + +.col-form-label-sm { + padding-top: calc(0.25rem + 1px); + padding-bottom: calc(0.25rem + 1px); + font-size: 0.875rem; +} + +.form-text { + margin-top: 0.25rem; + font-size: 0.875em; + color: #6c757d; +} + +.form-control { + display: block; + width: 100%; + padding: 0.375rem 0.75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ced4da; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + border-radius: 0.25rem; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-control { + transition: none; + } +} +.form-control[type=file] { + overflow: hidden; +} +.form-control[type=file]:not(:disabled):not([readonly]) { + cursor: pointer; +} +.form-control:focus { + color: #212529; + background-color: #fff; + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} +.form-control::-webkit-date-and-time-value { + height: 1.5em; +} +.form-control::-moz-placeholder { + color: #6c757d; + opacity: 1; +} +.form-control::placeholder { + color: #6c757d; + opacity: 1; +} +.form-control:disabled, .form-control[readonly] { + background-color: #e9ecef; + opacity: 1; +} +.form-control::file-selector-button { + padding: 0.375rem 0.75rem; + margin: -0.375rem -0.75rem; + -webkit-margin-end: 0.75rem; + margin-inline-end: 0.75rem; + color: #212529; + background-color: #e9ecef; + pointer-events: none; + border-color: inherit; + border-style: solid; + border-width: 0; + border-inline-end-width: 1px; + border-radius: 0; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-control::file-selector-button { + transition: none; + } +} +.form-control:hover:not(:disabled):not([readonly])::file-selector-button { + background-color: #dde0e3; +} +.form-control::-webkit-file-upload-button { + padding: 0.375rem 0.75rem; + margin: -0.375rem -0.75rem; + -webkit-margin-end: 0.75rem; + margin-inline-end: 0.75rem; + color: #212529; + background-color: #e9ecef; + pointer-events: none; + border-color: inherit; + border-style: solid; + border-width: 0; + border-inline-end-width: 1px; + border-radius: 0; + -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-control::-webkit-file-upload-button { + -webkit-transition: none; + transition: none; + } +} +.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button { + background-color: #dde0e3; +} + +.form-control-plaintext { + display: block; + width: 100%; + padding: 0.375rem 0; + margin-bottom: 0; + line-height: 1.5; + color: #212529; + background-color: transparent; + border: solid transparent; + border-width: 1px 0; +} +.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg { + padding-right: 0; + padding-left: 0; +} + +.form-control-sm { + min-height: calc(1.5em + 0.5rem + 2px); + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + border-radius: 0.2rem; +} +.form-control-sm::file-selector-button { + padding: 0.25rem 0.5rem; + margin: -0.25rem -0.5rem; + -webkit-margin-end: 0.5rem; + margin-inline-end: 0.5rem; +} +.form-control-sm::-webkit-file-upload-button { + padding: 0.25rem 0.5rem; + margin: -0.25rem -0.5rem; + -webkit-margin-end: 0.5rem; + margin-inline-end: 0.5rem; +} + +.form-control-lg { + min-height: calc(1.5em + 1rem + 2px); + padding: 0.5rem 1rem; + font-size: 1.25rem; + border-radius: 0.3rem; +} +.form-control-lg::file-selector-button { + padding: 0.5rem 1rem; + margin: -0.5rem -1rem; + -webkit-margin-end: 1rem; + margin-inline-end: 1rem; +} +.form-control-lg::-webkit-file-upload-button { + padding: 0.5rem 1rem; + margin: -0.5rem -1rem; + -webkit-margin-end: 1rem; + margin-inline-end: 1rem; +} + +textarea.form-control { + min-height: calc(1.5em + 0.75rem + 2px); +} +textarea.form-control-sm { + min-height: calc(1.5em + 0.5rem + 2px); +} +textarea.form-control-lg { + min-height: calc(1.5em + 1rem + 2px); +} + +.form-control-color { + max-width: 3rem; + height: auto; + padding: 0.375rem; +} +.form-control-color:not(:disabled):not([readonly]) { + cursor: pointer; +} +.form-control-color::-moz-color-swatch { + height: 1.5em; + border-radius: 0.25rem; +} +.form-control-color::-webkit-color-swatch { + height: 1.5em; + border-radius: 0.25rem; +} + +.form-select { + display: block; + width: 100%; + padding: 0.375rem 2.25rem 0.375rem 0.75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + background-color: #fff; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right 0.75rem center; + background-size: 16px 12px; + border: 1px solid #ced4da; + border-radius: 0.25rem; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} +.form-select:focus { + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} +.form-select[multiple], .form-select[size]:not([size="1"]) { + padding-right: 0.75rem; + background-image: none; +} +.form-select:disabled { + background-color: #e9ecef; +} +.form-select:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 #212529; +} + +.form-select-sm { + padding-top: 0.25rem; + padding-bottom: 0.25rem; + padding-left: 0.5rem; + font-size: 0.875rem; +} + +.form-select-lg { + padding-top: 0.5rem; + padding-bottom: 0.5rem; + padding-left: 1rem; + font-size: 1.25rem; +} + +.form-check { + display: block; + min-height: 1.5rem; + padding-left: 1.5em; + margin-bottom: 0.125rem; +} +.form-check .form-check-input { + float: left; + margin-left: -1.5em; +} + +.form-check-input { + width: 1em; + height: 1em; + margin-top: 0.25em; + vertical-align: top; + background-color: #fff; + background-repeat: no-repeat; + background-position: center; + background-size: contain; + border: 1px solid rgba(0, 0, 0, 0.25); + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + -webkit-print-color-adjust: exact; + color-adjust: exact; +} +.form-check-input[type=checkbox] { + border-radius: 0.25em; +} +.form-check-input[type=radio] { + border-radius: 50%; +} +.form-check-input:active { + filter: brightness(90%); +} +.form-check-input:focus { + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} +.form-check-input:checked { + background-color: #0d6efd; + border-color: #0d6efd; +} +.form-check-input:checked[type=checkbox] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e"); +} +.form-check-input:checked[type=radio] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e"); +} +.form-check-input[type=checkbox]:indeterminate { + background-color: #0d6efd; + border-color: #0d6efd; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e"); +} +.form-check-input:disabled { + pointer-events: none; + filter: none; + opacity: 0.5; +} +.form-check-input[disabled] ~ .form-check-label, .form-check-input:disabled ~ .form-check-label { + opacity: 0.5; +} + +.form-switch { + padding-left: 2.5em; +} +.form-switch .form-check-input { + width: 2em; + margin-left: -2.5em; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e"); + background-position: left center; + border-radius: 2em; + transition: background-position 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-switch .form-check-input { + transition: none; + } +} +.form-switch .form-check-input:focus { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e"); +} +.form-switch .form-check-input:checked { + background-position: right center; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e"); +} + +.form-check-inline { + display: inline-block; + margin-right: 1rem; +} + +.btn-check { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} +.btn-check[disabled] + .btn, .btn-check:disabled + .btn { + pointer-events: none; + filter: none; + opacity: 0.65; +} + +.form-range { + width: 100%; + height: 1.5rem; + padding: 0; + background-color: transparent; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} +.form-range:focus { + outline: 0; +} +.form-range:focus::-webkit-slider-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} +.form-range:focus::-moz-range-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} +.form-range::-moz-focus-outer { + border: 0; +} +.form-range::-webkit-slider-thumb { + width: 1rem; + height: 1rem; + margin-top: -0.25rem; + background-color: #0d6efd; + border: 0; + border-radius: 1rem; + -webkit-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + -webkit-appearance: none; + appearance: none; +} +@media (prefers-reduced-motion: reduce) { + .form-range::-webkit-slider-thumb { + -webkit-transition: none; + transition: none; + } +} +.form-range::-webkit-slider-thumb:active { + background-color: #b6d4fe; +} +.form-range::-webkit-slider-runnable-track { + width: 100%; + height: 0.5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem; +} +.form-range::-moz-range-thumb { + width: 1rem; + height: 1rem; + background-color: #0d6efd; + border: 0; + border-radius: 1rem; + -moz-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + -moz-appearance: none; + appearance: none; +} +@media (prefers-reduced-motion: reduce) { + .form-range::-moz-range-thumb { + -moz-transition: none; + transition: none; + } +} +.form-range::-moz-range-thumb:active { + background-color: #b6d4fe; +} +.form-range::-moz-range-track { + width: 100%; + height: 0.5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem; +} +.form-range:disabled { + pointer-events: none; +} +.form-range:disabled::-webkit-slider-thumb { + background-color: #adb5bd; +} +.form-range:disabled::-moz-range-thumb { + background-color: #adb5bd; +} + +.form-floating { + position: relative; +} +.form-floating > .form-control, +.form-floating > .form-select { + height: calc(3.5rem + 2px); + padding: 1rem 0.75rem; +} +.form-floating > label { + position: absolute; + top: 0; + left: 0; + height: 100%; + padding: 1rem 0.75rem; + pointer-events: none; + border: 1px solid transparent; + transform-origin: 0 0; + transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-floating > label { + transition: none; + } +} +.form-floating > .form-control::-moz-placeholder { + color: transparent; +} +.form-floating > .form-control::placeholder { + color: transparent; +} +.form-floating > .form-control:not(:-moz-placeholder-shown) { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-control:focus, .form-floating > .form-control:not(:placeholder-shown) { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-control:-webkit-autofill { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-select { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-control:not(:-moz-placeholder-shown) ~ label { + opacity: 0.65; + transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); +} +.form-floating > .form-control:focus ~ label, +.form-floating > .form-control:not(:placeholder-shown) ~ label, +.form-floating > .form-select ~ label { + opacity: 0.65; + transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); +} +.form-floating > .form-control:-webkit-autofill ~ label { + opacity: 0.65; + transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); +} + +.input-group { + position: relative; + display: flex; + flex-wrap: wrap; + align-items: stretch; + width: 100%; +} +.input-group > .form-control, +.input-group > .form-select { + position: relative; + flex: 1 1 auto; + width: 1%; + min-width: 0; +} +.input-group > .form-control:focus, +.input-group > .form-select:focus { + z-index: 3; +} +.input-group .btn { + position: relative; + z-index: 2; +} +.input-group .btn:focus { + z-index: 3; +} + +.input-group-text { + display: flex; + align-items: center; + padding: 0.375rem 0.75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + text-align: center; + white-space: nowrap; + background-color: #e9ecef; + border: 1px solid #ced4da; + border-radius: 0.25rem; +} + +.input-group-lg > .form-control, +.input-group-lg > .form-select, +.input-group-lg > .input-group-text, +.input-group-lg > .btn { + padding: 0.5rem 1rem; + font-size: 1.25rem; + border-radius: 0.3rem; +} + +.input-group-sm > .form-control, +.input-group-sm > .form-select, +.input-group-sm > .input-group-text, +.input-group-sm > .btn { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + border-radius: 0.2rem; +} + +.input-group-lg > .form-select, +.input-group-sm > .form-select { + padding-right: 3rem; +} + +.input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu), +.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n+3) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group.has-validation > :nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu), +.input-group.has-validation > .dropdown-toggle:nth-last-child(n+4) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group > :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) { + margin-left: -1px; + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.valid-feedback { + display: none; + width: 100%; + margin-top: 0.25rem; + font-size: 0.875em; + color: #198754; +} + +.valid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: 0.25rem 0.5rem; + margin-top: 0.1rem; + font-size: 0.875rem; + color: #fff; + background-color: rgba(25, 135, 84, 0.9); + border-radius: 0.25rem; +} + +.was-validated :valid ~ .valid-feedback, +.was-validated :valid ~ .valid-tooltip, +.is-valid ~ .valid-feedback, +.is-valid ~ .valid-tooltip { + display: block; +} + +.was-validated .form-control:valid, .form-control.is-valid { + border-color: #198754; + padding-right: calc(1.5em + 0.75rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(0.375em + 0.1875rem) center; + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.was-validated .form-control:valid:focus, .form-control.is-valid:focus { + border-color: #198754; + box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25); +} + +.was-validated textarea.form-control:valid, textarea.form-control.is-valid { + padding-right: calc(1.5em + 0.75rem); + background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); +} + +.was-validated .form-select:valid, .form-select.is-valid { + border-color: #198754; +} +.was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size="1"], .form-select.is-valid:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size="1"] { + padding-right: 4.125rem; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-position: right 0.75rem center, center right 2.25rem; + background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.was-validated .form-select:valid:focus, .form-select.is-valid:focus { + border-color: #198754; + box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25); +} + +.was-validated .form-check-input:valid, .form-check-input.is-valid { + border-color: #198754; +} +.was-validated .form-check-input:valid:checked, .form-check-input.is-valid:checked { + background-color: #198754; +} +.was-validated .form-check-input:valid:focus, .form-check-input.is-valid:focus { + box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25); +} +.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label { + color: #198754; +} + +.form-check-inline .form-check-input ~ .valid-feedback { + margin-left: 0.5em; +} + +.was-validated .input-group .form-control:valid, .input-group .form-control.is-valid, +.was-validated .input-group .form-select:valid, +.input-group .form-select.is-valid { + z-index: 1; +} +.was-validated .input-group .form-control:valid:focus, .input-group .form-control.is-valid:focus, +.was-validated .input-group .form-select:valid:focus, +.input-group .form-select.is-valid:focus { + z-index: 3; +} + +.invalid-feedback { + display: none; + width: 100%; + margin-top: 0.25rem; + font-size: 0.875em; + color: #dc3545; +} + +.invalid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: 0.25rem 0.5rem; + margin-top: 0.1rem; + font-size: 0.875rem; + color: #fff; + background-color: rgba(220, 53, 69, 0.9); + border-radius: 0.25rem; +} + +.was-validated :invalid ~ .invalid-feedback, +.was-validated :invalid ~ .invalid-tooltip, +.is-invalid ~ .invalid-feedback, +.is-invalid ~ .invalid-tooltip { + display: block; +} + +.was-validated .form-control:invalid, .form-control.is-invalid { + border-color: #dc3545; + padding-right: calc(1.5em + 0.75rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(0.375em + 0.1875rem) center; + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus { + border-color: #dc3545; + box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25); +} + +.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid { + padding-right: calc(1.5em + 0.75rem); + background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); +} + +.was-validated .form-select:invalid, .form-select.is-invalid { + border-color: #dc3545; +} +.was-validated .form-select:invalid:not([multiple]):not([size]), .was-validated .form-select:invalid:not([multiple])[size="1"], .form-select.is-invalid:not([multiple]):not([size]), .form-select.is-invalid:not([multiple])[size="1"] { + padding-right: 4.125rem; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); + background-position: right 0.75rem center, center right 2.25rem; + background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.was-validated .form-select:invalid:focus, .form-select.is-invalid:focus { + border-color: #dc3545; + box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25); +} + +.was-validated .form-check-input:invalid, .form-check-input.is-invalid { + border-color: #dc3545; +} +.was-validated .form-check-input:invalid:checked, .form-check-input.is-invalid:checked { + background-color: #dc3545; +} +.was-validated .form-check-input:invalid:focus, .form-check-input.is-invalid:focus { + box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25); +} +.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label { + color: #dc3545; +} + +.form-check-inline .form-check-input ~ .invalid-feedback { + margin-left: 0.5em; +} + +.was-validated .input-group .form-control:invalid, .input-group .form-control.is-invalid, +.was-validated .input-group .form-select:invalid, +.input-group .form-select.is-invalid { + z-index: 2; +} +.was-validated .input-group .form-control:invalid:focus, .input-group .form-control.is-invalid:focus, +.was-validated .input-group .form-select:invalid:focus, +.input-group .form-select.is-invalid:focus { + z-index: 3; +} + +.btn { + display: inline-block; + font-weight: 400; + line-height: 1.5; + color: #212529; + text-align: center; + text-decoration: none; + vertical-align: middle; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + background-color: transparent; + border: 1px solid transparent; + padding: 0.375rem 0.75rem; + font-size: 1rem; + border-radius: 0.25rem; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .btn { + transition: none; + } +} +.btn:hover { + color: #212529; +} +.btn-check:focus + .btn, .btn:focus { + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} +.btn:disabled, .btn.disabled, fieldset:disabled .btn { + pointer-events: none; + opacity: 0.65; +} + +.btn-primary { + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd; +} +.btn-primary:hover { + color: #fff; + background-color: #0b5ed7; + border-color: #0a58ca; +} +.btn-check:focus + .btn-primary, .btn-primary:focus { + color: #fff; + background-color: #0b5ed7; + border-color: #0a58ca; + box-shadow: 0 0 0 0.25rem rgba(49, 132, 253, 0.5); +} +.btn-check:checked + .btn-primary, .btn-check:active + .btn-primary, .btn-primary:active, .btn-primary.active, .show > .btn-primary.dropdown-toggle { + color: #fff; + background-color: #0a58ca; + border-color: #0a53be; +} +.btn-check:checked + .btn-primary:focus, .btn-check:active + .btn-primary:focus, .btn-primary:active:focus, .btn-primary.active:focus, .show > .btn-primary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(49, 132, 253, 0.5); +} +.btn-primary:disabled, .btn-primary.disabled { + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd; +} + +.btn-secondary { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} +.btn-secondary:hover { + color: #fff; + background-color: #5c636a; + border-color: #565e64; +} +.btn-check:focus + .btn-secondary, .btn-secondary:focus { + color: #fff; + background-color: #5c636a; + border-color: #565e64; + box-shadow: 0 0 0 0.25rem rgba(130, 138, 145, 0.5); +} +.btn-check:checked + .btn-secondary, .btn-check:active + .btn-secondary, .btn-secondary:active, .btn-secondary.active, .show > .btn-secondary.dropdown-toggle { + color: #fff; + background-color: #565e64; + border-color: #51585e; +} +.btn-check:checked + .btn-secondary:focus, .btn-check:active + .btn-secondary:focus, .btn-secondary:active:focus, .btn-secondary.active:focus, .show > .btn-secondary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(130, 138, 145, 0.5); +} +.btn-secondary:disabled, .btn-secondary.disabled { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} + +.btn-success { + color: #fff; + background-color: #198754; + border-color: #198754; +} +.btn-success:hover { + color: #fff; + background-color: #157347; + border-color: #146c43; +} +.btn-check:focus + .btn-success, .btn-success:focus { + color: #fff; + background-color: #157347; + border-color: #146c43; + box-shadow: 0 0 0 0.25rem rgba(60, 153, 110, 0.5); +} +.btn-check:checked + .btn-success, .btn-check:active + .btn-success, .btn-success:active, .btn-success.active, .show > .btn-success.dropdown-toggle { + color: #fff; + background-color: #146c43; + border-color: #13653f; +} +.btn-check:checked + .btn-success:focus, .btn-check:active + .btn-success:focus, .btn-success:active:focus, .btn-success.active:focus, .show > .btn-success.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(60, 153, 110, 0.5); +} +.btn-success:disabled, .btn-success.disabled { + color: #fff; + background-color: #198754; + border-color: #198754; +} + +.btn-info { + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0; +} +.btn-info:hover { + color: #000; + background-color: #31d2f2; + border-color: #25cff2; +} +.btn-check:focus + .btn-info, .btn-info:focus { + color: #000; + background-color: #31d2f2; + border-color: #25cff2; + box-shadow: 0 0 0 0.25rem rgba(11, 172, 204, 0.5); +} +.btn-check:checked + .btn-info, .btn-check:active + .btn-info, .btn-info:active, .btn-info.active, .show > .btn-info.dropdown-toggle { + color: #000; + background-color: #3dd5f3; + border-color: #25cff2; +} +.btn-check:checked + .btn-info:focus, .btn-check:active + .btn-info:focus, .btn-info:active:focus, .btn-info.active:focus, .show > .btn-info.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(11, 172, 204, 0.5); +} +.btn-info:disabled, .btn-info.disabled { + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0; +} + +.btn-warning { + color: #000; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-warning:hover { + color: #000; + background-color: #ffca2c; + border-color: #ffc720; +} +.btn-check:focus + .btn-warning, .btn-warning:focus { + color: #000; + background-color: #ffca2c; + border-color: #ffc720; + box-shadow: 0 0 0 0.25rem rgba(217, 164, 6, 0.5); +} +.btn-check:checked + .btn-warning, .btn-check:active + .btn-warning, .btn-warning:active, .btn-warning.active, .show > .btn-warning.dropdown-toggle { + color: #000; + background-color: #ffcd39; + border-color: #ffc720; +} +.btn-check:checked + .btn-warning:focus, .btn-check:active + .btn-warning:focus, .btn-warning:active:focus, .btn-warning.active:focus, .show > .btn-warning.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(217, 164, 6, 0.5); +} +.btn-warning:disabled, .btn-warning.disabled { + color: #000; + background-color: #ffc107; + border-color: #ffc107; +} + +.btn-danger { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} +.btn-danger:hover { + color: #fff; + background-color: #bb2d3b; + border-color: #b02a37; +} +.btn-check:focus + .btn-danger, .btn-danger:focus { + color: #fff; + background-color: #bb2d3b; + border-color: #b02a37; + box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5); +} +.btn-check:checked + .btn-danger, .btn-check:active + .btn-danger, .btn-danger:active, .btn-danger.active, .show > .btn-danger.dropdown-toggle { + color: #fff; + background-color: #b02a37; + border-color: #a52834; +} +.btn-check:checked + .btn-danger:focus, .btn-check:active + .btn-danger:focus, .btn-danger:active:focus, .btn-danger.active:focus, .show > .btn-danger.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5); +} +.btn-danger:disabled, .btn-danger.disabled { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} + +.btn-light { + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-light:hover { + color: #000; + background-color: #f9fafb; + border-color: #f9fafb; +} +.btn-check:focus + .btn-light, .btn-light:focus { + color: #000; + background-color: #f9fafb; + border-color: #f9fafb; + box-shadow: 0 0 0 0.25rem rgba(211, 212, 213, 0.5); +} +.btn-check:checked + .btn-light, .btn-check:active + .btn-light, .btn-light:active, .btn-light.active, .show > .btn-light.dropdown-toggle { + color: #000; + background-color: #f9fafb; + border-color: #f9fafb; +} +.btn-check:checked + .btn-light:focus, .btn-check:active + .btn-light:focus, .btn-light:active:focus, .btn-light.active:focus, .show > .btn-light.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(211, 212, 213, 0.5); +} +.btn-light:disabled, .btn-light.disabled { + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa; +} + +.btn-dark { + color: #fff; + background-color: #212529; + border-color: #212529; +} +.btn-dark:hover { + color: #fff; + background-color: #1c1f23; + border-color: #1a1e21; +} +.btn-check:focus + .btn-dark, .btn-dark:focus { + color: #fff; + background-color: #1c1f23; + border-color: #1a1e21; + box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5); +} +.btn-check:checked + .btn-dark, .btn-check:active + .btn-dark, .btn-dark:active, .btn-dark.active, .show > .btn-dark.dropdown-toggle { + color: #fff; + background-color: #1a1e21; + border-color: #191c1f; +} +.btn-check:checked + .btn-dark:focus, .btn-check:active + .btn-dark:focus, .btn-dark:active:focus, .btn-dark.active:focus, .show > .btn-dark.dropdown-toggle:focus { + box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5); +} +.btn-dark:disabled, .btn-dark.disabled { + color: #fff; + background-color: #212529; + border-color: #212529; +} + +.btn-outline-primary { + color: #0d6efd; + border-color: #0d6efd; +} +.btn-outline-primary:hover { + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd; +} +.btn-check:focus + .btn-outline-primary, .btn-outline-primary:focus { + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.5); +} +.btn-check:checked + .btn-outline-primary, .btn-check:active + .btn-outline-primary, .btn-outline-primary:active, .btn-outline-primary.active, .btn-outline-primary.dropdown-toggle.show { + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd; +} +.btn-check:checked + .btn-outline-primary:focus, .btn-check:active + .btn-outline-primary:focus, .btn-outline-primary:active:focus, .btn-outline-primary.active:focus, .btn-outline-primary.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.5); +} +.btn-outline-primary:disabled, .btn-outline-primary.disabled { + color: #0d6efd; + background-color: transparent; +} + +.btn-outline-secondary { + color: #6c757d; + border-color: #6c757d; +} +.btn-outline-secondary:hover { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} +.btn-check:focus + .btn-outline-secondary, .btn-outline-secondary:focus { + box-shadow: 0 0 0 0.25rem rgba(108, 117, 125, 0.5); +} +.btn-check:checked + .btn-outline-secondary, .btn-check:active + .btn-outline-secondary, .btn-outline-secondary:active, .btn-outline-secondary.active, .btn-outline-secondary.dropdown-toggle.show { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} +.btn-check:checked + .btn-outline-secondary:focus, .btn-check:active + .btn-outline-secondary:focus, .btn-outline-secondary:active:focus, .btn-outline-secondary.active:focus, .btn-outline-secondary.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(108, 117, 125, 0.5); +} +.btn-outline-secondary:disabled, .btn-outline-secondary.disabled { + color: #6c757d; + background-color: transparent; +} + +.btn-outline-success { + color: #198754; + border-color: #198754; +} +.btn-outline-success:hover { + color: #fff; + background-color: #198754; + border-color: #198754; +} +.btn-check:focus + .btn-outline-success, .btn-outline-success:focus { + box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.5); +} +.btn-check:checked + .btn-outline-success, .btn-check:active + .btn-outline-success, .btn-outline-success:active, .btn-outline-success.active, .btn-outline-success.dropdown-toggle.show { + color: #fff; + background-color: #198754; + border-color: #198754; +} +.btn-check:checked + .btn-outline-success:focus, .btn-check:active + .btn-outline-success:focus, .btn-outline-success:active:focus, .btn-outline-success.active:focus, .btn-outline-success.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.5); +} +.btn-outline-success:disabled, .btn-outline-success.disabled { + color: #198754; + background-color: transparent; +} + +.btn-outline-info { + color: #0dcaf0; + border-color: #0dcaf0; +} +.btn-outline-info:hover { + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0; +} +.btn-check:focus + .btn-outline-info, .btn-outline-info:focus { + box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.5); +} +.btn-check:checked + .btn-outline-info, .btn-check:active + .btn-outline-info, .btn-outline-info:active, .btn-outline-info.active, .btn-outline-info.dropdown-toggle.show { + color: #000; + background-color: #0dcaf0; + border-color: #0dcaf0; +} +.btn-check:checked + .btn-outline-info:focus, .btn-check:active + .btn-outline-info:focus, .btn-outline-info:active:focus, .btn-outline-info.active:focus, .btn-outline-info.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.5); +} +.btn-outline-info:disabled, .btn-outline-info.disabled { + color: #0dcaf0; + background-color: transparent; +} + +.btn-outline-warning { + color: #ffc107; + border-color: #ffc107; +} +.btn-outline-warning:hover { + color: #000; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-check:focus + .btn-outline-warning, .btn-outline-warning:focus { + box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5); +} +.btn-check:checked + .btn-outline-warning, .btn-check:active + .btn-outline-warning, .btn-outline-warning:active, .btn-outline-warning.active, .btn-outline-warning.dropdown-toggle.show { + color: #000; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-check:checked + .btn-outline-warning:focus, .btn-check:active + .btn-outline-warning:focus, .btn-outline-warning:active:focus, .btn-outline-warning.active:focus, .btn-outline-warning.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5); +} +.btn-outline-warning:disabled, .btn-outline-warning.disabled { + color: #ffc107; + background-color: transparent; +} + +.btn-outline-danger { + color: #dc3545; + border-color: #dc3545; +} +.btn-outline-danger:hover { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} +.btn-check:focus + .btn-outline-danger, .btn-outline-danger:focus { + box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.5); +} +.btn-check:checked + .btn-outline-danger, .btn-check:active + .btn-outline-danger, .btn-outline-danger:active, .btn-outline-danger.active, .btn-outline-danger.dropdown-toggle.show { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} +.btn-check:checked + .btn-outline-danger:focus, .btn-check:active + .btn-outline-danger:focus, .btn-outline-danger:active:focus, .btn-outline-danger.active:focus, .btn-outline-danger.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.5); +} +.btn-outline-danger:disabled, .btn-outline-danger.disabled { + color: #dc3545; + background-color: transparent; +} + +.btn-outline-light { + color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-outline-light:hover { + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-check:focus + .btn-outline-light, .btn-outline-light:focus { + box-shadow: 0 0 0 0.25rem rgba(248, 249, 250, 0.5); +} +.btn-check:checked + .btn-outline-light, .btn-check:active + .btn-outline-light, .btn-outline-light:active, .btn-outline-light.active, .btn-outline-light.dropdown-toggle.show { + color: #000; + background-color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-check:checked + .btn-outline-light:focus, .btn-check:active + .btn-outline-light:focus, .btn-outline-light:active:focus, .btn-outline-light.active:focus, .btn-outline-light.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(248, 249, 250, 0.5); +} +.btn-outline-light:disabled, .btn-outline-light.disabled { + color: #f8f9fa; + background-color: transparent; +} + +.btn-outline-dark { + color: #212529; + border-color: #212529; +} +.btn-outline-dark:hover { + color: #fff; + background-color: #212529; + border-color: #212529; +} +.btn-check:focus + .btn-outline-dark, .btn-outline-dark:focus { + box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5); +} +.btn-check:checked + .btn-outline-dark, .btn-check:active + .btn-outline-dark, .btn-outline-dark:active, .btn-outline-dark.active, .btn-outline-dark.dropdown-toggle.show { + color: #fff; + background-color: #212529; + border-color: #212529; +} +.btn-check:checked + .btn-outline-dark:focus, .btn-check:active + .btn-outline-dark:focus, .btn-outline-dark:active:focus, .btn-outline-dark.active:focus, .btn-outline-dark.dropdown-toggle.show:focus { + box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5); +} +.btn-outline-dark:disabled, .btn-outline-dark.disabled { + color: #212529; + background-color: transparent; +} + +.btn-link { + font-weight: 400; + color: #0d6efd; + text-decoration: underline; +} +.btn-link:hover { + color: #0a58ca; +} +.btn-link:disabled, .btn-link.disabled { + color: #6c757d; +} + +.btn-lg, .btn-group-lg > .btn { + padding: 0.5rem 1rem; + font-size: 1.25rem; + border-radius: 0.3rem; +} + +.btn-sm, .btn-group-sm > .btn { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + border-radius: 0.2rem; +} + +.fade { + transition: opacity 0.15s linear; +} +@media (prefers-reduced-motion: reduce) { + .fade { + transition: none; + } +} +.fade:not(.show) { + opacity: 0; +} + +.collapse:not(.show) { + display: none; +} + +.collapsing { + height: 0; + overflow: hidden; + transition: height 0.35s ease; +} +@media (prefers-reduced-motion: reduce) { + .collapsing { + transition: none; + } +} + +.dropup, +.dropend, +.dropdown, +.dropstart { + position: relative; +} + +.dropdown-toggle { + white-space: nowrap; +} +.dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid; + border-right: 0.3em solid transparent; + border-bottom: 0; + border-left: 0.3em solid transparent; +} +.dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropdown-menu { + position: absolute; + z-index: 1000; + display: none; + min-width: 10rem; + padding: 0.5rem 0; + margin: 0; + font-size: 1rem; + color: #212529; + text-align: left; + list-style: none; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; +} +.dropdown-menu[data-bs-popper] { + top: 100%; + left: 0; + margin-top: 0.125rem; +} + +.dropdown-menu-start { + --bs-position: start; +} +.dropdown-menu-start[data-bs-popper] { + right: auto /* rtl:ignore */; + left: 0 /* rtl:ignore */; +} + +.dropdown-menu-end { + --bs-position: end; +} +.dropdown-menu-end[data-bs-popper] { + right: 0 /* rtl:ignore */; + left: auto /* rtl:ignore */; +} + +@media (min-width: 576px) { + .dropdown-menu-sm-start { + --bs-position: start; + } + .dropdown-menu-sm-start[data-bs-popper] { + right: auto /* rtl:ignore */; + left: 0 /* rtl:ignore */; + } + + .dropdown-menu-sm-end { + --bs-position: end; + } + .dropdown-menu-sm-end[data-bs-popper] { + right: 0 /* rtl:ignore */; + left: auto /* rtl:ignore */; + } +} +@media (min-width: 768px) { + .dropdown-menu-md-start { + --bs-position: start; + } + .dropdown-menu-md-start[data-bs-popper] { + right: auto /* rtl:ignore */; + left: 0 /* rtl:ignore */; + } + + .dropdown-menu-md-end { + --bs-position: end; + } + .dropdown-menu-md-end[data-bs-popper] { + right: 0 /* rtl:ignore */; + left: auto /* rtl:ignore */; + } +} +@media (min-width: 992px) { + .dropdown-menu-lg-start { + --bs-position: start; + } + .dropdown-menu-lg-start[data-bs-popper] { + right: auto /* rtl:ignore */; + left: 0 /* rtl:ignore */; + } + + .dropdown-menu-lg-end { + --bs-position: end; + } + .dropdown-menu-lg-end[data-bs-popper] { + right: 0 /* rtl:ignore */; + left: auto /* rtl:ignore */; + } +} +@media (min-width: 1200px) { + .dropdown-menu-xl-start { + --bs-position: start; + } + .dropdown-menu-xl-start[data-bs-popper] { + right: auto /* rtl:ignore */; + left: 0 /* rtl:ignore */; + } + + .dropdown-menu-xl-end { + --bs-position: end; + } + .dropdown-menu-xl-end[data-bs-popper] { + right: 0 /* rtl:ignore */; + left: auto /* rtl:ignore */; + } +} +@media (min-width: 1400px) { + .dropdown-menu-xxl-start { + --bs-position: start; + } + .dropdown-menu-xxl-start[data-bs-popper] { + right: auto /* rtl:ignore */; + left: 0 /* rtl:ignore */; + } + + .dropdown-menu-xxl-end { + --bs-position: end; + } + .dropdown-menu-xxl-end[data-bs-popper] { + right: 0 /* rtl:ignore */; + left: auto /* rtl:ignore */; + } +} +.dropup .dropdown-menu[data-bs-popper] { + top: auto; + bottom: 100%; + margin-top: 0; + margin-bottom: 0.125rem; +} +.dropup .dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0; + border-right: 0.3em solid transparent; + border-bottom: 0.3em solid; + border-left: 0.3em solid transparent; +} +.dropup .dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropend .dropdown-menu[data-bs-popper] { + top: 0; + right: auto; + left: 100%; + margin-top: 0; + margin-left: 0.125rem; +} +.dropend .dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid transparent; + border-right: 0; + border-bottom: 0.3em solid transparent; + border-left: 0.3em solid; +} +.dropend .dropdown-toggle:empty::after { + margin-left: 0; +} +.dropend .dropdown-toggle::after { + vertical-align: 0; +} + +.dropstart .dropdown-menu[data-bs-popper] { + top: 0; + right: 100%; + left: auto; + margin-top: 0; + margin-right: 0.125rem; +} +.dropstart .dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; +} +.dropstart .dropdown-toggle::after { + display: none; +} +.dropstart .dropdown-toggle::before { + display: inline-block; + margin-right: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid transparent; + border-right: 0.3em solid; + border-bottom: 0.3em solid transparent; +} +.dropstart .dropdown-toggle:empty::after { + margin-left: 0; +} +.dropstart .dropdown-toggle::before { + vertical-align: 0; +} + +.dropdown-divider { + height: 0; + margin: 0.5rem 0; + overflow: hidden; + border-top: 1px solid rgba(0, 0, 0, 0.15); +} + +.dropdown-item { + display: block; + padding: 0.25rem 1rem; + clear: both; + font-weight: 400; + color: #212529; + text-align: inherit; + text-decoration: none; + white-space: nowrap; + background-color: transparent; + border: 0; +} +.dropdown-item:hover, .dropdown-item:focus { + color: #1e2125; + background-color: #e9ecef; +} +.dropdown-item.active, .dropdown-item:active { + color: #fff; + text-decoration: none; + background-color: #0d6efd; +} +.dropdown-item.disabled, .dropdown-item:disabled { + color: #adb5bd; + pointer-events: none; + background-color: transparent; +} + +.dropdown-menu.show { + display: block; +} + +.dropdown-header { + display: block; + padding: 0.5rem 1rem; + margin-bottom: 0; + font-size: 0.875rem; + color: #6c757d; + white-space: nowrap; +} + +.dropdown-item-text { + display: block; + padding: 0.25rem 1rem; + color: #212529; +} + +.dropdown-menu-dark { + color: #dee2e6; + background-color: #343a40; + border-color: rgba(0, 0, 0, 0.15); +} +.dropdown-menu-dark .dropdown-item { + color: #dee2e6; +} +.dropdown-menu-dark .dropdown-item:hover, .dropdown-menu-dark .dropdown-item:focus { + color: #fff; + background-color: rgba(255, 255, 255, 0.15); +} +.dropdown-menu-dark .dropdown-item.active, .dropdown-menu-dark .dropdown-item:active { + color: #fff; + background-color: #0d6efd; +} +.dropdown-menu-dark .dropdown-item.disabled, .dropdown-menu-dark .dropdown-item:disabled { + color: #adb5bd; +} +.dropdown-menu-dark .dropdown-divider { + border-color: rgba(0, 0, 0, 0.15); +} +.dropdown-menu-dark .dropdown-item-text { + color: #dee2e6; +} +.dropdown-menu-dark .dropdown-header { + color: #adb5bd; +} + +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-flex; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + flex: 1 1 auto; +} +.btn-group > .btn-check:checked + .btn, +.btn-group > .btn-check:focus + .btn, +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn-check:checked + .btn, +.btn-group-vertical > .btn-check:focus + .btn, +.btn-group-vertical > .btn:hover, +.btn-group-vertical > .btn:focus, +.btn-group-vertical > .btn:active, +.btn-group-vertical > .btn.active { + z-index: 1; +} + +.btn-toolbar { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; +} +.btn-toolbar .input-group { + width: auto; +} + +.btn-group > .btn:not(:first-child), +.btn-group > .btn-group:not(:first-child) { + margin-left: -1px; +} +.btn-group > .btn:not(:last-child):not(.dropdown-toggle), +.btn-group > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn:nth-child(n+3), +.btn-group > :not(.btn-check) + .btn, +.btn-group > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.dropdown-toggle-split { + padding-right: 0.5625rem; + padding-left: 0.5625rem; +} +.dropdown-toggle-split::after, .dropup .dropdown-toggle-split::after, .dropend .dropdown-toggle-split::after { + margin-left: 0; +} +.dropstart .dropdown-toggle-split::before { + margin-right: 0; +} + +.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split { + padding-right: 0.375rem; + padding-left: 0.375rem; +} + +.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split { + padding-right: 0.75rem; + padding-left: 0.75rem; +} + +.btn-group-vertical { + flex-direction: column; + align-items: flex-start; + justify-content: center; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group { + width: 100%; +} +.btn-group-vertical > .btn:not(:first-child), +.btn-group-vertical > .btn-group:not(:first-child) { + margin-top: -1px; +} +.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle), +.btn-group-vertical > .btn-group:not(:last-child) > .btn { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn ~ .btn, +.btn-group-vertical > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.nav { + display: flex; + flex-wrap: wrap; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} + +.nav-link { + display: block; + padding: 0.5rem 1rem; + color: #0d6efd; + text-decoration: none; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .nav-link { + transition: none; + } +} +.nav-link:hover, .nav-link:focus { + color: #0a58ca; +} +.nav-link.disabled { + color: #6c757d; + pointer-events: none; + cursor: default; +} + +.nav-tabs { + border-bottom: 1px solid #dee2e6; +} +.nav-tabs .nav-link { + margin-bottom: -1px; + background: none; + border: 1px solid transparent; + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} +.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus { + border-color: #e9ecef #e9ecef #dee2e6; + isolation: isolate; +} +.nav-tabs .nav-link.disabled { + color: #6c757d; + background-color: transparent; + border-color: transparent; +} +.nav-tabs .nav-link.active, +.nav-tabs .nav-item.show .nav-link { + color: #495057; + background-color: #fff; + border-color: #dee2e6 #dee2e6 #fff; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.nav-pills .nav-link { + background: none; + border: 0; + border-radius: 0.25rem; +} +.nav-pills .nav-link.active, +.nav-pills .show > .nav-link { + color: #fff; + background-color: #0d6efd; +} + +.nav-fill > .nav-link, +.nav-fill .nav-item { + flex: 1 1 auto; + text-align: center; +} + +.nav-justified > .nav-link, +.nav-justified .nav-item { + flex-basis: 0; + flex-grow: 1; + text-align: center; +} + +.nav-fill .nav-item .nav-link, +.nav-justified .nav-item .nav-link { + width: 100%; +} + +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} + +.navbar { + position: relative; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} +.navbar > .container, +.navbar > .container-fluid, +.navbar > .container-sm, +.navbar > .container-md, +.navbar > .container-lg, +.navbar > .container-xl, +.navbar > .container-xxl { + display: flex; + flex-wrap: inherit; + align-items: center; + justify-content: space-between; +} +.navbar-brand { + padding-top: 0.3125rem; + padding-bottom: 0.3125rem; + margin-right: 1rem; + font-size: 1.25rem; + text-decoration: none; + white-space: nowrap; +} +.navbar-nav { + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.navbar-nav .nav-link { + padding-right: 0; + padding-left: 0; +} +.navbar-nav .dropdown-menu { + position: static; +} + +.navbar-text { + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.navbar-collapse { + flex-basis: 100%; + flex-grow: 1; + align-items: center; +} + +.navbar-toggler { + padding: 0.25rem 0.75rem; + font-size: 1.25rem; + line-height: 1; + background-color: transparent; + border: 1px solid transparent; + border-radius: 0.25rem; + transition: box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .navbar-toggler { + transition: none; + } +} +.navbar-toggler:hover { + text-decoration: none; +} +.navbar-toggler:focus { + text-decoration: none; + outline: 0; + box-shadow: 0 0 0 0.25rem; +} + +.navbar-toggler-icon { + display: inline-block; + width: 1.5em; + height: 1.5em; + vertical-align: middle; + background-repeat: no-repeat; + background-position: center; + background-size: 100%; +} + +.navbar-nav-scroll { + max-height: var(--bs-scroll-height, 75vh); + overflow-y: auto; +} + +@media (min-width: 576px) { + .navbar-expand-sm { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-sm .navbar-nav { + flex-direction: row; + } + .navbar-expand-sm .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-sm .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-sm .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-sm .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-sm .navbar-toggler { + display: none; + } +} +@media (min-width: 768px) { + .navbar-expand-md { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-md .navbar-nav { + flex-direction: row; + } + .navbar-expand-md .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-md .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-md .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-md .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-md .navbar-toggler { + display: none; + } +} +@media (min-width: 992px) { + .navbar-expand-lg { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-lg .navbar-nav { + flex-direction: row; + } + .navbar-expand-lg .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-lg .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-lg .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-lg .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-lg .navbar-toggler { + display: none; + } +} +@media (min-width: 1200px) { + .navbar-expand-xl { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-xl .navbar-nav { + flex-direction: row; + } + .navbar-expand-xl .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-xl .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-xl .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-xl .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-xl .navbar-toggler { + display: none; + } +} +@media (min-width: 1400px) { + .navbar-expand-xxl { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-xxl .navbar-nav { + flex-direction: row; + } + .navbar-expand-xxl .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-xxl .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-xxl .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-xxl .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-xxl .navbar-toggler { + display: none; + } +} +.navbar-expand { + flex-wrap: nowrap; + justify-content: flex-start; +} +.navbar-expand .navbar-nav { + flex-direction: row; +} +.navbar-expand .navbar-nav .dropdown-menu { + position: absolute; +} +.navbar-expand .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; +} +.navbar-expand .navbar-nav-scroll { + overflow: visible; +} +.navbar-expand .navbar-collapse { + display: flex !important; + flex-basis: auto; +} +.navbar-expand .navbar-toggler { + display: none; +} + +.navbar-light .navbar-brand { + color: rgba(0, 0, 0, 0.9); +} +.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus { + color: rgba(0, 0, 0, 0.9); +} +.navbar-light .navbar-nav .nav-link { + color: rgba(0, 0, 0, 0.55); +} +.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus { + color: rgba(0, 0, 0, 0.7); +} +.navbar-light .navbar-nav .nav-link.disabled { + color: rgba(0, 0, 0, 0.3); +} +.navbar-light .navbar-nav .show > .nav-link, +.navbar-light .navbar-nav .nav-link.active { + color: rgba(0, 0, 0, 0.9); +} +.navbar-light .navbar-toggler { + color: rgba(0, 0, 0, 0.55); + border-color: rgba(0, 0, 0, 0.1); +} +.navbar-light .navbar-toggler-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); +} +.navbar-light .navbar-text { + color: rgba(0, 0, 0, 0.55); +} +.navbar-light .navbar-text a, +.navbar-light .navbar-text a:hover, +.navbar-light .navbar-text a:focus { + color: rgba(0, 0, 0, 0.9); +} + +.navbar-dark .navbar-brand { + color: #fff; +} +.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus { + color: #fff; +} +.navbar-dark .navbar-nav .nav-link { + color: rgba(255, 255, 255, 0.55); +} +.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus { + color: rgba(255, 255, 255, 0.75); +} +.navbar-dark .navbar-nav .nav-link.disabled { + color: rgba(255, 255, 255, 0.25); +} +.navbar-dark .navbar-nav .show > .nav-link, +.navbar-dark .navbar-nav .nav-link.active { + color: #fff; +} +.navbar-dark .navbar-toggler { + color: rgba(255, 255, 255, 0.55); + border-color: rgba(255, 255, 255, 0.1); +} +.navbar-dark .navbar-toggler-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); +} +.navbar-dark .navbar-text { + color: rgba(255, 255, 255, 0.55); +} +.navbar-dark .navbar-text a, +.navbar-dark .navbar-text a:hover, +.navbar-dark .navbar-text a:focus { + color: #fff; +} + +.card { + position: relative; + display: flex; + flex-direction: column; + min-width: 0; + word-wrap: break-word; + background-color: #fff; + background-clip: border-box; + border: 1px solid rgba(0, 0, 0, 0.125); + border-radius: 0.25rem; +} +.card > hr { + margin-right: 0; + margin-left: 0; +} +.card > .list-group { + border-top: inherit; + border-bottom: inherit; +} +.card > .list-group:first-child { + border-top-width: 0; + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} +.card > .list-group:last-child { + border-bottom-width: 0; + border-bottom-right-radius: calc(0.25rem - 1px); + border-bottom-left-radius: calc(0.25rem - 1px); +} +.card > .card-header + .list-group, +.card > .list-group + .card-footer { + border-top: 0; +} + +.card-body { + flex: 1 1 auto; + padding: 1rem 1rem; +} + +.card-title { + margin-bottom: 0.5rem; +} + +.card-subtitle { + margin-top: -0.25rem; + margin-bottom: 0; +} + +.card-text:last-child { + margin-bottom: 0; +} + +.card-link:hover { + text-decoration: none; +} +.card-link + .card-link { + margin-left: 1rem; +} + +.card-header { + padding: 0.5rem 1rem; + margin-bottom: 0; + background-color: rgba(0, 0, 0, 0.03); + border-bottom: 1px solid rgba(0, 0, 0, 0.125); +} +.card-header:first-child { + border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0; +} + +.card-footer { + padding: 0.5rem 1rem; + background-color: rgba(0, 0, 0, 0.03); + border-top: 1px solid rgba(0, 0, 0, 0.125); +} +.card-footer:last-child { + border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px); +} + +.card-header-tabs { + margin-right: -0.5rem; + margin-bottom: -0.5rem; + margin-left: -0.5rem; + border-bottom: 0; +} + +.card-header-pills { + margin-right: -0.5rem; + margin-left: -0.5rem; +} + +.card-img-overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: 1rem; + border-radius: calc(0.25rem - 1px); +} + +.card-img, +.card-img-top, +.card-img-bottom { + width: 100%; +} + +.card-img, +.card-img-top { + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} + +.card-img, +.card-img-bottom { + border-bottom-right-radius: calc(0.25rem - 1px); + border-bottom-left-radius: calc(0.25rem - 1px); +} + +.card-group > .card { + margin-bottom: 0.75rem; +} +@media (min-width: 576px) { + .card-group { + display: flex; + flex-flow: row wrap; + } + .card-group > .card { + flex: 1 0 0%; + margin-bottom: 0; + } + .card-group > .card + .card { + margin-left: 0; + border-left: 0; + } + .card-group > .card:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .card-group > .card:not(:last-child) .card-img-top, +.card-group > .card:not(:last-child) .card-header { + border-top-right-radius: 0; + } + .card-group > .card:not(:last-child) .card-img-bottom, +.card-group > .card:not(:last-child) .card-footer { + border-bottom-right-radius: 0; + } + .card-group > .card:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .card-group > .card:not(:first-child) .card-img-top, +.card-group > .card:not(:first-child) .card-header { + border-top-left-radius: 0; + } + .card-group > .card:not(:first-child) .card-img-bottom, +.card-group > .card:not(:first-child) .card-footer { + border-bottom-left-radius: 0; + } +} + +.accordion-button { + position: relative; + display: flex; + align-items: center; + width: 100%; + padding: 1rem 1.25rem; + font-size: 1rem; + color: #212529; + text-align: left; + background-color: #fff; + border: 0; + border-radius: 0; + overflow-anchor: none; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease; +} +@media (prefers-reduced-motion: reduce) { + .accordion-button { + transition: none; + } +} +.accordion-button:not(.collapsed) { + color: #0c63e4; + background-color: #e7f1ff; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.125); +} +.accordion-button:not(.collapsed)::after { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); + transform: rotate(-180deg); +} +.accordion-button::after { + flex-shrink: 0; + width: 1.25rem; + height: 1.25rem; + margin-left: auto; + content: ""; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-size: 1.25rem; + transition: transform 0.2s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .accordion-button::after { + transition: none; + } +} +.accordion-button:hover { + z-index: 2; +} +.accordion-button:focus { + z-index: 3; + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} + +.accordion-header { + margin-bottom: 0; +} + +.accordion-item { + background-color: #fff; + border: 1px solid rgba(0, 0, 0, 0.125); +} +.accordion-item:first-of-type { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} +.accordion-item:first-of-type .accordion-button { + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} +.accordion-item:not(:first-of-type) { + border-top: 0; +} +.accordion-item:last-of-type { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} +.accordion-item:last-of-type .accordion-button.collapsed { + border-bottom-right-radius: calc(0.25rem - 1px); + border-bottom-left-radius: calc(0.25rem - 1px); +} +.accordion-item:last-of-type .accordion-collapse { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} + +.accordion-body { + padding: 1rem 1.25rem; +} + +.accordion-flush .accordion-collapse { + border-width: 0; +} +.accordion-flush .accordion-item { + border-right: 0; + border-left: 0; + border-radius: 0; +} +.accordion-flush .accordion-item:first-child { + border-top: 0; +} +.accordion-flush .accordion-item:last-child { + border-bottom: 0; +} +.accordion-flush .accordion-item .accordion-button { + border-radius: 0; +} + +.breadcrumb { + display: flex; + flex-wrap: wrap; + padding: 0 0; + margin-bottom: 1rem; + list-style: none; +} + +.breadcrumb-item + .breadcrumb-item { + padding-left: 0.5rem; +} +.breadcrumb-item + .breadcrumb-item::before { + float: left; + padding-right: 0.5rem; + color: #6c757d; + content: var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */; +} +.breadcrumb-item.active { + color: #6c757d; +} + +.pagination { + display: flex; + padding-left: 0; + list-style: none; +} + +.page-link { + position: relative; + display: block; + color: #0d6efd; + text-decoration: none; + background-color: #fff; + border: 1px solid #dee2e6; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .page-link { + transition: none; + } +} +.page-link:hover { + z-index: 2; + color: #0a58ca; + background-color: #e9ecef; + border-color: #dee2e6; +} +.page-link:focus { + z-index: 3; + color: #0a58ca; + background-color: #e9ecef; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} + +.page-item:not(:first-child) .page-link { + margin-left: -1px; +} +.page-item.active .page-link { + z-index: 3; + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd; +} +.page-item.disabled .page-link { + color: #6c757d; + pointer-events: none; + background-color: #fff; + border-color: #dee2e6; +} + +.page-link { + padding: 0.375rem 0.75rem; +} + +.page-item:first-child .page-link { + border-top-left-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} +.page-item:last-child .page-link { + border-top-right-radius: 0.25rem; + border-bottom-right-radius: 0.25rem; +} + +.pagination-lg .page-link { + padding: 0.75rem 1.5rem; + font-size: 1.25rem; +} +.pagination-lg .page-item:first-child .page-link { + border-top-left-radius: 0.3rem; + border-bottom-left-radius: 0.3rem; +} +.pagination-lg .page-item:last-child .page-link { + border-top-right-radius: 0.3rem; + border-bottom-right-radius: 0.3rem; +} + +.pagination-sm .page-link { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; +} +.pagination-sm .page-item:first-child .page-link { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; +} +.pagination-sm .page-item:last-child .page-link { + border-top-right-radius: 0.2rem; + border-bottom-right-radius: 0.2rem; +} + +.badge { + display: inline-block; + padding: 0.35em 0.65em; + font-size: 0.75em; + font-weight: 700; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 0.25rem; +} +.badge:empty { + display: none; +} + +.btn .badge { + position: relative; + top: -1px; +} + +.alert { + position: relative; + padding: 1rem 1rem; + margin-bottom: 1rem; + border: 1px solid transparent; + border-radius: 0.25rem; +} + +.alert-heading { + color: inherit; +} + +.alert-link { + font-weight: 700; +} + +.alert-dismissible { + padding-right: 3rem; +} +.alert-dismissible .btn-close { + position: absolute; + top: 0; + right: 0; + z-index: 2; + padding: 1.25rem 1rem; +} + +.alert-primary { + color: #084298; + background-color: #cfe2ff; + border-color: #b6d4fe; +} +.alert-primary .alert-link { + color: #06357a; +} + +.alert-secondary { + color: #41464b; + background-color: #e2e3e5; + border-color: #d3d6d8; +} +.alert-secondary .alert-link { + color: #34383c; +} + +.alert-success { + color: #0f5132; + background-color: #d1e7dd; + border-color: #badbcc; +} +.alert-success .alert-link { + color: #0c4128; +} + +.alert-info { + color: #055160; + background-color: #cff4fc; + border-color: #b6effb; +} +.alert-info .alert-link { + color: #04414d; +} + +.alert-warning { + color: #664d03; + background-color: #fff3cd; + border-color: #ffecb5; +} +.alert-warning .alert-link { + color: #523e02; +} + +.alert-danger { + color: #842029; + background-color: #f8d7da; + border-color: #f5c2c7; +} +.alert-danger .alert-link { + color: #6a1a21; +} + +.alert-light { + color: #636464; + background-color: #fefefe; + border-color: #fdfdfe; +} +.alert-light .alert-link { + color: #4f5050; +} + +.alert-dark { + color: #141619; + background-color: #d3d3d4; + border-color: #bcbebf; +} +.alert-dark .alert-link { + color: #101214; +} + +@-webkit-keyframes progress-bar-stripes { + 0% { + background-position-x: 1rem; + } +} + +@keyframes progress-bar-stripes { + 0% { + background-position-x: 1rem; + } +} +.progress { + display: flex; + height: 1rem; + overflow: hidden; + font-size: 0.75rem; + background-color: #e9ecef; + border-radius: 0.25rem; +} + +.progress-bar { + display: flex; + flex-direction: column; + justify-content: center; + overflow: hidden; + color: #fff; + text-align: center; + white-space: nowrap; + background-color: #0d6efd; + transition: width 0.6s ease; +} +@media (prefers-reduced-motion: reduce) { + .progress-bar { + transition: none; + } +} + +.progress-bar-striped { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 1rem 1rem; +} + +.progress-bar-animated { + -webkit-animation: 1s linear infinite progress-bar-stripes; + animation: 1s linear infinite progress-bar-stripes; +} +@media (prefers-reduced-motion: reduce) { + .progress-bar-animated { + -webkit-animation: none; + animation: none; + } +} + +.list-group { + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + border-radius: 0.25rem; +} + +.list-group-numbered { + list-style-type: none; + counter-reset: section; +} +.list-group-numbered > li::before { + content: counters(section, ".") ". "; + counter-increment: section; +} + +.list-group-item-action { + width: 100%; + color: #495057; + text-align: inherit; +} +.list-group-item-action:hover, .list-group-item-action:focus { + z-index: 1; + color: #495057; + text-decoration: none; + background-color: #f8f9fa; +} +.list-group-item-action:active { + color: #212529; + background-color: #e9ecef; +} + +.list-group-item { + position: relative; + display: block; + padding: 0.5rem 1rem; + color: #212529; + text-decoration: none; + background-color: #fff; + border: 1px solid rgba(0, 0, 0, 0.125); +} +.list-group-item:first-child { + border-top-left-radius: inherit; + border-top-right-radius: inherit; +} +.list-group-item:last-child { + border-bottom-right-radius: inherit; + border-bottom-left-radius: inherit; +} +.list-group-item.disabled, .list-group-item:disabled { + color: #6c757d; + pointer-events: none; + background-color: #fff; +} +.list-group-item.active { + z-index: 2; + color: #fff; + background-color: #0d6efd; + border-color: #0d6efd; +} +.list-group-item + .list-group-item { + border-top-width: 0; +} +.list-group-item + .list-group-item.active { + margin-top: -1px; + border-top-width: 1px; +} + +.list-group-horizontal { + flex-direction: row; +} +.list-group-horizontal > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; +} +.list-group-horizontal > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; +} +.list-group-horizontal > .list-group-item.active { + margin-top: 0; +} +.list-group-horizontal > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; +} +.list-group-horizontal > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; +} + +@media (min-width: 576px) { + .list-group-horizontal-sm { + flex-direction: row; + } + .list-group-horizontal-sm > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + .list-group-horizontal-sm > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + .list-group-horizontal-sm > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-sm > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + .list-group-horizontal-sm > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } +} +@media (min-width: 768px) { + .list-group-horizontal-md { + flex-direction: row; + } + .list-group-horizontal-md > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + .list-group-horizontal-md > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + .list-group-horizontal-md > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-md > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + .list-group-horizontal-md > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } +} +@media (min-width: 992px) { + .list-group-horizontal-lg { + flex-direction: row; + } + .list-group-horizontal-lg > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + .list-group-horizontal-lg > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + .list-group-horizontal-lg > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-lg > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + .list-group-horizontal-lg > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } +} +@media (min-width: 1200px) { + .list-group-horizontal-xl { + flex-direction: row; + } + .list-group-horizontal-xl > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + .list-group-horizontal-xl > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + .list-group-horizontal-xl > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-xl > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + .list-group-horizontal-xl > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } +} +@media (min-width: 1400px) { + .list-group-horizontal-xxl { + flex-direction: row; + } + .list-group-horizontal-xxl > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + .list-group-horizontal-xxl > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + .list-group-horizontal-xxl > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-xxl > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + .list-group-horizontal-xxl > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } +} +.list-group-flush { + border-radius: 0; +} +.list-group-flush > .list-group-item { + border-width: 0 0 1px; +} +.list-group-flush > .list-group-item:last-child { + border-bottom-width: 0; +} + +.list-group-item-primary { + color: #084298; + background-color: #cfe2ff; +} +.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus { + color: #084298; + background-color: #bacbe6; +} +.list-group-item-primary.list-group-item-action.active { + color: #fff; + background-color: #084298; + border-color: #084298; +} + +.list-group-item-secondary { + color: #41464b; + background-color: #e2e3e5; +} +.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus { + color: #41464b; + background-color: #cbccce; +} +.list-group-item-secondary.list-group-item-action.active { + color: #fff; + background-color: #41464b; + border-color: #41464b; +} + +.list-group-item-success { + color: #0f5132; + background-color: #d1e7dd; +} +.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus { + color: #0f5132; + background-color: #bcd0c7; +} +.list-group-item-success.list-group-item-action.active { + color: #fff; + background-color: #0f5132; + border-color: #0f5132; +} + +.list-group-item-info { + color: #055160; + background-color: #cff4fc; +} +.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus { + color: #055160; + background-color: #badce3; +} +.list-group-item-info.list-group-item-action.active { + color: #fff; + background-color: #055160; + border-color: #055160; +} + +.list-group-item-warning { + color: #664d03; + background-color: #fff3cd; +} +.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus { + color: #664d03; + background-color: #e6dbb9; +} +.list-group-item-warning.list-group-item-action.active { + color: #fff; + background-color: #664d03; + border-color: #664d03; +} + +.list-group-item-danger { + color: #842029; + background-color: #f8d7da; +} +.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus { + color: #842029; + background-color: #dfc2c4; +} +.list-group-item-danger.list-group-item-action.active { + color: #fff; + background-color: #842029; + border-color: #842029; +} + +.list-group-item-light { + color: #636464; + background-color: #fefefe; +} +.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus { + color: #636464; + background-color: #e5e5e5; +} +.list-group-item-light.list-group-item-action.active { + color: #fff; + background-color: #636464; + border-color: #636464; +} + +.list-group-item-dark { + color: #141619; + background-color: #d3d3d4; +} +.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus { + color: #141619; + background-color: #bebebf; +} +.list-group-item-dark.list-group-item-action.active { + color: #fff; + background-color: #141619; + border-color: #141619; +} + +.btn-close { + box-sizing: content-box; + width: 1em; + height: 1em; + padding: 0.25em 0.25em; + color: #000; + background: transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat; + border: 0; + border-radius: 0.25rem; + opacity: 0.5; +} +.btn-close:hover { + color: #000; + text-decoration: none; + opacity: 0.75; +} +.btn-close:focus { + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); + opacity: 1; +} +.btn-close:disabled, .btn-close.disabled { + pointer-events: none; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + opacity: 0.25; +} + +.btn-close-white { + filter: invert(1) grayscale(100%) brightness(200%); +} + +.toast { + width: 350px; + max-width: 100%; + font-size: 0.875rem; + pointer-events: auto; + background-color: rgba(255, 255, 255, 0.85); + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.1); + box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; +} +.toast:not(.showing):not(.show) { + opacity: 0; +} +.toast.hide { + display: none; +} + +.toast-container { + width: -webkit-max-content; + width: -moz-max-content; + width: max-content; + max-width: 100%; + pointer-events: none; +} +.toast-container > :not(:last-child) { + margin-bottom: 0.75rem; +} + +.toast-header { + display: flex; + align-items: center; + padding: 0.5rem 0.75rem; + color: #6c757d; + background-color: rgba(255, 255, 255, 0.85); + background-clip: padding-box; + border-bottom: 1px solid rgba(0, 0, 0, 0.05); + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} +.toast-header .btn-close { + margin-right: -0.375rem; + margin-left: 0.75rem; +} + +.toast-body { + padding: 0.75rem; + word-wrap: break-word; +} + +.modal { + position: fixed; + top: 0; + left: 0; + z-index: 1060; + display: none; + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: auto; + outline: 0; +} + +.modal-dialog { + position: relative; + width: auto; + margin: 0.5rem; + pointer-events: none; +} +.modal.fade .modal-dialog { + transition: transform 0.3s ease-out; + transform: translate(0, -50px); +} +@media (prefers-reduced-motion: reduce) { + .modal.fade .modal-dialog { + transition: none; + } +} +.modal.show .modal-dialog { + transform: none; +} +.modal.modal-static .modal-dialog { + transform: scale(1.02); +} + +.modal-dialog-scrollable { + height: calc(100% - 1rem); +} +.modal-dialog-scrollable .modal-content { + max-height: 100%; + overflow: hidden; +} +.modal-dialog-scrollable .modal-body { + overflow-y: auto; +} + +.modal-dialog-centered { + display: flex; + align-items: center; + min-height: calc(100% - 1rem); +} + +.modal-content { + position: relative; + display: flex; + flex-direction: column; + width: 100%; + pointer-events: auto; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0.3rem; + outline: 0; +} + +.modal-backdrop { + position: fixed; + top: 0; + left: 0; + z-index: 1040; + width: 100vw; + height: 100vh; + background-color: #000; +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop.show { + opacity: 0.5; +} + +.modal-header { + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: space-between; + padding: 1rem 1rem; + border-bottom: 1px solid #dee2e6; + border-top-left-radius: calc(0.3rem - 1px); + border-top-right-radius: calc(0.3rem - 1px); +} +.modal-header .btn-close { + padding: 0.5rem 0.5rem; + margin: -0.5rem -0.5rem -0.5rem auto; +} + +.modal-title { + margin-bottom: 0; + line-height: 1.5; +} + +.modal-body { + position: relative; + flex: 1 1 auto; + padding: 1rem; +} + +.modal-footer { + display: flex; + flex-wrap: wrap; + flex-shrink: 0; + align-items: center; + justify-content: flex-end; + padding: 0.75rem; + border-top: 1px solid #dee2e6; + border-bottom-right-radius: calc(0.3rem - 1px); + border-bottom-left-radius: calc(0.3rem - 1px); +} +.modal-footer > * { + margin: 0.25rem; +} + +@media (min-width: 576px) { + .modal-dialog { + max-width: 500px; + margin: 1.75rem auto; + } + + .modal-dialog-scrollable { + height: calc(100% - 3.5rem); + } + + .modal-dialog-centered { + min-height: calc(100% - 3.5rem); + } + + .modal-sm { + max-width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg, +.modal-xl { + max-width: 800px; + } +} +@media (min-width: 1200px) { + .modal-xl { + max-width: 1140px; + } +} +.modal-fullscreen { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; +} +.modal-fullscreen .modal-content { + height: 100%; + border: 0; + border-radius: 0; +} +.modal-fullscreen .modal-header { + border-radius: 0; +} +.modal-fullscreen .modal-body { + overflow-y: auto; +} +.modal-fullscreen .modal-footer { + border-radius: 0; +} + +@media (max-width: 575.98px) { + .modal-fullscreen-sm-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-sm-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-sm-down .modal-header { + border-radius: 0; + } + .modal-fullscreen-sm-down .modal-body { + overflow-y: auto; + } + .modal-fullscreen-sm-down .modal-footer { + border-radius: 0; + } +} +@media (max-width: 767.98px) { + .modal-fullscreen-md-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-md-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-md-down .modal-header { + border-radius: 0; + } + .modal-fullscreen-md-down .modal-body { + overflow-y: auto; + } + .modal-fullscreen-md-down .modal-footer { + border-radius: 0; + } +} +@media (max-width: 991.98px) { + .modal-fullscreen-lg-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-lg-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-lg-down .modal-header { + border-radius: 0; + } + .modal-fullscreen-lg-down .modal-body { + overflow-y: auto; + } + .modal-fullscreen-lg-down .modal-footer { + border-radius: 0; + } +} +@media (max-width: 1199.98px) { + .modal-fullscreen-xl-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-xl-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-xl-down .modal-header { + border-radius: 0; + } + .modal-fullscreen-xl-down .modal-body { + overflow-y: auto; + } + .modal-fullscreen-xl-down .modal-footer { + border-radius: 0; + } +} +@media (max-width: 1399.98px) { + .modal-fullscreen-xxl-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-xxl-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-xxl-down .modal-header { + border-radius: 0; + } + .modal-fullscreen-xxl-down .modal-body { + overflow-y: auto; + } + .modal-fullscreen-xxl-down .modal-footer { + border-radius: 0; + } +} +.tooltip { + position: absolute; + z-index: 1080; + display: block; + margin: 0; + font-family: var(--bs-font-sans-serif); + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: 0.875rem; + word-wrap: break-word; + opacity: 0; +} +.tooltip.show { + opacity: 0.9; +} +.tooltip .tooltip-arrow { + position: absolute; + display: block; + width: 0.8rem; + height: 0.4rem; +} +.tooltip .tooltip-arrow::before { + position: absolute; + content: ""; + border-color: transparent; + border-style: solid; +} + +.bs-tooltip-top, .bs-tooltip-auto[data-popper-placement^=top] { + padding: 0.4rem 0; +} +.bs-tooltip-top .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow { + bottom: 0; +} +.bs-tooltip-top .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before { + top: -1px; + border-width: 0.4rem 0.4rem 0; + border-top-color: #000; +} + +.bs-tooltip-end, .bs-tooltip-auto[data-popper-placement^=right] { + padding: 0 0.4rem; +} +.bs-tooltip-end .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow { + left: 0; + width: 0.4rem; + height: 0.8rem; +} +.bs-tooltip-end .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before { + right: -1px; + border-width: 0.4rem 0.4rem 0.4rem 0; + border-right-color: #000; +} + +.bs-tooltip-bottom, .bs-tooltip-auto[data-popper-placement^=bottom] { + padding: 0.4rem 0; +} +.bs-tooltip-bottom .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow { + top: 0; +} +.bs-tooltip-bottom .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before { + bottom: -1px; + border-width: 0 0.4rem 0.4rem; + border-bottom-color: #000; +} + +.bs-tooltip-start, .bs-tooltip-auto[data-popper-placement^=left] { + padding: 0 0.4rem; +} +.bs-tooltip-start .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow { + right: 0; + width: 0.4rem; + height: 0.8rem; +} +.bs-tooltip-start .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before { + left: -1px; + border-width: 0.4rem 0 0.4rem 0.4rem; + border-left-color: #000; +} + +.tooltip-inner { + max-width: 200px; + padding: 0.25rem 0.5rem; + color: #fff; + text-align: center; + background-color: #000; + border-radius: 0.25rem; +} + +.popover { + position: absolute; + top: 0; + left: 0 /* rtl:ignore */; + z-index: 1070; + display: block; + max-width: 276px; + font-family: var(--bs-font-sans-serif); + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: 0.875rem; + word-wrap: break-word; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0.3rem; +} +.popover .popover-arrow { + position: absolute; + display: block; + width: 1rem; + height: 0.5rem; +} +.popover .popover-arrow::before, .popover .popover-arrow::after { + position: absolute; + display: block; + content: ""; + border-color: transparent; + border-style: solid; +} + +.bs-popover-top > .popover-arrow, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow { + bottom: calc(-0.5rem - 1px); +} +.bs-popover-top > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before { + bottom: 0; + border-width: 0.5rem 0.5rem 0; + border-top-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after { + bottom: 1px; + border-width: 0.5rem 0.5rem 0; + border-top-color: #fff; +} + +.bs-popover-end > .popover-arrow, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow { + left: calc(-0.5rem - 1px); + width: 0.5rem; + height: 1rem; +} +.bs-popover-end > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before { + left: 0; + border-width: 0.5rem 0.5rem 0.5rem 0; + border-right-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after { + left: 1px; + border-width: 0.5rem 0.5rem 0.5rem 0; + border-right-color: #fff; +} + +.bs-popover-bottom > .popover-arrow, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow { + top: calc(-0.5rem - 1px); +} +.bs-popover-bottom > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before { + top: 0; + border-width: 0 0.5rem 0.5rem 0.5rem; + border-bottom-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after { + top: 1px; + border-width: 0 0.5rem 0.5rem 0.5rem; + border-bottom-color: #fff; +} +.bs-popover-bottom .popover-header::before, .bs-popover-auto[data-popper-placement^=bottom] .popover-header::before { + position: absolute; + top: 0; + left: 50%; + display: block; + width: 1rem; + margin-left: -0.5rem; + content: ""; + border-bottom: 1px solid #f0f0f0; +} + +.bs-popover-start > .popover-arrow, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow { + right: calc(-0.5rem - 1px); + width: 0.5rem; + height: 1rem; +} +.bs-popover-start > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before { + right: 0; + border-width: 0.5rem 0 0.5rem 0.5rem; + border-left-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after { + right: 1px; + border-width: 0.5rem 0 0.5rem 0.5rem; + border-left-color: #fff; +} + +.popover-header { + padding: 0.5rem 1rem; + margin-bottom: 0; + font-size: 1rem; + background-color: #f0f0f0; + border-bottom: 1px solid #d8d8d8; + border-top-left-radius: calc(0.3rem - 1px); + border-top-right-radius: calc(0.3rem - 1px); +} +.popover-header:empty { + display: none; +} + +.popover-body { + padding: 1rem 1rem; + color: #212529; +} + +.carousel { + position: relative; +} + +.carousel.pointer-event { + touch-action: pan-y; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} +.carousel-inner::after { + display: block; + clear: both; + content: ""; +} + +.carousel-item { + position: relative; + display: none; + float: left; + width: 100%; + margin-right: -100%; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + transition: transform 0.6s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .carousel-item { + transition: none; + } +} + +.carousel-item.active, +.carousel-item-next, +.carousel-item-prev { + display: block; +} + +/* rtl:begin:ignore */ +.carousel-item-next:not(.carousel-item-start), +.active.carousel-item-end { + transform: translateX(100%); +} + +.carousel-item-prev:not(.carousel-item-end), +.active.carousel-item-start { + transform: translateX(-100%); +} + +/* rtl:end:ignore */ +.carousel-fade .carousel-item { + opacity: 0; + transition-property: opacity; + transform: none; +} +.carousel-fade .carousel-item.active, +.carousel-fade .carousel-item-next.carousel-item-start, +.carousel-fade .carousel-item-prev.carousel-item-end { + z-index: 1; + opacity: 1; +} +.carousel-fade .active.carousel-item-start, +.carousel-fade .active.carousel-item-end { + z-index: 0; + opacity: 0; + transition: opacity 0s 0.6s; +} +@media (prefers-reduced-motion: reduce) { + .carousel-fade .active.carousel-item-start, +.carousel-fade .active.carousel-item-end { + transition: none; + } +} + +.carousel-control-prev, +.carousel-control-next { + position: absolute; + top: 0; + bottom: 0; + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + width: 15%; + padding: 0; + color: #fff; + text-align: center; + background: none; + border: 0; + opacity: 0.5; + transition: opacity 0.15s ease; +} +@media (prefers-reduced-motion: reduce) { + .carousel-control-prev, +.carousel-control-next { + transition: none; + } +} +.carousel-control-prev:hover, .carousel-control-prev:focus, +.carousel-control-next:hover, +.carousel-control-next:focus { + color: #fff; + text-decoration: none; + outline: 0; + opacity: 0.9; +} + +.carousel-control-prev { + left: 0; +} + +.carousel-control-next { + right: 0; +} + +.carousel-control-prev-icon, +.carousel-control-next-icon { + display: inline-block; + width: 2rem; + height: 2rem; + background-repeat: no-repeat; + background-position: 50%; + background-size: 100% 100%; +} + +/* rtl:options: { + "autoRename": true, + "stringMap":[ { + "name" : "prev-next", + "search" : "prev", + "replace" : "next" + } ] +} */ +.carousel-control-prev-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e"); +} + +.carousel-control-next-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); +} + +.carousel-indicators { + position: absolute; + right: 0; + bottom: 0; + left: 0; + z-index: 2; + display: flex; + justify-content: center; + padding: 0; + margin-right: 15%; + margin-bottom: 1rem; + margin-left: 15%; + list-style: none; +} +.carousel-indicators [data-bs-target] { + box-sizing: content-box; + flex: 0 1 auto; + width: 30px; + height: 3px; + padding: 0; + margin-right: 3px; + margin-left: 3px; + text-indent: -999px; + cursor: pointer; + background-color: #fff; + background-clip: padding-box; + border: 0; + border-top: 10px solid transparent; + border-bottom: 10px solid transparent; + opacity: 0.5; + transition: opacity 0.6s ease; +} +@media (prefers-reduced-motion: reduce) { + .carousel-indicators [data-bs-target] { + transition: none; + } +} +.carousel-indicators .active { + opacity: 1; +} + +.carousel-caption { + position: absolute; + right: 15%; + bottom: 1.25rem; + left: 15%; + padding-top: 1.25rem; + padding-bottom: 1.25rem; + color: #fff; + text-align: center; +} + +.carousel-dark .carousel-control-prev-icon, +.carousel-dark .carousel-control-next-icon { + filter: invert(1) grayscale(100); +} +.carousel-dark .carousel-indicators [data-bs-target] { + background-color: #000; +} +.carousel-dark .carousel-caption { + color: #000; +} + +@-webkit-keyframes spinner-border { + to { + transform: rotate(360deg) /* rtl:ignore */; + } +} + +@keyframes spinner-border { + to { + transform: rotate(360deg) /* rtl:ignore */; + } +} +.spinner-border { + display: inline-block; + width: 2rem; + height: 2rem; + vertical-align: -0.125em; + border: 0.25em solid currentColor; + border-right-color: transparent; + border-radius: 50%; + -webkit-animation: 0.75s linear infinite spinner-border; + animation: 0.75s linear infinite spinner-border; +} + +.spinner-border-sm { + width: 1rem; + height: 1rem; + border-width: 0.2em; +} + +@-webkit-keyframes spinner-grow { + 0% { + transform: scale(0); + } + 50% { + opacity: 1; + transform: none; + } +} + +@keyframes spinner-grow { + 0% { + transform: scale(0); + } + 50% { + opacity: 1; + transform: none; + } +} +.spinner-grow { + display: inline-block; + width: 2rem; + height: 2rem; + vertical-align: -0.125em; + background-color: currentColor; + border-radius: 50%; + opacity: 0; + -webkit-animation: 0.75s linear infinite spinner-grow; + animation: 0.75s linear infinite spinner-grow; +} + +.spinner-grow-sm { + width: 1rem; + height: 1rem; +} + +@media (prefers-reduced-motion: reduce) { + .spinner-border, +.spinner-grow { + -webkit-animation-duration: 1.5s; + animation-duration: 1.5s; + } +} +.offcanvas { + position: fixed; + bottom: 0; + z-index: 1050; + display: flex; + flex-direction: column; + max-width: 100%; + visibility: hidden; + background-color: #fff; + background-clip: padding-box; + outline: 0; + transition: transform 0.3s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .offcanvas { + transition: none; + } +} + +.offcanvas-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 1rem 1rem; +} +.offcanvas-header .btn-close { + padding: 0.5rem 0.5rem; + margin: -0.5rem -0.5rem -0.5rem auto; +} + +.offcanvas-title { + margin-bottom: 0; + line-height: 1.5; +} + +.offcanvas-body { + flex-grow: 1; + padding: 1rem 1rem; + overflow-y: auto; +} + +.offcanvas-start { + top: 0; + left: 0; + width: 400px; + border-right: 1px solid rgba(0, 0, 0, 0.2); + transform: translateX(-100%); +} + +.offcanvas-end { + top: 0; + right: 0; + width: 400px; + border-left: 1px solid rgba(0, 0, 0, 0.2); + transform: translateX(100%); +} + +.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: 30vh; + max-height: 100%; + border-bottom: 1px solid rgba(0, 0, 0, 0.2); + transform: translateY(-100%); +} + +.offcanvas-bottom { + right: 0; + left: 0; + height: 30vh; + max-height: 100%; + border-top: 1px solid rgba(0, 0, 0, 0.2); + transform: translateY(100%); +} + +.offcanvas.show { + transform: none; +} + +.clearfix::after { + display: block; + clear: both; + content: ""; +} + +.link-primary { + color: #0d6efd; +} +.link-primary:hover, .link-primary:focus { + color: #0a58ca; +} + +.link-secondary { + color: #6c757d; +} +.link-secondary:hover, .link-secondary:focus { + color: #565e64; +} + +.link-success { + color: #198754; +} +.link-success:hover, .link-success:focus { + color: #146c43; +} + +.link-info { + color: #0dcaf0; +} +.link-info:hover, .link-info:focus { + color: #3dd5f3; +} + +.link-warning { + color: #ffc107; +} +.link-warning:hover, .link-warning:focus { + color: #ffcd39; +} + +.link-danger { + color: #dc3545; +} +.link-danger:hover, .link-danger:focus { + color: #b02a37; +} + +.link-light { + color: #f8f9fa; +} +.link-light:hover, .link-light:focus { + color: #f9fafb; +} + +.link-dark { + color: #212529; +} +.link-dark:hover, .link-dark:focus { + color: #1a1e21; +} + +.ratio { + position: relative; + width: 100%; +} +.ratio::before { + display: block; + padding-top: var(--bs-aspect-ratio); + content: ""; +} +.ratio > * { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.ratio-1x1 { + --bs-aspect-ratio: 100%; +} + +.ratio-4x3 { + --bs-aspect-ratio: calc(3 / 4 * 100%); +} + +.ratio-16x9 { + --bs-aspect-ratio: calc(9 / 16 * 100%); +} + +.ratio-21x9 { + --bs-aspect-ratio: calc(9 / 21 * 100%); +} + +.fixed-top { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 1030; +} + +.fixed-bottom { + position: fixed; + right: 0; + bottom: 0; + left: 0; + z-index: 1030; +} + +.sticky-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020; +} + +@media (min-width: 576px) { + .sticky-sm-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020; + } +} +@media (min-width: 768px) { + .sticky-md-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020; + } +} +@media (min-width: 992px) { + .sticky-lg-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020; + } +} +@media (min-width: 1200px) { + .sticky-xl-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020; + } +} +@media (min-width: 1400px) { + .sticky-xxl-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020; + } +} +.visually-hidden, +.visually-hidden-focusable:not(:focus):not(:focus-within) { + position: absolute !important; + width: 1px !important; + height: 1px !important; + padding: 0 !important; + margin: -1px !important; + overflow: hidden !important; + clip: rect(0, 0, 0, 0) !important; + white-space: nowrap !important; + border: 0 !important; +} + +.stretched-link::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1; + content: ""; +} + +.text-truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.align-baseline { + vertical-align: baseline !important; +} + +.align-top { + vertical-align: top !important; +} + +.align-middle { + vertical-align: middle !important; +} + +.align-bottom { + vertical-align: bottom !important; +} + +.align-text-bottom { + vertical-align: text-bottom !important; +} + +.align-text-top { + vertical-align: text-top !important; +} + +.float-start { + float: left !important; +} + +.float-end { + float: right !important; +} + +.float-none { + float: none !important; +} + +.overflow-auto { + overflow: auto !important; +} + +.overflow-hidden { + overflow: hidden !important; +} + +.overflow-visible { + overflow: visible !important; +} + +.overflow-scroll { + overflow: scroll !important; +} + +.d-inline { + display: inline !important; +} + +.d-inline-block { + display: inline-block !important; +} + +.d-block { + display: block !important; +} + +.d-grid { + display: grid !important; +} + +.d-table { + display: table !important; +} + +.d-table-row { + display: table-row !important; +} + +.d-table-cell { + display: table-cell !important; +} + +.d-flex { + display: flex !important; +} + +.d-inline-flex { + display: inline-flex !important; +} + +.d-none { + display: none !important; +} + +.shadow { + box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important; +} + +.shadow-sm { + box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important; +} + +.shadow-lg { + box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important; +} + +.shadow-none { + box-shadow: none !important; +} + +.position-static { + position: static !important; +} + +.position-relative { + position: relative !important; +} + +.position-absolute { + position: absolute !important; +} + +.position-fixed { + position: fixed !important; +} + +.position-sticky { + position: -webkit-sticky !important; + position: sticky !important; +} + +.top-0 { + top: 0 !important; +} + +.top-50 { + top: 50% !important; +} + +.top-100 { + top: 100% !important; +} + +.bottom-0 { + bottom: 0 !important; +} + +.bottom-50 { + bottom: 50% !important; +} + +.bottom-100 { + bottom: 100% !important; +} + +.start-0 { + left: 0 !important; +} + +.start-50 { + left: 50% !important; +} + +.start-100 { + left: 100% !important; +} + +.end-0 { + right: 0 !important; +} + +.end-50 { + right: 50% !important; +} + +.end-100 { + right: 100% !important; +} + +.translate-middle { + transform: translate(-50%, -50%) !important; +} + +.translate-middle-x { + transform: translateX(-50%) !important; +} + +.translate-middle-y { + transform: translateY(-50%) !important; +} + +.border { + border: 1px solid #dee2e6 !important; +} + +.border-0 { + border: 0 !important; +} + +.border-top { + border-top: 1px solid #dee2e6 !important; +} + +.border-top-0 { + border-top: 0 !important; +} + +.border-end { + border-right: 1px solid #dee2e6 !important; +} + +.border-end-0 { + border-right: 0 !important; +} + +.border-bottom { + border-bottom: 1px solid #dee2e6 !important; +} + +.border-bottom-0 { + border-bottom: 0 !important; +} + +.border-start { + border-left: 1px solid #dee2e6 !important; +} + +.border-start-0 { + border-left: 0 !important; +} + +.border-primary { + border-color: #0d6efd !important; +} + +.border-secondary { + border-color: #6c757d !important; +} + +.border-success { + border-color: #198754 !important; +} + +.border-info { + border-color: #0dcaf0 !important; +} + +.border-warning { + border-color: #ffc107 !important; +} + +.border-danger { + border-color: #dc3545 !important; +} + +.border-light { + border-color: #f8f9fa !important; +} + +.border-dark { + border-color: #212529 !important; +} + +.border-white { + border-color: #fff !important; +} + +.border-1 { + border-width: 1px !important; +} + +.border-2 { + border-width: 2px !important; +} + +.border-3 { + border-width: 3px !important; +} + +.border-4 { + border-width: 4px !important; +} + +.border-5 { + border-width: 5px !important; +} + +.w-25 { + width: 25% !important; +} + +.w-50 { + width: 50% !important; +} + +.w-75 { + width: 75% !important; +} + +.w-100 { + width: 100% !important; +} + +.w-auto { + width: auto !important; +} + +.mw-100 { + max-width: 100% !important; +} + +.vw-100 { + width: 100vw !important; +} + +.min-vw-100 { + min-width: 100vw !important; +} + +.h-25 { + height: 25% !important; +} + +.h-50 { + height: 50% !important; +} + +.h-75 { + height: 75% !important; +} + +.h-100 { + height: 100% !important; +} + +.h-auto { + height: auto !important; +} + +.mh-100 { + max-height: 100% !important; +} + +.vh-100 { + height: 100vh !important; +} + +.min-vh-100 { + min-height: 100vh !important; +} + +.flex-fill { + flex: 1 1 auto !important; +} + +.flex-row { + flex-direction: row !important; +} + +.flex-column { + flex-direction: column !important; +} + +.flex-row-reverse { + flex-direction: row-reverse !important; +} + +.flex-column-reverse { + flex-direction: column-reverse !important; +} + +.flex-grow-0 { + flex-grow: 0 !important; +} + +.flex-grow-1 { + flex-grow: 1 !important; +} + +.flex-shrink-0 { + flex-shrink: 0 !important; +} + +.flex-shrink-1 { + flex-shrink: 1 !important; +} + +.flex-wrap { + flex-wrap: wrap !important; +} + +.flex-nowrap { + flex-wrap: nowrap !important; +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse !important; +} + +.gap-0 { + gap: 0 !important; +} + +.gap-1 { + gap: 0.25rem !important; +} + +.gap-2 { + gap: 0.5rem !important; +} + +.gap-3 { + gap: 1rem !important; +} + +.gap-4 { + gap: 1.5rem !important; +} + +.gap-5 { + gap: 3rem !important; +} + +.justify-content-start { + justify-content: flex-start !important; +} + +.justify-content-end { + justify-content: flex-end !important; +} + +.justify-content-center { + justify-content: center !important; +} + +.justify-content-between { + justify-content: space-between !important; +} + +.justify-content-around { + justify-content: space-around !important; +} + +.justify-content-evenly { + justify-content: space-evenly !important; +} + +.align-items-start { + align-items: flex-start !important; +} + +.align-items-end { + align-items: flex-end !important; +} + +.align-items-center { + align-items: center !important; +} + +.align-items-baseline { + align-items: baseline !important; +} + +.align-items-stretch { + align-items: stretch !important; +} + +.align-content-start { + align-content: flex-start !important; +} + +.align-content-end { + align-content: flex-end !important; +} + +.align-content-center { + align-content: center !important; +} + +.align-content-between { + align-content: space-between !important; +} + +.align-content-around { + align-content: space-around !important; +} + +.align-content-stretch { + align-content: stretch !important; +} + +.align-self-auto { + align-self: auto !important; +} + +.align-self-start { + align-self: flex-start !important; +} + +.align-self-end { + align-self: flex-end !important; +} + +.align-self-center { + align-self: center !important; +} + +.align-self-baseline { + align-self: baseline !important; +} + +.align-self-stretch { + align-self: stretch !important; +} + +.order-first { + order: -1 !important; +} + +.order-0 { + order: 0 !important; +} + +.order-1 { + order: 1 !important; +} + +.order-2 { + order: 2 !important; +} + +.order-3 { + order: 3 !important; +} + +.order-4 { + order: 4 !important; +} + +.order-5 { + order: 5 !important; +} + +.order-last { + order: 6 !important; +} + +.m-0 { + margin: 0 !important; +} + +.m-1 { + margin: 0.25rem !important; +} + +.m-2 { + margin: 0.5rem !important; +} + +.m-3 { + margin: 1rem !important; +} + +.m-4 { + margin: 1.5rem !important; +} + +.m-5 { + margin: 3rem !important; +} + +.m-auto { + margin: auto !important; +} + +.mx-0 { + margin-right: 0 !important; + margin-left: 0 !important; +} + +.mx-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; +} + +.mx-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; +} + +.mx-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; +} + +.mx-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; +} + +.mx-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; +} + +.mx-auto { + margin-right: auto !important; + margin-left: auto !important; +} + +.my-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; +} + +.my-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; +} + +.my-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; +} + +.my-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; +} + +.my-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; +} + +.my-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; +} + +.my-auto { + margin-top: auto !important; + margin-bottom: auto !important; +} + +.mt-0 { + margin-top: 0 !important; +} + +.mt-1 { + margin-top: 0.25rem !important; +} + +.mt-2 { + margin-top: 0.5rem !important; +} + +.mt-3 { + margin-top: 1rem !important; +} + +.mt-4 { + margin-top: 1.5rem !important; +} + +.mt-5 { + margin-top: 3rem !important; +} + +.mt-auto { + margin-top: auto !important; +} + +.me-0 { + margin-right: 0 !important; +} + +.me-1 { + margin-right: 0.25rem !important; +} + +.me-2 { + margin-right: 0.5rem !important; +} + +.me-3 { + margin-right: 1rem !important; +} + +.me-4 { + margin-right: 1.5rem !important; +} + +.me-5 { + margin-right: 3rem !important; +} + +.me-auto { + margin-right: auto !important; +} + +.mb-0 { + margin-bottom: 0 !important; +} + +.mb-1 { + margin-bottom: 0.25rem !important; +} + +.mb-2 { + margin-bottom: 0.5rem !important; +} + +.mb-3 { + margin-bottom: 1rem !important; +} + +.mb-4 { + margin-bottom: 1.5rem !important; +} + +.mb-5 { + margin-bottom: 3rem !important; +} + +.mb-auto { + margin-bottom: auto !important; +} + +.ms-0 { + margin-left: 0 !important; +} + +.ms-1 { + margin-left: 0.25rem !important; +} + +.ms-2 { + margin-left: 0.5rem !important; +} + +.ms-3 { + margin-left: 1rem !important; +} + +.ms-4 { + margin-left: 1.5rem !important; +} + +.ms-5 { + margin-left: 3rem !important; +} + +.ms-auto { + margin-left: auto !important; +} + +.p-0 { + padding: 0 !important; +} + +.p-1 { + padding: 0.25rem !important; +} + +.p-2 { + padding: 0.5rem !important; +} + +.p-3 { + padding: 1rem !important; +} + +.p-4 { + padding: 1.5rem !important; +} + +.p-5 { + padding: 3rem !important; +} + +.px-0 { + padding-right: 0 !important; + padding-left: 0 !important; +} + +.px-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; +} + +.px-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; +} + +.px-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; +} + +.px-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; +} + +.px-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; +} + +.py-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; +} + +.py-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; +} + +.py-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; +} + +.py-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; +} + +.py-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; +} + +.py-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; +} + +.pt-0 { + padding-top: 0 !important; +} + +.pt-1 { + padding-top: 0.25rem !important; +} + +.pt-2 { + padding-top: 0.5rem !important; +} + +.pt-3 { + padding-top: 1rem !important; +} + +.pt-4 { + padding-top: 1.5rem !important; +} + +.pt-5 { + padding-top: 3rem !important; +} + +.pe-0 { + padding-right: 0 !important; +} + +.pe-1 { + padding-right: 0.25rem !important; +} + +.pe-2 { + padding-right: 0.5rem !important; +} + +.pe-3 { + padding-right: 1rem !important; +} + +.pe-4 { + padding-right: 1.5rem !important; +} + +.pe-5 { + padding-right: 3rem !important; +} + +.pb-0 { + padding-bottom: 0 !important; +} + +.pb-1 { + padding-bottom: 0.25rem !important; +} + +.pb-2 { + padding-bottom: 0.5rem !important; +} + +.pb-3 { + padding-bottom: 1rem !important; +} + +.pb-4 { + padding-bottom: 1.5rem !important; +} + +.pb-5 { + padding-bottom: 3rem !important; +} + +.ps-0 { + padding-left: 0 !important; +} + +.ps-1 { + padding-left: 0.25rem !important; +} + +.ps-2 { + padding-left: 0.5rem !important; +} + +.ps-3 { + padding-left: 1rem !important; +} + +.ps-4 { + padding-left: 1.5rem !important; +} + +.ps-5 { + padding-left: 3rem !important; +} + +.font-monospace { + font-family: var(--bs-font-monospace) !important; +} + +.fs-1 { + font-size: calc(1.375rem + 1.5vw) !important; +} + +.fs-2 { + font-size: calc(1.325rem + 0.9vw) !important; +} + +.fs-3 { + font-size: calc(1.3rem + 0.6vw) !important; +} + +.fs-4 { + font-size: calc(1.275rem + 0.3vw) !important; +} + +.fs-5 { + font-size: 1.25rem !important; +} + +.fs-6 { + font-size: 1rem !important; +} + +.fst-italic { + font-style: italic !important; +} + +.fst-normal { + font-style: normal !important; +} + +.fw-light { + font-weight: 300 !important; +} + +.fw-lighter { + font-weight: lighter !important; +} + +.fw-normal { + font-weight: 400 !important; +} + +.fw-bold { + font-weight: 700 !important; +} + +.fw-bolder { + font-weight: bolder !important; +} + +.lh-1 { + line-height: 1 !important; +} + +.lh-sm { + line-height: 1.25 !important; +} + +.lh-base { + line-height: 1.5 !important; +} + +.lh-lg { + line-height: 2 !important; +} + +.text-start { + text-align: left !important; +} + +.text-end { + text-align: right !important; +} + +.text-center { + text-align: center !important; +} + +.text-decoration-none { + text-decoration: none !important; +} + +.text-decoration-underline { + text-decoration: underline !important; +} + +.text-decoration-line-through { + text-decoration: line-through !important; +} + +.text-lowercase { + text-transform: lowercase !important; +} + +.text-uppercase { + text-transform: uppercase !important; +} + +.text-capitalize { + text-transform: capitalize !important; +} + +.text-wrap { + white-space: normal !important; +} + +.text-nowrap { + white-space: nowrap !important; +} + +/* rtl:begin:remove */ +.text-break { + word-wrap: break-word !important; + word-break: break-word !important; +} + +/* rtl:end:remove */ +.text-primary { + color: #0d6efd !important; +} + +.text-secondary { + color: #6c757d !important; +} + +.text-success { + color: #198754 !important; +} + +.text-info { + color: #0dcaf0 !important; +} + +.text-warning { + color: #ffc107 !important; +} + +.text-danger { + color: #dc3545 !important; +} + +.text-light { + color: #f8f9fa !important; +} + +.text-dark { + color: #212529 !important; +} + +.text-white { + color: #fff !important; +} + +.text-body { + color: #212529 !important; +} + +.text-muted { + color: #6c757d !important; +} + +.text-black-50 { + color: rgba(0, 0, 0, 0.5) !important; +} + +.text-white-50 { + color: rgba(255, 255, 255, 0.5) !important; +} + +.text-reset { + color: inherit !important; +} + +.bg-primary { + background-color: #0d6efd !important; +} + +.bg-secondary { + background-color: #6c757d !important; +} + +.bg-success { + background-color: #198754 !important; +} + +.bg-info { + background-color: #0dcaf0 !important; +} + +.bg-warning { + background-color: #ffc107 !important; +} + +.bg-danger { + background-color: #dc3545 !important; +} + +.bg-light { + background-color: #f8f9fa !important; +} + +.bg-dark { + background-color: #212529 !important; +} + +.bg-body { + background-color: #fff !important; +} + +.bg-white { + background-color: #fff !important; +} + +.bg-transparent { + background-color: transparent !important; +} + +.bg-gradient { + background-image: var(--bs-gradient) !important; +} + +.user-select-all { + -webkit-user-select: all !important; + -moz-user-select: all !important; + user-select: all !important; +} + +.user-select-auto { + -webkit-user-select: auto !important; + -moz-user-select: auto !important; + user-select: auto !important; +} + +.user-select-none { + -webkit-user-select: none !important; + -moz-user-select: none !important; + user-select: none !important; +} + +.pe-none { + pointer-events: none !important; +} + +.pe-auto { + pointer-events: auto !important; +} + +.rounded { + border-radius: 0.25rem !important; +} + +.rounded-0 { + border-radius: 0 !important; +} + +.rounded-1 { + border-radius: 0.2rem !important; +} + +.rounded-2 { + border-radius: 0.25rem !important; +} + +.rounded-3 { + border-radius: 0.3rem !important; +} + +.rounded-circle { + border-radius: 50% !important; +} + +.rounded-pill { + border-radius: 50rem !important; +} + +.rounded-top { + border-top-left-radius: 0.25rem !important; + border-top-right-radius: 0.25rem !important; +} + +.rounded-end { + border-top-right-radius: 0.25rem !important; + border-bottom-right-radius: 0.25rem !important; +} + +.rounded-bottom { + border-bottom-right-radius: 0.25rem !important; + border-bottom-left-radius: 0.25rem !important; +} + +.rounded-start { + border-bottom-left-radius: 0.25rem !important; + border-top-left-radius: 0.25rem !important; +} + +.visible { + visibility: visible !important; +} + +.invisible { + visibility: hidden !important; +} + +@media (min-width: 576px) { + .float-sm-start { + float: left !important; + } + + .float-sm-end { + float: right !important; + } + + .float-sm-none { + float: none !important; + } + + .d-sm-inline { + display: inline !important; + } + + .d-sm-inline-block { + display: inline-block !important; + } + + .d-sm-block { + display: block !important; + } + + .d-sm-grid { + display: grid !important; + } + + .d-sm-table { + display: table !important; + } + + .d-sm-table-row { + display: table-row !important; + } + + .d-sm-table-cell { + display: table-cell !important; + } + + .d-sm-flex { + display: flex !important; + } + + .d-sm-inline-flex { + display: inline-flex !important; + } + + .d-sm-none { + display: none !important; + } + + .flex-sm-fill { + flex: 1 1 auto !important; + } + + .flex-sm-row { + flex-direction: row !important; + } + + .flex-sm-column { + flex-direction: column !important; + } + + .flex-sm-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-sm-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-sm-grow-0 { + flex-grow: 0 !important; + } + + .flex-sm-grow-1 { + flex-grow: 1 !important; + } + + .flex-sm-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-sm-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-sm-wrap { + flex-wrap: wrap !important; + } + + .flex-sm-nowrap { + flex-wrap: nowrap !important; + } + + .flex-sm-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .gap-sm-0 { + gap: 0 !important; + } + + .gap-sm-1 { + gap: 0.25rem !important; + } + + .gap-sm-2 { + gap: 0.5rem !important; + } + + .gap-sm-3 { + gap: 1rem !important; + } + + .gap-sm-4 { + gap: 1.5rem !important; + } + + .gap-sm-5 { + gap: 3rem !important; + } + + .justify-content-sm-start { + justify-content: flex-start !important; + } + + .justify-content-sm-end { + justify-content: flex-end !important; + } + + .justify-content-sm-center { + justify-content: center !important; + } + + .justify-content-sm-between { + justify-content: space-between !important; + } + + .justify-content-sm-around { + justify-content: space-around !important; + } + + .justify-content-sm-evenly { + justify-content: space-evenly !important; + } + + .align-items-sm-start { + align-items: flex-start !important; + } + + .align-items-sm-end { + align-items: flex-end !important; + } + + .align-items-sm-center { + align-items: center !important; + } + + .align-items-sm-baseline { + align-items: baseline !important; + } + + .align-items-sm-stretch { + align-items: stretch !important; + } + + .align-content-sm-start { + align-content: flex-start !important; + } + + .align-content-sm-end { + align-content: flex-end !important; + } + + .align-content-sm-center { + align-content: center !important; + } + + .align-content-sm-between { + align-content: space-between !important; + } + + .align-content-sm-around { + align-content: space-around !important; + } + + .align-content-sm-stretch { + align-content: stretch !important; + } + + .align-self-sm-auto { + align-self: auto !important; + } + + .align-self-sm-start { + align-self: flex-start !important; + } + + .align-self-sm-end { + align-self: flex-end !important; + } + + .align-self-sm-center { + align-self: center !important; + } + + .align-self-sm-baseline { + align-self: baseline !important; + } + + .align-self-sm-stretch { + align-self: stretch !important; + } + + .order-sm-first { + order: -1 !important; + } + + .order-sm-0 { + order: 0 !important; + } + + .order-sm-1 { + order: 1 !important; + } + + .order-sm-2 { + order: 2 !important; + } + + .order-sm-3 { + order: 3 !important; + } + + .order-sm-4 { + order: 4 !important; + } + + .order-sm-5 { + order: 5 !important; + } + + .order-sm-last { + order: 6 !important; + } + + .m-sm-0 { + margin: 0 !important; + } + + .m-sm-1 { + margin: 0.25rem !important; + } + + .m-sm-2 { + margin: 0.5rem !important; + } + + .m-sm-3 { + margin: 1rem !important; + } + + .m-sm-4 { + margin: 1.5rem !important; + } + + .m-sm-5 { + margin: 3rem !important; + } + + .m-sm-auto { + margin: auto !important; + } + + .mx-sm-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + + .mx-sm-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + + .mx-sm-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + + .mx-sm-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + + .mx-sm-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + + .mx-sm-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + + .mx-sm-auto { + margin-right: auto !important; + margin-left: auto !important; + } + + .my-sm-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + + .my-sm-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + + .my-sm-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + + .my-sm-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + + .my-sm-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + + .my-sm-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + + .my-sm-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + + .mt-sm-0 { + margin-top: 0 !important; + } + + .mt-sm-1 { + margin-top: 0.25rem !important; + } + + .mt-sm-2 { + margin-top: 0.5rem !important; + } + + .mt-sm-3 { + margin-top: 1rem !important; + } + + .mt-sm-4 { + margin-top: 1.5rem !important; + } + + .mt-sm-5 { + margin-top: 3rem !important; + } + + .mt-sm-auto { + margin-top: auto !important; + } + + .me-sm-0 { + margin-right: 0 !important; + } + + .me-sm-1 { + margin-right: 0.25rem !important; + } + + .me-sm-2 { + margin-right: 0.5rem !important; + } + + .me-sm-3 { + margin-right: 1rem !important; + } + + .me-sm-4 { + margin-right: 1.5rem !important; + } + + .me-sm-5 { + margin-right: 3rem !important; + } + + .me-sm-auto { + margin-right: auto !important; + } + + .mb-sm-0 { + margin-bottom: 0 !important; + } + + .mb-sm-1 { + margin-bottom: 0.25rem !important; + } + + .mb-sm-2 { + margin-bottom: 0.5rem !important; + } + + .mb-sm-3 { + margin-bottom: 1rem !important; + } + + .mb-sm-4 { + margin-bottom: 1.5rem !important; + } + + .mb-sm-5 { + margin-bottom: 3rem !important; + } + + .mb-sm-auto { + margin-bottom: auto !important; + } + + .ms-sm-0 { + margin-left: 0 !important; + } + + .ms-sm-1 { + margin-left: 0.25rem !important; + } + + .ms-sm-2 { + margin-left: 0.5rem !important; + } + + .ms-sm-3 { + margin-left: 1rem !important; + } + + .ms-sm-4 { + margin-left: 1.5rem !important; + } + + .ms-sm-5 { + margin-left: 3rem !important; + } + + .ms-sm-auto { + margin-left: auto !important; + } + + .p-sm-0 { + padding: 0 !important; + } + + .p-sm-1 { + padding: 0.25rem !important; + } + + .p-sm-2 { + padding: 0.5rem !important; + } + + .p-sm-3 { + padding: 1rem !important; + } + + .p-sm-4 { + padding: 1.5rem !important; + } + + .p-sm-5 { + padding: 3rem !important; + } + + .px-sm-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + + .px-sm-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + + .px-sm-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + + .px-sm-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + + .px-sm-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + + .px-sm-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + + .py-sm-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + + .py-sm-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + + .py-sm-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + + .py-sm-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + + .py-sm-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + + .py-sm-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + + .pt-sm-0 { + padding-top: 0 !important; + } + + .pt-sm-1 { + padding-top: 0.25rem !important; + } + + .pt-sm-2 { + padding-top: 0.5rem !important; + } + + .pt-sm-3 { + padding-top: 1rem !important; + } + + .pt-sm-4 { + padding-top: 1.5rem !important; + } + + .pt-sm-5 { + padding-top: 3rem !important; + } + + .pe-sm-0 { + padding-right: 0 !important; + } + + .pe-sm-1 { + padding-right: 0.25rem !important; + } + + .pe-sm-2 { + padding-right: 0.5rem !important; + } + + .pe-sm-3 { + padding-right: 1rem !important; + } + + .pe-sm-4 { + padding-right: 1.5rem !important; + } + + .pe-sm-5 { + padding-right: 3rem !important; + } + + .pb-sm-0 { + padding-bottom: 0 !important; + } + + .pb-sm-1 { + padding-bottom: 0.25rem !important; + } + + .pb-sm-2 { + padding-bottom: 0.5rem !important; + } + + .pb-sm-3 { + padding-bottom: 1rem !important; + } + + .pb-sm-4 { + padding-bottom: 1.5rem !important; + } + + .pb-sm-5 { + padding-bottom: 3rem !important; + } + + .ps-sm-0 { + padding-left: 0 !important; + } + + .ps-sm-1 { + padding-left: 0.25rem !important; + } + + .ps-sm-2 { + padding-left: 0.5rem !important; + } + + .ps-sm-3 { + padding-left: 1rem !important; + } + + .ps-sm-4 { + padding-left: 1.5rem !important; + } + + .ps-sm-5 { + padding-left: 3rem !important; + } + + .text-sm-start { + text-align: left !important; + } + + .text-sm-end { + text-align: right !important; + } + + .text-sm-center { + text-align: center !important; + } +} +@media (min-width: 768px) { + .float-md-start { + float: left !important; + } + + .float-md-end { + float: right !important; + } + + .float-md-none { + float: none !important; + } + + .d-md-inline { + display: inline !important; + } + + .d-md-inline-block { + display: inline-block !important; + } + + .d-md-block { + display: block !important; + } + + .d-md-grid { + display: grid !important; + } + + .d-md-table { + display: table !important; + } + + .d-md-table-row { + display: table-row !important; + } + + .d-md-table-cell { + display: table-cell !important; + } + + .d-md-flex { + display: flex !important; + } + + .d-md-inline-flex { + display: inline-flex !important; + } + + .d-md-none { + display: none !important; + } + + .flex-md-fill { + flex: 1 1 auto !important; + } + + .flex-md-row { + flex-direction: row !important; + } + + .flex-md-column { + flex-direction: column !important; + } + + .flex-md-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-md-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-md-grow-0 { + flex-grow: 0 !important; + } + + .flex-md-grow-1 { + flex-grow: 1 !important; + } + + .flex-md-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-md-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-md-wrap { + flex-wrap: wrap !important; + } + + .flex-md-nowrap { + flex-wrap: nowrap !important; + } + + .flex-md-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .gap-md-0 { + gap: 0 !important; + } + + .gap-md-1 { + gap: 0.25rem !important; + } + + .gap-md-2 { + gap: 0.5rem !important; + } + + .gap-md-3 { + gap: 1rem !important; + } + + .gap-md-4 { + gap: 1.5rem !important; + } + + .gap-md-5 { + gap: 3rem !important; + } + + .justify-content-md-start { + justify-content: flex-start !important; + } + + .justify-content-md-end { + justify-content: flex-end !important; + } + + .justify-content-md-center { + justify-content: center !important; + } + + .justify-content-md-between { + justify-content: space-between !important; + } + + .justify-content-md-around { + justify-content: space-around !important; + } + + .justify-content-md-evenly { + justify-content: space-evenly !important; + } + + .align-items-md-start { + align-items: flex-start !important; + } + + .align-items-md-end { + align-items: flex-end !important; + } + + .align-items-md-center { + align-items: center !important; + } + + .align-items-md-baseline { + align-items: baseline !important; + } + + .align-items-md-stretch { + align-items: stretch !important; + } + + .align-content-md-start { + align-content: flex-start !important; + } + + .align-content-md-end { + align-content: flex-end !important; + } + + .align-content-md-center { + align-content: center !important; + } + + .align-content-md-between { + align-content: space-between !important; + } + + .align-content-md-around { + align-content: space-around !important; + } + + .align-content-md-stretch { + align-content: stretch !important; + } + + .align-self-md-auto { + align-self: auto !important; + } + + .align-self-md-start { + align-self: flex-start !important; + } + + .align-self-md-end { + align-self: flex-end !important; + } + + .align-self-md-center { + align-self: center !important; + } + + .align-self-md-baseline { + align-self: baseline !important; + } + + .align-self-md-stretch { + align-self: stretch !important; + } + + .order-md-first { + order: -1 !important; + } + + .order-md-0 { + order: 0 !important; + } + + .order-md-1 { + order: 1 !important; + } + + .order-md-2 { + order: 2 !important; + } + + .order-md-3 { + order: 3 !important; + } + + .order-md-4 { + order: 4 !important; + } + + .order-md-5 { + order: 5 !important; + } + + .order-md-last { + order: 6 !important; + } + + .m-md-0 { + margin: 0 !important; + } + + .m-md-1 { + margin: 0.25rem !important; + } + + .m-md-2 { + margin: 0.5rem !important; + } + + .m-md-3 { + margin: 1rem !important; + } + + .m-md-4 { + margin: 1.5rem !important; + } + + .m-md-5 { + margin: 3rem !important; + } + + .m-md-auto { + margin: auto !important; + } + + .mx-md-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + + .mx-md-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + + .mx-md-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + + .mx-md-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + + .mx-md-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + + .mx-md-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + + .mx-md-auto { + margin-right: auto !important; + margin-left: auto !important; + } + + .my-md-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + + .my-md-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + + .my-md-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + + .my-md-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + + .my-md-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + + .my-md-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + + .my-md-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + + .mt-md-0 { + margin-top: 0 !important; + } + + .mt-md-1 { + margin-top: 0.25rem !important; + } + + .mt-md-2 { + margin-top: 0.5rem !important; + } + + .mt-md-3 { + margin-top: 1rem !important; + } + + .mt-md-4 { + margin-top: 1.5rem !important; + } + + .mt-md-5 { + margin-top: 3rem !important; + } + + .mt-md-auto { + margin-top: auto !important; + } + + .me-md-0 { + margin-right: 0 !important; + } + + .me-md-1 { + margin-right: 0.25rem !important; + } + + .me-md-2 { + margin-right: 0.5rem !important; + } + + .me-md-3 { + margin-right: 1rem !important; + } + + .me-md-4 { + margin-right: 1.5rem !important; + } + + .me-md-5 { + margin-right: 3rem !important; + } + + .me-md-auto { + margin-right: auto !important; + } + + .mb-md-0 { + margin-bottom: 0 !important; + } + + .mb-md-1 { + margin-bottom: 0.25rem !important; + } + + .mb-md-2 { + margin-bottom: 0.5rem !important; + } + + .mb-md-3 { + margin-bottom: 1rem !important; + } + + .mb-md-4 { + margin-bottom: 1.5rem !important; + } + + .mb-md-5 { + margin-bottom: 3rem !important; + } + + .mb-md-auto { + margin-bottom: auto !important; + } + + .ms-md-0 { + margin-left: 0 !important; + } + + .ms-md-1 { + margin-left: 0.25rem !important; + } + + .ms-md-2 { + margin-left: 0.5rem !important; + } + + .ms-md-3 { + margin-left: 1rem !important; + } + + .ms-md-4 { + margin-left: 1.5rem !important; + } + + .ms-md-5 { + margin-left: 3rem !important; + } + + .ms-md-auto { + margin-left: auto !important; + } + + .p-md-0 { + padding: 0 !important; + } + + .p-md-1 { + padding: 0.25rem !important; + } + + .p-md-2 { + padding: 0.5rem !important; + } + + .p-md-3 { + padding: 1rem !important; + } + + .p-md-4 { + padding: 1.5rem !important; + } + + .p-md-5 { + padding: 3rem !important; + } + + .px-md-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + + .px-md-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + + .px-md-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + + .px-md-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + + .px-md-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + + .px-md-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + + .py-md-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + + .py-md-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + + .py-md-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + + .py-md-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + + .py-md-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + + .py-md-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + + .pt-md-0 { + padding-top: 0 !important; + } + + .pt-md-1 { + padding-top: 0.25rem !important; + } + + .pt-md-2 { + padding-top: 0.5rem !important; + } + + .pt-md-3 { + padding-top: 1rem !important; + } + + .pt-md-4 { + padding-top: 1.5rem !important; + } + + .pt-md-5 { + padding-top: 3rem !important; + } + + .pe-md-0 { + padding-right: 0 !important; + } + + .pe-md-1 { + padding-right: 0.25rem !important; + } + + .pe-md-2 { + padding-right: 0.5rem !important; + } + + .pe-md-3 { + padding-right: 1rem !important; + } + + .pe-md-4 { + padding-right: 1.5rem !important; + } + + .pe-md-5 { + padding-right: 3rem !important; + } + + .pb-md-0 { + padding-bottom: 0 !important; + } + + .pb-md-1 { + padding-bottom: 0.25rem !important; + } + + .pb-md-2 { + padding-bottom: 0.5rem !important; + } + + .pb-md-3 { + padding-bottom: 1rem !important; + } + + .pb-md-4 { + padding-bottom: 1.5rem !important; + } + + .pb-md-5 { + padding-bottom: 3rem !important; + } + + .ps-md-0 { + padding-left: 0 !important; + } + + .ps-md-1 { + padding-left: 0.25rem !important; + } + + .ps-md-2 { + padding-left: 0.5rem !important; + } + + .ps-md-3 { + padding-left: 1rem !important; + } + + .ps-md-4 { + padding-left: 1.5rem !important; + } + + .ps-md-5 { + padding-left: 3rem !important; + } + + .text-md-start { + text-align: left !important; + } + + .text-md-end { + text-align: right !important; + } + + .text-md-center { + text-align: center !important; + } +} +@media (min-width: 992px) { + .float-lg-start { + float: left !important; + } + + .float-lg-end { + float: right !important; + } + + .float-lg-none { + float: none !important; + } + + .d-lg-inline { + display: inline !important; + } + + .d-lg-inline-block { + display: inline-block !important; + } + + .d-lg-block { + display: block !important; + } + + .d-lg-grid { + display: grid !important; + } + + .d-lg-table { + display: table !important; + } + + .d-lg-table-row { + display: table-row !important; + } + + .d-lg-table-cell { + display: table-cell !important; + } + + .d-lg-flex { + display: flex !important; + } + + .d-lg-inline-flex { + display: inline-flex !important; + } + + .d-lg-none { + display: none !important; + } + + .flex-lg-fill { + flex: 1 1 auto !important; + } + + .flex-lg-row { + flex-direction: row !important; + } + + .flex-lg-column { + flex-direction: column !important; + } + + .flex-lg-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-lg-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-lg-grow-0 { + flex-grow: 0 !important; + } + + .flex-lg-grow-1 { + flex-grow: 1 !important; + } + + .flex-lg-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-lg-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-lg-wrap { + flex-wrap: wrap !important; + } + + .flex-lg-nowrap { + flex-wrap: nowrap !important; + } + + .flex-lg-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .gap-lg-0 { + gap: 0 !important; + } + + .gap-lg-1 { + gap: 0.25rem !important; + } + + .gap-lg-2 { + gap: 0.5rem !important; + } + + .gap-lg-3 { + gap: 1rem !important; + } + + .gap-lg-4 { + gap: 1.5rem !important; + } + + .gap-lg-5 { + gap: 3rem !important; + } + + .justify-content-lg-start { + justify-content: flex-start !important; + } + + .justify-content-lg-end { + justify-content: flex-end !important; + } + + .justify-content-lg-center { + justify-content: center !important; + } + + .justify-content-lg-between { + justify-content: space-between !important; + } + + .justify-content-lg-around { + justify-content: space-around !important; + } + + .justify-content-lg-evenly { + justify-content: space-evenly !important; + } + + .align-items-lg-start { + align-items: flex-start !important; + } + + .align-items-lg-end { + align-items: flex-end !important; + } + + .align-items-lg-center { + align-items: center !important; + } + + .align-items-lg-baseline { + align-items: baseline !important; + } + + .align-items-lg-stretch { + align-items: stretch !important; + } + + .align-content-lg-start { + align-content: flex-start !important; + } + + .align-content-lg-end { + align-content: flex-end !important; + } + + .align-content-lg-center { + align-content: center !important; + } + + .align-content-lg-between { + align-content: space-between !important; + } + + .align-content-lg-around { + align-content: space-around !important; + } + + .align-content-lg-stretch { + align-content: stretch !important; + } + + .align-self-lg-auto { + align-self: auto !important; + } + + .align-self-lg-start { + align-self: flex-start !important; + } + + .align-self-lg-end { + align-self: flex-end !important; + } + + .align-self-lg-center { + align-self: center !important; + } + + .align-self-lg-baseline { + align-self: baseline !important; + } + + .align-self-lg-stretch { + align-self: stretch !important; + } + + .order-lg-first { + order: -1 !important; + } + + .order-lg-0 { + order: 0 !important; + } + + .order-lg-1 { + order: 1 !important; + } + + .order-lg-2 { + order: 2 !important; + } + + .order-lg-3 { + order: 3 !important; + } + + .order-lg-4 { + order: 4 !important; + } + + .order-lg-5 { + order: 5 !important; + } + + .order-lg-last { + order: 6 !important; + } + + .m-lg-0 { + margin: 0 !important; + } + + .m-lg-1 { + margin: 0.25rem !important; + } + + .m-lg-2 { + margin: 0.5rem !important; + } + + .m-lg-3 { + margin: 1rem !important; + } + + .m-lg-4 { + margin: 1.5rem !important; + } + + .m-lg-5 { + margin: 3rem !important; + } + + .m-lg-auto { + margin: auto !important; + } + + .mx-lg-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + + .mx-lg-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + + .mx-lg-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + + .mx-lg-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + + .mx-lg-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + + .mx-lg-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + + .mx-lg-auto { + margin-right: auto !important; + margin-left: auto !important; + } + + .my-lg-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + + .my-lg-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + + .my-lg-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + + .my-lg-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + + .my-lg-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + + .my-lg-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + + .my-lg-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + + .mt-lg-0 { + margin-top: 0 !important; + } + + .mt-lg-1 { + margin-top: 0.25rem !important; + } + + .mt-lg-2 { + margin-top: 0.5rem !important; + } + + .mt-lg-3 { + margin-top: 1rem !important; + } + + .mt-lg-4 { + margin-top: 1.5rem !important; + } + + .mt-lg-5 { + margin-top: 3rem !important; + } + + .mt-lg-auto { + margin-top: auto !important; + } + + .me-lg-0 { + margin-right: 0 !important; + } + + .me-lg-1 { + margin-right: 0.25rem !important; + } + + .me-lg-2 { + margin-right: 0.5rem !important; + } + + .me-lg-3 { + margin-right: 1rem !important; + } + + .me-lg-4 { + margin-right: 1.5rem !important; + } + + .me-lg-5 { + margin-right: 3rem !important; + } + + .me-lg-auto { + margin-right: auto !important; + } + + .mb-lg-0 { + margin-bottom: 0 !important; + } + + .mb-lg-1 { + margin-bottom: 0.25rem !important; + } + + .mb-lg-2 { + margin-bottom: 0.5rem !important; + } + + .mb-lg-3 { + margin-bottom: 1rem !important; + } + + .mb-lg-4 { + margin-bottom: 1.5rem !important; + } + + .mb-lg-5 { + margin-bottom: 3rem !important; + } + + .mb-lg-auto { + margin-bottom: auto !important; + } + + .ms-lg-0 { + margin-left: 0 !important; + } + + .ms-lg-1 { + margin-left: 0.25rem !important; + } + + .ms-lg-2 { + margin-left: 0.5rem !important; + } + + .ms-lg-3 { + margin-left: 1rem !important; + } + + .ms-lg-4 { + margin-left: 1.5rem !important; + } + + .ms-lg-5 { + margin-left: 3rem !important; + } + + .ms-lg-auto { + margin-left: auto !important; + } + + .p-lg-0 { + padding: 0 !important; + } + + .p-lg-1 { + padding: 0.25rem !important; + } + + .p-lg-2 { + padding: 0.5rem !important; + } + + .p-lg-3 { + padding: 1rem !important; + } + + .p-lg-4 { + padding: 1.5rem !important; + } + + .p-lg-5 { + padding: 3rem !important; + } + + .px-lg-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + + .px-lg-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + + .px-lg-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + + .px-lg-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + + .px-lg-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + + .px-lg-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + + .py-lg-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + + .py-lg-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + + .py-lg-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + + .py-lg-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + + .py-lg-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + + .py-lg-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + + .pt-lg-0 { + padding-top: 0 !important; + } + + .pt-lg-1 { + padding-top: 0.25rem !important; + } + + .pt-lg-2 { + padding-top: 0.5rem !important; + } + + .pt-lg-3 { + padding-top: 1rem !important; + } + + .pt-lg-4 { + padding-top: 1.5rem !important; + } + + .pt-lg-5 { + padding-top: 3rem !important; + } + + .pe-lg-0 { + padding-right: 0 !important; + } + + .pe-lg-1 { + padding-right: 0.25rem !important; + } + + .pe-lg-2 { + padding-right: 0.5rem !important; + } + + .pe-lg-3 { + padding-right: 1rem !important; + } + + .pe-lg-4 { + padding-right: 1.5rem !important; + } + + .pe-lg-5 { + padding-right: 3rem !important; + } + + .pb-lg-0 { + padding-bottom: 0 !important; + } + + .pb-lg-1 { + padding-bottom: 0.25rem !important; + } + + .pb-lg-2 { + padding-bottom: 0.5rem !important; + } + + .pb-lg-3 { + padding-bottom: 1rem !important; + } + + .pb-lg-4 { + padding-bottom: 1.5rem !important; + } + + .pb-lg-5 { + padding-bottom: 3rem !important; + } + + .ps-lg-0 { + padding-left: 0 !important; + } + + .ps-lg-1 { + padding-left: 0.25rem !important; + } + + .ps-lg-2 { + padding-left: 0.5rem !important; + } + + .ps-lg-3 { + padding-left: 1rem !important; + } + + .ps-lg-4 { + padding-left: 1.5rem !important; + } + + .ps-lg-5 { + padding-left: 3rem !important; + } + + .text-lg-start { + text-align: left !important; + } + + .text-lg-end { + text-align: right !important; + } + + .text-lg-center { + text-align: center !important; + } +} +@media (min-width: 1200px) { + .float-xl-start { + float: left !important; + } + + .float-xl-end { + float: right !important; + } + + .float-xl-none { + float: none !important; + } + + .d-xl-inline { + display: inline !important; + } + + .d-xl-inline-block { + display: inline-block !important; + } + + .d-xl-block { + display: block !important; + } + + .d-xl-grid { + display: grid !important; + } + + .d-xl-table { + display: table !important; + } + + .d-xl-table-row { + display: table-row !important; + } + + .d-xl-table-cell { + display: table-cell !important; + } + + .d-xl-flex { + display: flex !important; + } + + .d-xl-inline-flex { + display: inline-flex !important; + } + + .d-xl-none { + display: none !important; + } + + .flex-xl-fill { + flex: 1 1 auto !important; + } + + .flex-xl-row { + flex-direction: row !important; + } + + .flex-xl-column { + flex-direction: column !important; + } + + .flex-xl-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-xl-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-xl-grow-0 { + flex-grow: 0 !important; + } + + .flex-xl-grow-1 { + flex-grow: 1 !important; + } + + .flex-xl-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-xl-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-xl-wrap { + flex-wrap: wrap !important; + } + + .flex-xl-nowrap { + flex-wrap: nowrap !important; + } + + .flex-xl-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .gap-xl-0 { + gap: 0 !important; + } + + .gap-xl-1 { + gap: 0.25rem !important; + } + + .gap-xl-2 { + gap: 0.5rem !important; + } + + .gap-xl-3 { + gap: 1rem !important; + } + + .gap-xl-4 { + gap: 1.5rem !important; + } + + .gap-xl-5 { + gap: 3rem !important; + } + + .justify-content-xl-start { + justify-content: flex-start !important; + } + + .justify-content-xl-end { + justify-content: flex-end !important; + } + + .justify-content-xl-center { + justify-content: center !important; + } + + .justify-content-xl-between { + justify-content: space-between !important; + } + + .justify-content-xl-around { + justify-content: space-around !important; + } + + .justify-content-xl-evenly { + justify-content: space-evenly !important; + } + + .align-items-xl-start { + align-items: flex-start !important; + } + + .align-items-xl-end { + align-items: flex-end !important; + } + + .align-items-xl-center { + align-items: center !important; + } + + .align-items-xl-baseline { + align-items: baseline !important; + } + + .align-items-xl-stretch { + align-items: stretch !important; + } + + .align-content-xl-start { + align-content: flex-start !important; + } + + .align-content-xl-end { + align-content: flex-end !important; + } + + .align-content-xl-center { + align-content: center !important; + } + + .align-content-xl-between { + align-content: space-between !important; + } + + .align-content-xl-around { + align-content: space-around !important; + } + + .align-content-xl-stretch { + align-content: stretch !important; + } + + .align-self-xl-auto { + align-self: auto !important; + } + + .align-self-xl-start { + align-self: flex-start !important; + } + + .align-self-xl-end { + align-self: flex-end !important; + } + + .align-self-xl-center { + align-self: center !important; + } + + .align-self-xl-baseline { + align-self: baseline !important; + } + + .align-self-xl-stretch { + align-self: stretch !important; + } + + .order-xl-first { + order: -1 !important; + } + + .order-xl-0 { + order: 0 !important; + } + + .order-xl-1 { + order: 1 !important; + } + + .order-xl-2 { + order: 2 !important; + } + + .order-xl-3 { + order: 3 !important; + } + + .order-xl-4 { + order: 4 !important; + } + + .order-xl-5 { + order: 5 !important; + } + + .order-xl-last { + order: 6 !important; + } + + .m-xl-0 { + margin: 0 !important; + } + + .m-xl-1 { + margin: 0.25rem !important; + } + + .m-xl-2 { + margin: 0.5rem !important; + } + + .m-xl-3 { + margin: 1rem !important; + } + + .m-xl-4 { + margin: 1.5rem !important; + } + + .m-xl-5 { + margin: 3rem !important; + } + + .m-xl-auto { + margin: auto !important; + } + + .mx-xl-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + + .mx-xl-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + + .mx-xl-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + + .mx-xl-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + + .mx-xl-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + + .mx-xl-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + + .mx-xl-auto { + margin-right: auto !important; + margin-left: auto !important; + } + + .my-xl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + + .my-xl-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + + .my-xl-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + + .my-xl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + + .my-xl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + + .my-xl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + + .my-xl-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + + .mt-xl-0 { + margin-top: 0 !important; + } + + .mt-xl-1 { + margin-top: 0.25rem !important; + } + + .mt-xl-2 { + margin-top: 0.5rem !important; + } + + .mt-xl-3 { + margin-top: 1rem !important; + } + + .mt-xl-4 { + margin-top: 1.5rem !important; + } + + .mt-xl-5 { + margin-top: 3rem !important; + } + + .mt-xl-auto { + margin-top: auto !important; + } + + .me-xl-0 { + margin-right: 0 !important; + } + + .me-xl-1 { + margin-right: 0.25rem !important; + } + + .me-xl-2 { + margin-right: 0.5rem !important; + } + + .me-xl-3 { + margin-right: 1rem !important; + } + + .me-xl-4 { + margin-right: 1.5rem !important; + } + + .me-xl-5 { + margin-right: 3rem !important; + } + + .me-xl-auto { + margin-right: auto !important; + } + + .mb-xl-0 { + margin-bottom: 0 !important; + } + + .mb-xl-1 { + margin-bottom: 0.25rem !important; + } + + .mb-xl-2 { + margin-bottom: 0.5rem !important; + } + + .mb-xl-3 { + margin-bottom: 1rem !important; + } + + .mb-xl-4 { + margin-bottom: 1.5rem !important; + } + + .mb-xl-5 { + margin-bottom: 3rem !important; + } + + .mb-xl-auto { + margin-bottom: auto !important; + } + + .ms-xl-0 { + margin-left: 0 !important; + } + + .ms-xl-1 { + margin-left: 0.25rem !important; + } + + .ms-xl-2 { + margin-left: 0.5rem !important; + } + + .ms-xl-3 { + margin-left: 1rem !important; + } + + .ms-xl-4 { + margin-left: 1.5rem !important; + } + + .ms-xl-5 { + margin-left: 3rem !important; + } + + .ms-xl-auto { + margin-left: auto !important; + } + + .p-xl-0 { + padding: 0 !important; + } + + .p-xl-1 { + padding: 0.25rem !important; + } + + .p-xl-2 { + padding: 0.5rem !important; + } + + .p-xl-3 { + padding: 1rem !important; + } + + .p-xl-4 { + padding: 1.5rem !important; + } + + .p-xl-5 { + padding: 3rem !important; + } + + .px-xl-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + + .px-xl-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + + .px-xl-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + + .px-xl-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + + .px-xl-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + + .px-xl-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + + .py-xl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + + .py-xl-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + + .py-xl-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + + .py-xl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + + .py-xl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + + .py-xl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + + .pt-xl-0 { + padding-top: 0 !important; + } + + .pt-xl-1 { + padding-top: 0.25rem !important; + } + + .pt-xl-2 { + padding-top: 0.5rem !important; + } + + .pt-xl-3 { + padding-top: 1rem !important; + } + + .pt-xl-4 { + padding-top: 1.5rem !important; + } + + .pt-xl-5 { + padding-top: 3rem !important; + } + + .pe-xl-0 { + padding-right: 0 !important; + } + + .pe-xl-1 { + padding-right: 0.25rem !important; + } + + .pe-xl-2 { + padding-right: 0.5rem !important; + } + + .pe-xl-3 { + padding-right: 1rem !important; + } + + .pe-xl-4 { + padding-right: 1.5rem !important; + } + + .pe-xl-5 { + padding-right: 3rem !important; + } + + .pb-xl-0 { + padding-bottom: 0 !important; + } + + .pb-xl-1 { + padding-bottom: 0.25rem !important; + } + + .pb-xl-2 { + padding-bottom: 0.5rem !important; + } + + .pb-xl-3 { + padding-bottom: 1rem !important; + } + + .pb-xl-4 { + padding-bottom: 1.5rem !important; + } + + .pb-xl-5 { + padding-bottom: 3rem !important; + } + + .ps-xl-0 { + padding-left: 0 !important; + } + + .ps-xl-1 { + padding-left: 0.25rem !important; + } + + .ps-xl-2 { + padding-left: 0.5rem !important; + } + + .ps-xl-3 { + padding-left: 1rem !important; + } + + .ps-xl-4 { + padding-left: 1.5rem !important; + } + + .ps-xl-5 { + padding-left: 3rem !important; + } + + .text-xl-start { + text-align: left !important; + } + + .text-xl-end { + text-align: right !important; + } + + .text-xl-center { + text-align: center !important; + } +} +@media (min-width: 1400px) { + .float-xxl-start { + float: left !important; + } + + .float-xxl-end { + float: right !important; + } + + .float-xxl-none { + float: none !important; + } + + .d-xxl-inline { + display: inline !important; + } + + .d-xxl-inline-block { + display: inline-block !important; + } + + .d-xxl-block { + display: block !important; + } + + .d-xxl-grid { + display: grid !important; + } + + .d-xxl-table { + display: table !important; + } + + .d-xxl-table-row { + display: table-row !important; + } + + .d-xxl-table-cell { + display: table-cell !important; + } + + .d-xxl-flex { + display: flex !important; + } + + .d-xxl-inline-flex { + display: inline-flex !important; + } + + .d-xxl-none { + display: none !important; + } + + .flex-xxl-fill { + flex: 1 1 auto !important; + } + + .flex-xxl-row { + flex-direction: row !important; + } + + .flex-xxl-column { + flex-direction: column !important; + } + + .flex-xxl-row-reverse { + flex-direction: row-reverse !important; + } + + .flex-xxl-column-reverse { + flex-direction: column-reverse !important; + } + + .flex-xxl-grow-0 { + flex-grow: 0 !important; + } + + .flex-xxl-grow-1 { + flex-grow: 1 !important; + } + + .flex-xxl-shrink-0 { + flex-shrink: 0 !important; + } + + .flex-xxl-shrink-1 { + flex-shrink: 1 !important; + } + + .flex-xxl-wrap { + flex-wrap: wrap !important; + } + + .flex-xxl-nowrap { + flex-wrap: nowrap !important; + } + + .flex-xxl-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + + .gap-xxl-0 { + gap: 0 !important; + } + + .gap-xxl-1 { + gap: 0.25rem !important; + } + + .gap-xxl-2 { + gap: 0.5rem !important; + } + + .gap-xxl-3 { + gap: 1rem !important; + } + + .gap-xxl-4 { + gap: 1.5rem !important; + } + + .gap-xxl-5 { + gap: 3rem !important; + } + + .justify-content-xxl-start { + justify-content: flex-start !important; + } + + .justify-content-xxl-end { + justify-content: flex-end !important; + } + + .justify-content-xxl-center { + justify-content: center !important; + } + + .justify-content-xxl-between { + justify-content: space-between !important; + } + + .justify-content-xxl-around { + justify-content: space-around !important; + } + + .justify-content-xxl-evenly { + justify-content: space-evenly !important; + } + + .align-items-xxl-start { + align-items: flex-start !important; + } + + .align-items-xxl-end { + align-items: flex-end !important; + } + + .align-items-xxl-center { + align-items: center !important; + } + + .align-items-xxl-baseline { + align-items: baseline !important; + } + + .align-items-xxl-stretch { + align-items: stretch !important; + } + + .align-content-xxl-start { + align-content: flex-start !important; + } + + .align-content-xxl-end { + align-content: flex-end !important; + } + + .align-content-xxl-center { + align-content: center !important; + } + + .align-content-xxl-between { + align-content: space-between !important; + } + + .align-content-xxl-around { + align-content: space-around !important; + } + + .align-content-xxl-stretch { + align-content: stretch !important; + } + + .align-self-xxl-auto { + align-self: auto !important; + } + + .align-self-xxl-start { + align-self: flex-start !important; + } + + .align-self-xxl-end { + align-self: flex-end !important; + } + + .align-self-xxl-center { + align-self: center !important; + } + + .align-self-xxl-baseline { + align-self: baseline !important; + } + + .align-self-xxl-stretch { + align-self: stretch !important; + } + + .order-xxl-first { + order: -1 !important; + } + + .order-xxl-0 { + order: 0 !important; + } + + .order-xxl-1 { + order: 1 !important; + } + + .order-xxl-2 { + order: 2 !important; + } + + .order-xxl-3 { + order: 3 !important; + } + + .order-xxl-4 { + order: 4 !important; + } + + .order-xxl-5 { + order: 5 !important; + } + + .order-xxl-last { + order: 6 !important; + } + + .m-xxl-0 { + margin: 0 !important; + } + + .m-xxl-1 { + margin: 0.25rem !important; + } + + .m-xxl-2 { + margin: 0.5rem !important; + } + + .m-xxl-3 { + margin: 1rem !important; + } + + .m-xxl-4 { + margin: 1.5rem !important; + } + + .m-xxl-5 { + margin: 3rem !important; + } + + .m-xxl-auto { + margin: auto !important; + } + + .mx-xxl-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + + .mx-xxl-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + + .mx-xxl-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + + .mx-xxl-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + + .mx-xxl-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + + .mx-xxl-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + + .mx-xxl-auto { + margin-right: auto !important; + margin-left: auto !important; + } + + .my-xxl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + + .my-xxl-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + + .my-xxl-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + + .my-xxl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + + .my-xxl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + + .my-xxl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + + .my-xxl-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + + .mt-xxl-0 { + margin-top: 0 !important; + } + + .mt-xxl-1 { + margin-top: 0.25rem !important; + } + + .mt-xxl-2 { + margin-top: 0.5rem !important; + } + + .mt-xxl-3 { + margin-top: 1rem !important; + } + + .mt-xxl-4 { + margin-top: 1.5rem !important; + } + + .mt-xxl-5 { + margin-top: 3rem !important; + } + + .mt-xxl-auto { + margin-top: auto !important; + } + + .me-xxl-0 { + margin-right: 0 !important; + } + + .me-xxl-1 { + margin-right: 0.25rem !important; + } + + .me-xxl-2 { + margin-right: 0.5rem !important; + } + + .me-xxl-3 { + margin-right: 1rem !important; + } + + .me-xxl-4 { + margin-right: 1.5rem !important; + } + + .me-xxl-5 { + margin-right: 3rem !important; + } + + .me-xxl-auto { + margin-right: auto !important; + } + + .mb-xxl-0 { + margin-bottom: 0 !important; + } + + .mb-xxl-1 { + margin-bottom: 0.25rem !important; + } + + .mb-xxl-2 { + margin-bottom: 0.5rem !important; + } + + .mb-xxl-3 { + margin-bottom: 1rem !important; + } + + .mb-xxl-4 { + margin-bottom: 1.5rem !important; + } + + .mb-xxl-5 { + margin-bottom: 3rem !important; + } + + .mb-xxl-auto { + margin-bottom: auto !important; + } + + .ms-xxl-0 { + margin-left: 0 !important; + } + + .ms-xxl-1 { + margin-left: 0.25rem !important; + } + + .ms-xxl-2 { + margin-left: 0.5rem !important; + } + + .ms-xxl-3 { + margin-left: 1rem !important; + } + + .ms-xxl-4 { + margin-left: 1.5rem !important; + } + + .ms-xxl-5 { + margin-left: 3rem !important; + } + + .ms-xxl-auto { + margin-left: auto !important; + } + + .p-xxl-0 { + padding: 0 !important; + } + + .p-xxl-1 { + padding: 0.25rem !important; + } + + .p-xxl-2 { + padding: 0.5rem !important; + } + + .p-xxl-3 { + padding: 1rem !important; + } + + .p-xxl-4 { + padding: 1.5rem !important; + } + + .p-xxl-5 { + padding: 3rem !important; + } + + .px-xxl-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + + .px-xxl-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + + .px-xxl-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + + .px-xxl-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + + .px-xxl-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + + .px-xxl-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + + .py-xxl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + + .py-xxl-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + + .py-xxl-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + + .py-xxl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + + .py-xxl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + + .py-xxl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + + .pt-xxl-0 { + padding-top: 0 !important; + } + + .pt-xxl-1 { + padding-top: 0.25rem !important; + } + + .pt-xxl-2 { + padding-top: 0.5rem !important; + } + + .pt-xxl-3 { + padding-top: 1rem !important; + } + + .pt-xxl-4 { + padding-top: 1.5rem !important; + } + + .pt-xxl-5 { + padding-top: 3rem !important; + } + + .pe-xxl-0 { + padding-right: 0 !important; + } + + .pe-xxl-1 { + padding-right: 0.25rem !important; + } + + .pe-xxl-2 { + padding-right: 0.5rem !important; + } + + .pe-xxl-3 { + padding-right: 1rem !important; + } + + .pe-xxl-4 { + padding-right: 1.5rem !important; + } + + .pe-xxl-5 { + padding-right: 3rem !important; + } + + .pb-xxl-0 { + padding-bottom: 0 !important; + } + + .pb-xxl-1 { + padding-bottom: 0.25rem !important; + } + + .pb-xxl-2 { + padding-bottom: 0.5rem !important; + } + + .pb-xxl-3 { + padding-bottom: 1rem !important; + } + + .pb-xxl-4 { + padding-bottom: 1.5rem !important; + } + + .pb-xxl-5 { + padding-bottom: 3rem !important; + } + + .ps-xxl-0 { + padding-left: 0 !important; + } + + .ps-xxl-1 { + padding-left: 0.25rem !important; + } + + .ps-xxl-2 { + padding-left: 0.5rem !important; + } + + .ps-xxl-3 { + padding-left: 1rem !important; + } + + .ps-xxl-4 { + padding-left: 1.5rem !important; + } + + .ps-xxl-5 { + padding-left: 3rem !important; + } + + .text-xxl-start { + text-align: left !important; + } + + .text-xxl-end { + text-align: right !important; + } + + .text-xxl-center { + text-align: center !important; + } +} +@media (min-width: 1200px) { + .fs-1 { + font-size: 2.5rem !important; + } + + .fs-2 { + font-size: 2rem !important; + } + + .fs-3 { + font-size: 1.75rem !important; + } + + .fs-4 { + font-size: 1.5rem !important; + } +} +@media print { + .d-print-inline { + display: inline !important; + } + + .d-print-inline-block { + display: inline-block !important; + } + + .d-print-block { + display: block !important; + } + + .d-print-grid { + display: grid !important; + } + + .d-print-table { + display: table !important; + } + + .d-print-table-row { + display: table-row !important; + } + + .d-print-table-cell { + display: table-cell !important; + } + + .d-print-flex { + display: flex !important; + } + + .d-print-inline-flex { + display: inline-flex !important; + } + + .d-print-none { + display: none !important; + } +} + /*# sourceMappingURL=bootstrap.css.map */ \ No newline at end of file diff --git a/admin/css/fontiran.css b/admin/css/fontiran.css index 3ba8712..14c003c 100644 --- a/admin/css/fontiran.css +++ b/admin/css/fontiran.css @@ -1,105 +1,105 @@ -/** -* -* Name: IRANYekan Font -* Version: 3.3 -* Author: Moslem Ebrahimi (moslemebrahimi.com) -* Created on: Sep 17, 2020 -* Updated on: Sep 17, 2020 -* Website: http://fontiran.com -* Copyright: Commercial/Proprietary Software --------------------------------------------------------------------------------------- -فونت ایران یکان یک نرم افزار مالکیتی محسوب می شود. جهت آگاهی از قوانین استفاده از این فونت ها لطفا به وب سایت (فونت ایران دات کام) مراجعه نمایید --------------------------------------------------------------------------------------- -IRANYekan fonts are considered a proprietary software. To gain information about the laws regarding the use of these fonts, please visit www.fontiran.com --------------------------------------------------------------------------------------- -This set of fonts are used in this project under the license: (.....) --------------------------------------------------------------------------------------- -* -**/ -@font-face { - font-family: iranyekan; - font-style: normal; - font-weight: bold; - src: url('../fonts/eot/iranyekanwebbold.eot'); - src: url('../fonts/eot/iranyekanwebbold.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ - url('../fonts/woff/iranyekanwebbold.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ - url('../fonts/woff2/iranyekanwebbold.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ - url('../fonts/ttf/iranyekanwebbold.ttf') format('truetype'); -} - -@font-face { - font-family: iranyekan; - font-style: normal; - font-weight: 100; - src: url('../fonts/eot/iranyekanwebthin.eot'); - src: url('../fonts/eot/iranyekanwebthin.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ - url('../fonts/woff/iranyekanwebthin.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ - url('../fonts/woff2/iranyekanwebthin.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ - url('../fonts/ttf/iranyekanwebthin.ttf') format('truetype'); -} - -@font-face { - font-family: iranyekan; - font-style: normal; - font-weight: 300; - src: url('../fonts/eot/iranyekanweblight.eot'); - src: url('../fonts/eot/iranyekanweblight.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ - url('../fonts/woff/iranyekanweblight.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ - url('../fonts/woff2/iranyekanweblight.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ - url('../fonts/ttf/iranyekanweblight.ttf') format('truetype'); -} - -@font-face { - font-family: iranyekan; - font-style: normal; - font-weight: normal; - src: url('../fonts/eot/iranyekanwebregular.eot'); - src: url('../fonts/eot/iranyekanwebregular.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ - url('../fonts/woff/iranyekanwebregular.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ - url('../fonts/woff2/iranyekanwebregular.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ - url('../fonts/ttf/iranyekanwebregular.ttf') format('truetype'); -} - -@font-face { - font-family: iranyekan; - font-style: normal; - font-weight: 500; - src: url('../fonts/eot/iranyekanwebmedium.eot'); - src: url('../fonts/eot/iranyekanwebmedium.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ - url('../fonts/woff/iranyekanwebmedium.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ - url('../fonts/woff2/iranyekanwebmedium.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ - url('../fonts/ttf/iranyekanwebmedium.ttf') format('truetype'); -} - -@font-face { - font-family: iranyekan; - font-style: normal; - font-weight: 800; - src: url('../fonts/eot/iranyekanwebextrabold.eot'); - src: url('../fonts/eot/iranyekanwebextrabold.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ - url('../fonts/woff/iranyekanwebextrabold.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ - url('../fonts/woff2/iranyekanwebextrabold.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ - url('../fonts/ttf/iranyekanwebextrabold.ttf') format('truetype'); -} - -@font-face { - font-family: iranyekan; - font-style: normal; - font-weight: 850; - src: url('../fonts/eot/iranyekanwebblack.eot'); - src: url('../fonts/eot/iranyekanwebblack.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ - url('../fonts/woff/iranyekanwebblack.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ - url('../fonts/woff2/iranyekanwebblack.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ - url('../fonts/ttf/iranyekanwebblack.ttf') format('truetype'); -} - -@font-face { - font-family: iranyekan; - font-style: normal; - font-weight: 900; - src: url('../fonts/eot/iranyekanwebextrablack.eot'); - src: url('../fonts/eot/iranyekanwebextrablack.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ - url('../fonts/woff/iranyekanwebextrablack.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ - url('../fonts/woff2/iranyekanwebextrablack.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ - url('../fonts/ttf/iranyekanwebextrablack.ttf') format('truetype'); +/** +* +* Name: IRANYekan Font +* Version: 3.3 +* Author: Moslem Ebrahimi (moslemebrahimi.com) +* Created on: Sep 17, 2020 +* Updated on: Sep 17, 2020 +* Website: http://fontiran.com +* Copyright: Commercial/Proprietary Software +-------------------------------------------------------------------------------------- +فونت ایران یکان یک نرم افزار مالکیتی محسوب می شود. جهت آگاهی از قوانین استفاده از این فونت ها لطفا به وب سایت (فونت ایران دات کام) مراجعه نمایید +-------------------------------------------------------------------------------------- +IRANYekan fonts are considered a proprietary software. To gain information about the laws regarding the use of these fonts, please visit www.fontiran.com +-------------------------------------------------------------------------------------- +This set of fonts are used in this project under the license: (.....) +-------------------------------------------------------------------------------------- +* +**/ +@font-face { + font-family: iranyekan; + font-style: normal; + font-weight: bold; + src: url('../fonts/eot/iranyekanwebbold.eot'); + src: url('../fonts/eot/iranyekanwebbold.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('../fonts/woff/iranyekanwebbold.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('../fonts/woff2/iranyekanwebbold.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('../fonts/ttf/iranyekanwebbold.ttf') format('truetype'); +} + +@font-face { + font-family: iranyekan; + font-style: normal; + font-weight: 100; + src: url('../fonts/eot/iranyekanwebthin.eot'); + src: url('../fonts/eot/iranyekanwebthin.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('../fonts/woff/iranyekanwebthin.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('../fonts/woff2/iranyekanwebthin.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('../fonts/ttf/iranyekanwebthin.ttf') format('truetype'); +} + +@font-face { + font-family: iranyekan; + font-style: normal; + font-weight: 300; + src: url('../fonts/eot/iranyekanweblight.eot'); + src: url('../fonts/eot/iranyekanweblight.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('../fonts/woff/iranyekanweblight.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('../fonts/woff2/iranyekanweblight.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('../fonts/ttf/iranyekanweblight.ttf') format('truetype'); +} + +@font-face { + font-family: iranyekan; + font-style: normal; + font-weight: normal; + src: url('../fonts/eot/iranyekanwebregular.eot'); + src: url('../fonts/eot/iranyekanwebregular.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('../fonts/woff/iranyekanwebregular.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('../fonts/woff2/iranyekanwebregular.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('../fonts/ttf/iranyekanwebregular.ttf') format('truetype'); +} + +@font-face { + font-family: iranyekan; + font-style: normal; + font-weight: 500; + src: url('../fonts/eot/iranyekanwebmedium.eot'); + src: url('../fonts/eot/iranyekanwebmedium.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('../fonts/woff/iranyekanwebmedium.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('../fonts/woff2/iranyekanwebmedium.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('../fonts/ttf/iranyekanwebmedium.ttf') format('truetype'); +} + +@font-face { + font-family: iranyekan; + font-style: normal; + font-weight: 800; + src: url('../fonts/eot/iranyekanwebextrabold.eot'); + src: url('../fonts/eot/iranyekanwebextrabold.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('../fonts/woff/iranyekanwebextrabold.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('../fonts/woff2/iranyekanwebextrabold.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('../fonts/ttf/iranyekanwebextrabold.ttf') format('truetype'); +} + +@font-face { + font-family: iranyekan; + font-style: normal; + font-weight: 850; + src: url('../fonts/eot/iranyekanwebblack.eot'); + src: url('../fonts/eot/iranyekanwebblack.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('../fonts/woff/iranyekanwebblack.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('../fonts/woff2/iranyekanwebblack.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('../fonts/ttf/iranyekanwebblack.ttf') format('truetype'); +} + +@font-face { + font-family: iranyekan; + font-style: normal; + font-weight: 900; + src: url('../fonts/eot/iranyekanwebextrablack.eot'); + src: url('../fonts/eot/iranyekanwebextrablack.eot?#iefix') format('embedded-opentype'), /* IE6-8 */ + url('../fonts/woff/iranyekanwebextrablack.woff') format('woff'), /* FF3.6+, IE9, Chrome6+, Saf5.1+*/ + url('../fonts/woff2/iranyekanwebextrablack.woff2') format('woff2'), /* FF39+,Chrome36+, Opera24+*/ + url('../fonts/ttf/iranyekanwebextrablack.ttf') format('truetype'); } \ No newline at end of file diff --git a/admin/css/ssbhesabix-admin.css b/admin/css/ssbhesabfa-admin.css similarity index 93% rename from admin/css/ssbhesabix-admin.css rename to admin/css/ssbhesabfa-admin.css index 80deee9..fe05fbe 100644 --- a/admin/css/ssbhesabix-admin.css +++ b/admin/css/ssbhesabfa-admin.css @@ -1,67 +1,67 @@ -* { - font-family: "Tahoma", "Calibri", sans-serif; -} - -.hand { - cursor: pointer; -} - -.hesabix-tab-icon { - width: 16px; - height: 16px; - margin-left: 10px; -} - -a.nav-tab { - padding: 5px 10px; - font-weight: normal; - border-radius: 7px 7px 0px 0px; - -} - -.hesabix-tab-page-title { - color: dimgray; -} - -.hesabix-f-12 { - font-size: 12pt; -} - -.hesabix-f li { - font-size: 11pt; -} - -.hesabix-header { - background-color: #304967; - box-shadow: 5px 5px 5px #f3f3f3; - padding: 5px; - margin-right: -20px; -} - -.hesabix-header img { - height: 35px; -} - -.hesabix-card { - max-width: none !important; - margin-left: 20px; - background-color: whitesmoke !important; -} - -.hesabix-bold { - font-weight: bold; -} - -.hesabix-plugin-tutorial-chapter { - color: dimgray; - font-weight: bold; - border-bottom: 1px solid silver; - margin-bottom: 5px; - padding-bottom: 10px; - margin-top: 10px; -} - -.hesabix-plugin-tutorial-chapter:hover { - color: dodgerblue; - cursor: pointer; -} \ No newline at end of file +* { + font-family: "Tahoma", "Calibri", sans-serif; +} + +.hand { + cursor: pointer; +} + +.hesabix-tab-icon { + width: 16px; + height: 16px; + margin-left: 10px; +} + +a.nav-tab { + padding: 5px 10px; + font-weight: normal; + border-radius: 7px 7px 0px 0px; + +} + +.hesabix-tab-page-title { + color: dimgray; +} + +.hesabix-f-12 { + font-size: 12pt; +} + +.hesabix-f li { + font-size: 11pt; +} + +.hesabix-header { + background-color: #304967; + box-shadow: 5px 5px 5px #f3f3f3; + padding: 5px; + margin-right: -20px; +} + +.hesabix-header img { + height: 35px; +} + +.hesabix-card { + max-width: none !important; + margin-left: 20px; + background-color: whitesmoke !important; +} + +.hesabix-bold { + font-weight: bold; +} + +.hesabix-plugin-tutorial-chapter { + color: dimgray; + font-weight: bold; + border-bottom: 1px solid silver; + margin-bottom: 5px; + padding-bottom: 10px; + margin-top: 10px; +} + +.hesabix-plugin-tutorial-chapter:hover { + color: dodgerblue; + cursor: pointer; +} diff --git a/admin/fonts/svg/IRANYekanWebRegular.svg b/admin/fonts/svg/IRANYekanWebRegular.svg index b92610d..e0997ef 100644 --- a/admin/fonts/svg/IRANYekanWebRegular.svg +++ b/admin/fonts/svg/IRANYekanWebRegular.svg @@ -1,1548 +1,1548 @@ - - - - -Created by FontForge 20170924 at Wed Sep 16 22:18:33 2020 - By www-data -Copyright (c) 2019 by www.fontiran.com (Moslem Ebrahimi). All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + +Created by FontForge 20170924 at Wed Sep 16 22:18:33 2020 + By www-data +Copyright (c) 2019 by www.fontiran.com (Moslem Ebrahimi). All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/admin/fonts/svg/iranyekanwebblack.svg b/admin/fonts/svg/iranyekanwebblack.svg index 878552d..7852c95 100644 --- a/admin/fonts/svg/iranyekanwebblack.svg +++ b/admin/fonts/svg/iranyekanwebblack.svg @@ -1,1474 +1,1474 @@ - - - - -Created by FontForge 20161003 at Sun Dec 16 22:19:23 2018 - By www-data -Copyright (c) 2019 by fontiran.com. All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + +Created by FontForge 20161003 at Sun Dec 16 22:19:23 2018 + By www-data +Copyright (c) 2019 by fontiran.com. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/admin/fonts/svg/iranyekanwebbold.svg b/admin/fonts/svg/iranyekanwebbold.svg index 88b7867..6a6006b 100644 --- a/admin/fonts/svg/iranyekanwebbold.svg +++ b/admin/fonts/svg/iranyekanwebbold.svg @@ -1,1569 +1,1569 @@ - - - - -Created by FontForge 20161003 at Sun Dec 16 22:19:37 2018 - By www-data -Copyright (c) 2019 by fontiran.com. All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + +Created by FontForge 20161003 at Sun Dec 16 22:19:37 2018 + By www-data +Copyright (c) 2019 by fontiran.com. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/admin/fonts/svg/iranyekanwebextrablack.svg b/admin/fonts/svg/iranyekanwebextrablack.svg index 01c9d7d..815b866 100644 --- a/admin/fonts/svg/iranyekanwebextrablack.svg +++ b/admin/fonts/svg/iranyekanwebextrablack.svg @@ -1,1486 +1,1486 @@ - - - - -Created by FontForge 20161003 at Sun Dec 16 22:19:45 2018 - By www-data -Copyright (c) 2019 by fontiran.com. All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + +Created by FontForge 20161003 at Sun Dec 16 22:19:45 2018 + By www-data +Copyright (c) 2019 by fontiran.com. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/admin/fonts/svg/iranyekanwebextrabold.svg b/admin/fonts/svg/iranyekanwebextrabold.svg index 1dcb7ea..21e8a53 100644 --- a/admin/fonts/svg/iranyekanwebextrabold.svg +++ b/admin/fonts/svg/iranyekanwebextrabold.svg @@ -1,1472 +1,1472 @@ - - - - -Created by FontForge 20161003 at Sun Dec 16 22:19:55 2018 - By www-data -Copyright (c) 2018 by fontiran.com. All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + +Created by FontForge 20161003 at Sun Dec 16 22:19:55 2018 + By www-data +Copyright (c) 2018 by fontiran.com. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/admin/fonts/svg/iranyekanweblight.svg b/admin/fonts/svg/iranyekanweblight.svg index 9c0c619..da89c03 100644 --- a/admin/fonts/svg/iranyekanweblight.svg +++ b/admin/fonts/svg/iranyekanweblight.svg @@ -1,1619 +1,1619 @@ - - - - -Created by FontForge 20161003 at Sun Dec 16 22:20:09 2018 - By www-data -Copyright (c) 2019 by fontiran.com. All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + +Created by FontForge 20161003 at Sun Dec 16 22:20:09 2018 + By www-data +Copyright (c) 2019 by fontiran.com. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/admin/fonts/svg/iranyekanwebmedium.svg b/admin/fonts/svg/iranyekanwebmedium.svg index e7fd092..3e2ce2c 100644 --- a/admin/fonts/svg/iranyekanwebmedium.svg +++ b/admin/fonts/svg/iranyekanwebmedium.svg @@ -1,1573 +1,1573 @@ - - - - -Created by FontForge 20161003 at Sun Dec 16 22:20:19 2018 - By www-data -Copyright (c) 2019 by fontiran.com. All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + +Created by FontForge 20161003 at Sun Dec 16 22:20:19 2018 + By www-data +Copyright (c) 2019 by fontiran.com. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/admin/fonts/svg/iranyekanwebthin.svg b/admin/fonts/svg/iranyekanwebthin.svg index f83cc44..2cd7c74 100644 --- a/admin/fonts/svg/iranyekanwebthin.svg +++ b/admin/fonts/svg/iranyekanwebthin.svg @@ -1,1639 +1,1639 @@ - - - - -Created by FontForge 20161003 at Sun Dec 16 22:20:45 2018 - By www-data -Copyright (c) 2019 by fontiran.com. All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + +Created by FontForge 20161003 at Sun Dec 16 22:20:45 2018 + By www-data +Copyright (c) 2019 by fontiran.com. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/admin/img/hesabix-logo.fa.png b/admin/img/hesabix-logo.fa.png index 2ef38dfa0f3bd053595e10a850b58c208fd4e9af..9be7bdf52917d8354c9faf51d39343554c65e4fd 100644 GIT binary patch delta 22924 zcmb^XWl$Sjv<3<%P~4@I;!bgQhv3#0cXxLu!KG*^F2&v5rD$D3(2Oc?5_k~ zQf{JwdOs0?4t@#-EBYjxao}Vr7dIjbjvXrkv0!x>L+5_UnLix`bvS!dlEp6N#iy7d zH2Tb_)3cC0?c(D%caDEy`5w6B>O7_PR8Dw{Xv;6^LvzEAC?j~4)h)#dzqVd^z%3UI zhTb;f-;Gy;sUecK++==qvJwG3ub2b_0hKtKAsslVyH-jFhX~!ZS{3*LtEB({FxW~$ z;;XEL1ev3=gSnNh835p!;TJC?(<@5UZ=h13&4BLyWjij1e@Rl3s320Z`s*@s1%Ha} z6PzN!Pux$^Jq??igT`|`{aP9bU=1v5|0Z&j+R;J z5(h$Ynpr-M6I-&uN7yQS2*e+R`75P_mg9$(XH1pP!-Myy9j*0)H=-c99#e=iRhCJs z5takygsnFJf!{VOgFNyT-&L^KCo2El*3*B42S0mZCQu2NZUmiDG#TA$z^nb`w#9uj zecvSKz8DO(lsm3(m#d$Y`zgQu`6{OK*D-Vd3$~^>HeGn!H)%LE&G4zxcw-91XD5vJ z@EzrNc^VD4C?b?%v5?(|p7%|UCUYn2X+`Azfb~x+Z}_kZsLWyZ^7#A?RPXToM=VrIgbU;$T*&cVvX$;!sb&dScl#mbpL4F4I( zo4^CFg2Tqf&&saK#=+0Z#m~vcz{b`2Y5P-3UA)FyRJXmx_&#%Y>cVoQH|s zjGdKbZQX=aoSudHddZoRuo%91kF0 zQiQ=q$HK)7_&pq*JyZhv0Q^WkjAdBIk-mmj%M63GwB!g9{qrgzDG9>d#caWS*a~na z4HT_KBD44@WKnqX`j%qi<6Rn?dbVWy^T}U0Vf0Q_L!;xo(xC&aQMC@s`Tyk_z?1nQ zDgj+4Dud0TCc)ve@qCw^FPCf2S~#tt&@~_xlBTsmEg!Qn%2@$EoB2E|I^D>ai-y`u zQT`m#@UO@rYVS^Y@rn0%#Fmeaf|a2ckYWKFe?~^}O)J~35@95Q3>#1ZYl#*FG{Ip9xS~NTTmZf6qNm=XxDsyZy z5Rm=D^n_@o5Ll+N^(m-k_H8kV_VW&{!m`&GW^4lP%5SY%SXY?dj6awF7t~fC>wkI073(D0b;RmM$-m9x;(yC^*JS4sU zQMYUTRqB=Y&}@;|R33Gzixxq8KzR3b0y`?|Tc`RB$wu3DTIcPO|CHysrx>ryAKpMd zZz>6}0({L7{Ve@IwQnS0ppXxkj4XBhTk{W#y2F8`cgYf9 zv4~9AEM-`jlH?EHyNcOVJZ?Lk=DN6YY`~V#6)drfc5MwOiC#MtB_HF9^}!_NH}9bA zFCF$qzlka)4zaJt>xka5gxX$n#R4HyQFSK~{XCGvRE4RDed2}4`b+V2m%+syO)Szn zV>IG|z0BJZQ?)ocAOL5Y1yM;)Qv8jvF4vo&?SD@aO{C(UVpDk*eM%*{1`ffl3Hn?N zH)8w~CNiSrQg699Fh5}3r6Ox2IokT!Ly(f6)za5*vQ*$3g)?Hx7{xz#?AFZiA7dzu zol9RP{YUM-?`UJt)!!RMQjasw!I~oFzvFW}fw`F3AAa1w`Ps?+uhUBz&W;O~DT$9N z=XGk;rhxdyeyXL>c-er9K0JO4on?Dv0;w=|H3HpH;tLSsxcjJ9zS>mHPjdZ-537HxuQFt_m(!_6DS=w8BJvHhv#E0Cf~)&rf7I3-0gQN|X(+ziBgnvfo|II>g=H zm-2LOxf+|ie8Y?OiCcOR)cl@PVN3bdy>V%NKGy_a--6{=fIOd?-f3Lev37YU_pF=q zxqyo)i|nn390^#}b$JzwVKME04#Z8-XP&_aR{Op-_A{CiIn7Qir=AZSuY%;pJFv7A zj`(3Ic`L27DpPuhS0=KR@bduP65OFLA(5$WK0u|!_>6!EzV|lq%k*w#Mj6r8kdu(} za8l^PteshevoN494l_Y(cKu8AV!;1O;{*VvK3{Xoo2)t`T|34_CxsJHN%toifuFe< z)U+@WCBPr%D@)9uC3m!Rv{XIfP18(&`(hHEF;F%Ntv!5xnz z4iiJR5DGMP`I+B}&bCut@_%P?I&FUa916PeHNQrz29YnP&rqTMN{ij%B$iK)5O^2p zqVcJeS1WtnADy9v9E0ikz_k`{%UW=m-IDvxbIt&weS79L_d?Debt8k4_7G*h=Z)z- z-tJNE9f`*B;1`xd_I(}@3*W^{v!A12eM#Dt$Di))kOzBlP!j+xgEqTI{ffHO0l z8}coy3vanIEgZsnyu%ur@~59mQA=x*t8>3=+J)`k@W15+bNM#U?)X<2U74RGo09Yp z@u5W*Y1C&`{tu{`z#@$Cx`>k=AIReE7^;*ej_XRM(S%~uo_YR-5x~H*$SToBP)O?! ze~nA+chuo+)6g%75HPx+9P04>M!Ga*5LS5B&P??08-MR3?_`dq{KSvn$V!nvsfto~M}{Y9G)i2$7pq5bwZxV)>&b{404hBUPREWSR# z-Sq#)9VBwI{+Kw{CYR_KbC2;_n{>(kQ?@a?-+_58W(DlVWT%bNP5jY}k$&>*ij3e) z)8f{hEzE;mH4&E%zu&yNoQ`vDC}4rkw(~F+w@AWu@4@~B=9C>e?!E?#G!CUICh4p~ zf8zfTfm>mAg5U2C*47T*D`f))~qKTI7F9L~2N*J8h2h{J2SNat)uj<%S z3CPy;bgJh+i7h$X8_x?K1w7m8Az+`I=AVd_)JU4DNiaZV4-wq-x>;JWeC^){>Sb*&dJd54z zk!GPYnMpr^qm$ee?QV0xI_nBa>fI~8AyLMffdz)-kLmhK`{1f&o2)wi<|554Bb#8M zwDhs~=*%87B-tntpCyBVP z?SD(?0N$KAHkMItwlmxxt)A#1R*k3=kbH~kr|k_Jpj9(DIH4rHo1zs=PNDn7acY`e zVq%n!lZp_ZqOcx4cpB~Cr$o;(fZ~K${K+th4fEqxyYF(Ez;}#v-++vdG`DKG&T-^uBqV48Y9D}z%{bI7Qh+IfREv7 zz+C(ZWPEf0ymoO%N)|FA8lG6J2*U$A8C zrm=s(7L$US;50lu<0HCl?s!*+O@++szY>7ohZ4-i^Be)dR@ zPy5X=r)yi|g%9{P^w+*kU6`6aws=j+xu_Uq`bqH+OkhG9O`H%gO93b{UzkER86>w< z@FSEUHu&R{*+FQwVZkVfKB{pNCYom~{_DnyrjqGjrMnJ`M`e1#54Bq` zHk}sN4-H0cqN&b9-)aytAi#hgni>3dBg?(H9^#kvmQapv7xSGZT71?dEma@(gVfde z%0RAlFcS`uK zGF?Msx8nCvi!t%kCLc_RkKA&cN3lt<$v7+t*lBAmckH8StzZ4tuW%aI=$bIAv$njN zS6RRU3}=7QP197f<3_YHJaKxErOqp>Wt627qL>`hs#DadX_103jGHRwN|<-o zC!;$RPCc%q=T2_xhiQj}l#())vP#ma`L@yFvIRr}>rb1pnF)vle}{vo z!7%X`zj?zYUq2`w5||*=@zdnwoXO$8@chD=j@wHV9UN%j#3d#wB1MeGRCWCoEX8Cw z%dJxF;QjTX5XbCuW#l;fcZ~40T6Dih?yu)NtLObBR!U1;K(vq4+J9GPEzmmfrB+VZ zF4?apg#b&H@d;QO4>cP+gB|gh6umv6qF|`lIZ`+CdN6|e@kh+e9PTQgOhth_Hn$kO zywK2uk9PD%akzP6!uETTi%L#xLBV`Ai|l{~DRjx_K+AK?78fI|qPL)r3t{XGT6Np4 zoQ56hi&gf?-!PYwOx(ysyCK8y7a#x5A>zhof_#0 z-0Nnb%%B&InaSOLIe$pEdxruVzTfD13Z&--4loX5sQNGr27G1kX6__WbN)LuxmeBR zicpgLLPAzi{OV&Q!uyfipvL7N7*l(uPF4b?N4x#bK|nSh20P!+Prwx=$QJ_@De!Xi zeE$tJILT*GdGwj7LDV+TI1f0mi<1x&BQ6UU6t>Y-r_;u|+d74bMX=f7Z*^$wGObhRJ}x&(fG}V&?>lhdTv!psnSX3WUA>5Apu9-CtRZOv}1V*uw0CCkS(cv$zt}+YVFXW~N z`gU_jP<^lTMvh?F^6f}WkGZUD>tc_5P((PHV@Vu!C^X-|d>N^rgV8_Zwu%$VG1%V&wr%l<6f9&ElWoka3 zb2&oAH)z?!WA35QE&9ZbiT=4}EgBQnl1_$MGUx@-@*Qrmm86X2u?Vj|R4TP9p_)$) zZuxC@xOn|o80*W8olU-bq)Q{0jJBExQ!-h%vF`&9WLQ8SuVjS@t!H7$F!Tzpm!2 za21!ikHP7de#aAcMu4JdHn*>Ek#P~Ih!mpJrE30^`_AC-6Iz#EJ;G$}O!^%M6se-Wsv7d)<8ftFTI&&@-=2qgip z(k53f(%~CMO+drWquA=Ak2c~9h@s#tc?3Wjj~wM3TuSGqA(LzLZQn6WFfW1mM$kav zGTX{<GmBgMlBY9BT~WMX@Krum}AQ!h>9Oq*M(MCfQKE=XLNJZiVu4K7DvLB zxM4mv^*xs5pPBI`lsu0uec`U9KVy098p<0RbnZTWwH$v+xozYEh?=a78$Qv87nv6o z@X0)qsk3wn%-V3(lfZ}L0e-`O)$k26g;i%^=5fK#$+2UG-~erRnl;}4lu8;fw?)sa zc)(pf0$wp7V?@eR8r9ZQz2LV*O$*q8WB`H29?)BUHthh=TwR)MWw}AvcMbG~k9yi} zqU=Cem+Mq{bMaVbhTQ4_>UzSL&kx%UwQkOig|90N;QLYy->4u2D-9fnTJ>&Aw~A+r z*yc~tWWuOXB{7M;%;l}kzQ4ncD#9#?7Y{k8FXVn%sNutVswK{Df?2lK=rjPleyHr; zN(_kw!AT2us&tZSpkpfB!4^S+&rv~C#!gnhEktU^NRbU595KQZHl)u>wGJkbFgdcL z6oUvEa&QQ=698ixg$+2Ih-8A|4wfRHg5~wV$u;a}YA&dpqn&7=!Dd1E^kk9ACQ{^q zOtR!~+3z28Sacim!3Z|0sD(Q)UZWgigQqbJ&N>Hw25;saf*gfJ z;c;V;*mGa*O}w8m05+fF!C!x|Nv4wR5pR_J4E!ZX z^l$hm46MoxQ%s{9n6rg{O(TT%U^5|V>jCEB8aTOMn>AW(SVWqgHO^sz{iFQ>KQI!@Vy2EU} zNfz_(iED>LzSb^6-6&F1c&t1xzzijnhE{^>FPMrXV2*psJ;^GG%K*T;KzBOW(~ZE$ zPr%nMX8R;$v~I$vnPy81r4fGWZR;mRXV9ewCq|xy6LvNZKoHiE#`MuXI>3oGwxmXB zk8xkHl3t^dlK9Kb;<;84@78)O8M>p`Gh%r4Oi^G&MEG1Sc7Ke+@LkTV*7#Xx($=r$ zE33mP@FHywzN7_x7RejFTn&NSM&4HRR2CQ8SSmLyBo*Wf>~bn*zYuI}lkJ*-RgT)?Zc-{F*? zwY;%zzPKClv7a>k*-C@i9}xBapdeMK-oKJr%9?66Th61!9=1Y?C-rfew=t{tUAGpV z;nOQt86GjrK49cyy+ETjug$2{5yXd+y@_2cx7O=Y3Go6sGH`hpqg1>dKEn4P%|q}L zSXC-iP>8xu6#b2{udwJ}({_s%t+QT&H)-ntJn+wk-$)dWN_{qGX{6eZafF?wHx)aZ zjhf!QU8QsX=f;jURgJUUQrjM2t%{9N|V3)}MTk~rvsNls>a&cErc`4?sU z+(QH+Om+C!`lK{-qKdAXa1R<4IBimTZ>*OGHW@m&0;wXm2AFrb4#290p*%6Y!Kn!e|${LPs{@4;MUFWc$2)!BII zFISeXUcNFh$Z7FCY<8SzVpcJIO|06FhWL%hO39&KY>;@X8`^<~_T$A^>#9zJhE^)N z+|l$7BuFI;pO_1qE{=67q4*+diL80lzgR+f3=UHnfkC?i`51biG)XIeA%=lZA|KjK zI3!G|x%{!E>k$JC7=Z!Dq!byNuP6a&6x|GwG1;QC7-mrgFJ=zDm_qoQ4)GDT4Sm`o za25;gO1lz^&kz9aD2@i!WYa%j{|+)-e!o)P7D(wdY`T4DM1MlvHK9edU9Tx`_Omv2 zzli10f-lMYE+nn(0i&sL820;Pb_VzE!h{&0JdA?@Ou(FjW6TG>maJxSFWopDR1L7O zU0HE$Y^W*7ktTa!R(Ad`6E|Ytl#=lqbh4-p2oB6T^cUAWp@KCZ1PE3tA^8Rr*j}G+<1`bN zv9cWk9?CaO^}Bft3xuNwLO%UrzZkq}TG-5#RRQjZk|hGZc?D7A;8C56ORTT}b$_Jz z61=xi<<|$fpek(m^9Q>j&KGJAZ}2GUi2vKMwCsWp{%!Q-AI18~DVo2YFm4bLf@K(V zib;s~iUUSFO9sw6klVaPHwiqm`RJnt?O?!O$BI3u0_={7%l&Vmv)!%_Ib-+7ppmIb zcQV9JITlmb56}y_o+*ez6%*X=gsI5jLbQwnpCxIs(w{wgrnz*>UFdEbAoGM`_$C~V zUa`4!4l;QrCvz18kw^+X)o?cm;Y*8e6G0jo!Owa|Z-fNPmBBqt6vRGA4jy+WY<*WU zTI^*%TdXSm3GDd3Eq?Ju%haGjh#Dv){OtD3fmsmf^*g9(VMIP79B%p^In}F?pQl^; zoLc7)=0^5g%t$z{G~t@cdbJ}M^O@@Nmi%O0F;~V(!z(&S`e@5cg+TU-pgX!}z5?Z- z9&9|U#0`7Ku%%1{{b26@@H57JF~w25$DCm@3y&o~Df*Sutf7GQM~DaMjl5=cC2If*}+Zxa2v1&(7(@C)G2|gm{6H?><_7_)qb&K=GV_ zU@z98ZiK?+QZ6NaL>^r}5~FB%dh&~hJ^0(!9cK~EVRB)8WT}DqZK5B{>ltVsAtc;G z@>RTKCjC`YcsnDH^n(%>MkZ}V&quX(V2|lRK@Uf=HWg792L~gurj&$9xdH$LZDGyif zB@A14Kkiq4Jd~gPx`7dH`YN%ZHBRAsXTd~QrC#zC1hYrG!$=sn>uYMduuRO`KPT+fg`8G6#4v) zrS8T9oyaj$k@lY@yb%pxJU!wB`K3=yO4^jkh6Mn;Xrm=lZH(`5SnGIkDB?OZ=DHDC zLu}o4Ne)XNKXpYT-oZRX#PQ#7GWz0mlZvOCvXKIi43n@}fsEiEu=@!5w$qKjsYJ zC64W_7|L6XAetc(fzEHZLxSw6$+CX8P7FsBb*9dm@|ktb8)o-oUVx2CGUR9!*`-0p zuoK?A{1X6h?|9K!e4TrnvVA& z=$!z3QPAwbu|Q4KT-m377L8wDZ5&ERP4t&$U&3v0(Y)KAh67M9R~E|)pB30RO};Q; zm_;f8gAHkbWD-a_P0tzSwnHaFW)cv>xdB{mudG-1Vg zrX}RB>^(|8dp`a7Oy&hdq=hks_x*Z~Fv4Blx%-JBHJLqR+Jx9gV9$A!FLooboP4UASr*L>` zk)IIr6VTU|buOG5zbPO(##Yc7!Mss9D1;lLj3W5i)E_CE6pA%XWxrFQeZYtx0Di_z z-am%m7n17n!BY7wx<@zlK`PT}MZh@FXd6GvGB(xD##pLdC3pYj)CRLE&5hP2XD(Xwyk!KeOD$6kNac>?jJQ`B18#%vlo__4y~H$hU@YbT=; z@0#Gj59_msyr6y{Ml|#R%yid(45u{IM%V`PbbAtr3j)r&P=u1vAM`!62lp{cOlo22 z9T5I-1Lj~>5e&KTSpqIC5IbQR@DN5gIXnC`FgwvN4*;X^Q;l2W7AST;z-(#JW@4dF zRsTfXVgd&2x;{*50G^1tSCYi)QL{-m=L`igHotYZ5|<_2Jp5iZG9H)=FudY|R?J{e zZc&|G&Mh}GZP-A>zfQR7JND&$rSjEV z?4YbMi9GSICN8vjg--!yGOA3~qoIn2I8xNrs90Uf8Oz`9Tpa=f%y{dT4Zz~OR9}s8 zL`E$)dJTT;-E*bdK=}|NlRq3YD%<@jrvu%mg8wE77R1R&#yz_?X8&`SHzG96t(lVb zp8H7x?Y4agls=YShOwDO0Y(`P@C`zC&jA=O98XuI)c?(VBo;9OX&^^j|Seu(0eBm;TV$APuWf;~zfI$iYzRch`;& zZQr2g`oXR~BHZp6n4QjINt!&H$>bpf`onE%V~RwD&X!qfdKx-yfzbm(??{7Y%EVj+ z!jppfU-9wpp=gqPu*#eF`lVd93)ll5)laYwlDW^$ITJUG$#IAp_)>auzT7}Bk*Yyl z`lR_oQ|t&?*`t4#_OQc|p9SxHhlZ3c#sR~eE9ZB1&6(J!r4aTEKlgoBm^-3^4l7Rd zS&^~hstehZdUl&V__FG@*TAe?_8qyKk6Qm7v;y!YCBQp3;GK_ag%7^2eT@1stOUD* z&e=$cbC?!=HVAQ&j<^>hhtCbMTs^n;GvO>9-ugmGkfGE1t*bs?TjD+&!#UqaO_NhF zuP^@Dv~*}hsQHp--0#r*hG!`MCs`W7<^a)$!XU%^fC2Ydu(K6F%1fE&S}#Col#5jdZij68Uqq z$cpwvKRBej6HrzD)R007%>6B`d=T~|OIq=m;FJp1R&FI>VD=}(ZGqps_dVYt)~q>{ zoM11*6G9od@IChWWWGz_7sOf0vl?u>ep@a99?`M-d->A|zjh*ZMJs*PPSfjZBfiH1 z_~w^rZ;Kp7y?7iX!I>J%u5M6|oo%uvn@Jk@k&j29<>UqPXDrNh7<1bFhT-KsjNU?A z5#)*|*;^Rqn$5H9+T=eeg+!54a=!^yciaA29Z)JJ5?tmfo-4K29SYqr@?-Zs2l9dQ zD?p4r4@}`AA!?skCe80|%|lv9#eE5)%7Ff#qvn=^p`#aXeSr@S9_Uq>Rr)VfAoEWU z7T9YP!*ckC_ijPbhLgJfR$e#pZ2^2$ky3Q$}1i ziZ49UmlEjrvOL_=7WjAIZS^P#22)mtb{_3X7_=Nt0Pe(~?NvYw{LT-uQ^Z0hKNl&E zP(VA{_CdEN{`d8mCKj!n-=}Pl|BSjBWjG@??AJvD2I4ITJm6V9#pZEt8l zu~tP5z46o_#wCR-M*uVd`jr^z(8!MvAz*f)j=*;wM&rs-VLx>Z$XWo$7DA~<@UrwR zx_eo{xfJ)#6vIoE1#}(Z=_+K^7S;F^4xj5#v>3+GS~rc3b@Kir_5puJnnFxBg@&oM zjlDExU|6K0QbUS#gNB#wjXefj5CGfVf3^M_yIWe?4iWG_#)Z%yh5hE%a*YDaD>=m+ zjbVmUm2QQpV^?5cg2^=hk4*FZ`&Hzgy@7^DntNh^iEc~@c5D=T-@FSYj@PPbZ$0-j ztE2=xhnDS4AUuNUgxbmch$(V-AhDR1S^@>jG_<bRCX~XO7)rQw`Z0g8!J715%Ya zZE+EiDNEE^;psCO64bfPd5>m|Q0P8+-~9s__raa!ii23!40k zM8>SGtPv>|2!2bj?^QZJAFbB#voy7uT+;t-RbR@3TwBC~QH^ioZ_lAC9sdqhkD!x> zESH6R3^8yrKaiG>D(+r_5<=I=7vOF&%N;ZwD{Vg71=D^P;5y-U^eq9*M`yd{@1gw- zJmkdew7JVG-u3Z+xE>_KO5^OgGEQ?EQ_)8*CU}JzNjX;-nz}C79LmN?0E>urOg<(D zHbeNj4|U}hDPg8xuWf$NFjsBtBdn+yJmHQkBa8oX(jSlXJNhmiIrAUmW{B(NTO_W= zS;pc1CzZrN%GD1ZV|m+_sVM9(QpnyGu~BMI4tul29Mxsu`F$DK#aE2qd$GxrtpO>6^}eIlL+PA5HOu_4YoF z#mcP8tRzO2N*wyVCKSq6w%}$vRob~fSIS*mCxn7dCpqU%Mfm@Cgby)%*ZpS1oOp&v zqx^qn6g4Ft0P8ADmzszvv@)BO=4Lx^CF94p{ETKoZpTZ4CFQ^`2KJA$6Q-AD7p!0} zFN#Q>#r2q7xLmkCss6`jiPn|&m@__GZcI9uI6o1vPi!7My3xLa=K@$z42H8D;n7%ve`xLQF)WyX}eFG4(=scwQ+ zBuRmWbdse8>cS)(hLrXz9tRHg;FZj^)nPTSGHq?CI}PbD8RH6D}En;$$vb382{qT&lo{5Na+4FTUc25x6ta1xSKns@jn6( zU~(Qj-zZ6+_>_cc41={+WBT{!!M`pp9-a%T;0FSZd)Nm__EcXB6|!qZ`_V5SxQ*^{ zODp3?1QDe_Z!x~?%YzC7hw$ygj4QJA#LM{eR{3W7@WvAi*_8_q`$nK7h}IW*rA zBf=78WdjSa)^f21!X+k=w?yXfu!Uh?+8scZ5 z+n%|S(It}S4fk!ABM1E}3mPTa&;A)6&slG|e%H9Cor}cVn@(M!7xnKT+1O|(g^Nga zd4T(Rf9ywzKV|M&!w|Q)xJ9~q*)k2-j8>=%f9H}L1t+B9SrUNfuH0_S(U6|lJt8}9 z)ivZ`Mw?=og?;B5>HNI@!_4wR855_i>s%3(4T-AkSmom6X2qPEi8OiFZM0p&gn;Rk z9?O!J2TJmu?NwB)8iqHvTI`}E<|k9_xRToR#+0AOR#^Ul9 zH|AKQ)~V%_+Vc^z|M+c8u|^@exw*X`pPnj2PYYRxOXaP|(EUC-KBnLOdVY9Vd~$NK z5}oSP+SazQjJa!pKLD4iU~T}WSmxs4?Hn8}f`$D0_Y88yz}oB87q-!wkG)Z8!csaF zHC$+4{t}ISki@L!7PID5Nnmr-!e!t1+|!~(AV;+3oAItX%uo4UhyzJ(<;-g?d-15q=p!kOmyA`7w5IVw8Bp zXuB_B0)_l-c$8&e=jxfCpZ}P94_I7MQo>CVyJ3PqAP>koJ~{EpDJa-W$a9QkW>a)2 z`1NlBpiYGy(d#mZaR~h|A^eRZ*pq`K)}VuY$mwdkpR`=B&0QIQAV(L=spt}RetzBs z6!q}97nwe~i2=j_z>bc3dTR%#2@28C!>SxFUFi}TuWcJ|_7<6Do*Ej{t`yQks@*f8{!6lYH6DHnRXI)d^}at-tH>xQS%?54vQ*d@ zP;%d0ua~a{63ZS(`e2i z*}(sC5O6*p)fC^G)tA4V5NiFUkvhhMys@QOAD-M+-Y_zim~g1$X~Yb%aM#d~ui}$< z@^}9!sr^TA&#dV_3t-U@F*Eg@R(aoj{pWWQ8IVu1utmKA045FH5S;@Y6JE&fB7)Vy zSkT_p*7m$*-O<6v@gV=Ew~rBi=tj49kvDbd_5+W}yD4hqG>^B@LRwl{&%(l@Yl5me zJ~bA$8UZrq;!|#bCH_*=*m$R$nVC6V(DO{6%cuyhWjx_c*IJHw1+4N9>>&bDcpUW0 z3k&yU00?Z?cK~bPOLFQv@}@;zL-6G4YC8wk7_gcF@)t0V4b7j<&ySCv>IQ{`l2RS6 zv3`BHGyt#woAWw5-v-9V$MwhdxtW$@$pU}Y&VU?ZaXat#Wk{iA0*<+cXaFKCfAWY!uagfnGV@K@xJ4(+{Wb+R7MeFUW2W)eH;%+n0 z4HEzXXDS|`9gGQjO@5#Nm4J)z5p>IDk7%(6-YXNrLR4}I!)phr(t*neF8@I&ya z5dlJb9pFIpuM(uLlKQxC!L6Ok{oFsS(Xe16Bt)C#97TB&GU?EE#%<&1cu7WQh66bPX6P6gfWy<5T+4Io z>Qv_E=KMlZC(QRx0Hal9WdaY4EB1A*t*w=?j;s)d)RrIN?rpn2<+GgTr)FnWunRDT`vdE&03Je;fkT@zcfH$<^>f(J?i_BgLHXr?pEc~ zm|)sp({qH&Blfgfs(6_UYmsW(rP_ug*QdJg!`CT~{N``=?5Tnu0YCrlwg8k2_xAw& zl<`BAlx}2YjYK#RAQXtpNU^&`FY6nt$NB1HyRVM6HUSt2ZLp0%UQ28xUEoBZ#$F=Rf6ujAD8 z@)8CPEAvTAI^6Y!J%JnM?5PVOm{JZ77h-_(iu%s|{eACV))=$>ij>sw!@rf4mD1O+ zm>d_q;88X}HRFj!vc9*~=8zcQneqK<>w6mX3(SNiMF7S+teah^6JbN>Mo}qR=~5Nm z)++3KS;rX?>i;!2mXsV#$+L9a^j6boU3vPVLu|q=i~jA0Xnh;~E%H8JAfH@$Ll0$& z-{ctKR{>LC4DUe{S4J8d8WFxwH(n06Yy$rqMCxpBX?cvjyWPo1Sd`=*16%WFz7aqo zMp4Q8%o1%GY^|-WSruJ)0ENG%kI&EF{J8e;V+Whe_ECy`$BtZZXq6NI&Ab^kDOHy> z=*9Spru)CgG6n8c_`-x4wQBQep|VZ5ZKvTfy5wB$81gSdcRT&utuZn8r zbZ$26Z!9nKQ)eoXDuUAY7?ti}T_=SG( zR->O>$(}~ojL^=+^KI|h{j@)3gd^9@X&Mk=h5LX;r^^{`;vUVA)LUMD#G~NX0y25j zD#|;M9(5x{hH3!TGceU-JUt4W@`w$HZLF^+qAzF<3b($7g{tZvh(Cl=ZG?XYa3|00 znwy(rY7|)O+qo(LnHp^9!ex(`K)}eN5^pKLoH3VfwdWx0l~AN1>W3`JgOb^=aX_5$ zsS`B069Vur zR*ECCeK2hrP?eA2>xwMi_VR-7o*R9^!a76RM5S=9%;cF!=cy9-ERqp05DcT zM)O`@U+-ZTH@L-G;UPaKKQU^u&eWE_1P*t+wYTcdPHNm&qXE3`}bR`H2Lcj70V;UH=0hr!Kr+^T&`qr6iA{U^wWy-b?r~m zM63M{p`ddxmi{T>yZ+XVD=9F>gHW{K*IHx`lQL^VsF9!;NMIM8czR*szJSkV-}mi5 z$kEo(DKceG^%5gA!XHR=ul*+hMOG}3>IHs=%IM3SDf^@5+aff11Pd7b3D$`?Jc+5L z^#o%*1;U|pT58SH0SaLrB-m5io%1K0pcxV&Kna?z1%X^kckWHv5rv9%Al1XML9cd#SL zEXvXp@f;rsRvJ<87*mQ%1xR8i621#dfi|dfd&3WDp|Sj-`U6P>X!)bVb~zLPpW=tZ z!re87j5DAI~}!C-6qOpm_%p^zIIvNj=``aR7evKWqxwhvGbBB9Cs4Igg< zH!)fn>EjZgISSnTDbK70YuLHX-ljoOG(N8MceM1cjbuPXFeZmMkxA*l3^;-#hQBfU zjqBx4722kfs;wW(hOij3=~l|Xy$7L6hrKlLl?o^*Fg`J9-;i*0RWvuLNW@L-M>@Z&&OPp@I|%oVem=NTpsACbw2(wJN}Rdx=@HXb zcGf+ZjY@{rGPUw^rQnA%o#uwTC=2u2?N0g&ML)k+j>y^sX;yo|ov9+{K~!Yt(W3U` zkSSE&$`FBn&wFAXZx@UQtKZcMxLp5Hiro#(oM(7?Vu7J^GC&v!-MG+IbaGMW3TXI5 z7rAqnO+BHmy$T=E{U2H68ZOI<50JA50hmvGaI2McYZ2?h4Hh}baG_~wzxn-*Xnj79 zd2X|CmdH7^p5_aDi$0tfF`6jXVlcP7owaousv$%F2NT*@F}7k~RfhvwRX1*KZY5Q% zZwfQ3T!(cO1-=e`LWgF-Y=*e zU^%CUJh=hXVsP@IxmSBxsf7oE+EQaj>J?1qsYfO>hH9id z{#t!vbe?KcYCf$UX>TO{951sw80k(_>3x*?D1d?oX8iK`GA%v*Uaf(!yQD>|6R}3K zTyhKLGKc<83Z+Klt7mRY3*WEFx^{P@0FE$<5#3L+W!u^*6dX-Y)i6znLKD)g7mwjE>tx#uBSD@%L`v+MRD^J*bug@ zd12hRagX))_kZXx??s5{{zM|tN<{YwA)=W~=1^w7NTGkBtsNQ~dN|0nlF8)HIyyRj z+1uOOuwuoEp4)D_&DZ=&L}w)ui5P&c+;*HJnfZK`S%iq{rIe2}H#eUtrF_UV%|-x+ zG4qA0ft-l8Fbv}_&CSid+pE^4`2Z`u+Qp(F6 z^4Y$>zyG1;=H@fIyStxWuwcOqDP;?QGhN!Ti)oq|%$qoYIg_V(^5gh&E7 zP*LR0pkoFRtz+hcGMP*_5lv7{)&cxJkw~0dS6BD@!NI}FQp)39*6u+>Q_|`5pA(71 zxtV`V=3ybkwnB&mfRh#S{e6{Ha$Bqx7gMm8iP+sk+y`mX$p8Qqrb$FWRNZDa@)m1Uh4{%m$N;mv$Hb;pxn6ErvW%EAB2CwXN_Z)5aRA!Xxj$A@iw`3A5;(U)_d50Kq&9!Ng@{ryNJ63Fe} zSC!jK2=VtsA`z$^0QO?$$35x;5iP04GaRNICr+G*L?VIyex=3S0MIFf=Xrb0VVAYfySg2KdrZ@FC`}X5W#Q9_BidS?OPuLAm3y1Xe+yWFfU2-% zt>k)&)T1hrwp$GH{k2EJQQ|@vq2#$KW68t&ELV)xHFVV1*LO4X3l*ID za$Q~B5^MxeY4Ene?CK>;mi(W~&+B~ZHC;&Pi@D zQWmnUVVHoO=31v_?q&vdHMv(u%N>qJ=bSJEXtP^CijLVPIaTooaA?g1`Pm}770l)2 zAH!W0UqAPq$9gRHfLe1uGamt9Wf`ZfGz{a2^_`6=mtf`Na@vjZLSWvzcJ118JqEgm zJkGT&%X-A+w^J(Y@4u=npP+yB1`Z|4%zqsk8alp8kHDzNF<_nV8;0?GU1|_5|=$fK%?sWHP%-Dfa{LvQOO- zz>+m<)*O`&pQ%DFeC7YT)bV3gTFuth)+t2v#WMRk0H8gYOztkFJTA!2f(qmlaJq~o zZ@u-_o&fe`=9heAcujwOef@r+hv6JWIR>ovFG2`q4uO$AGs$G~CICmmBZFY>++Jp$ zn~R%YgucGM|3Scb@V5Hi1@MhzGP!u9V+J!nVHn2eGMUUC%=|n5;(U{oa!(<|Ud;S= zpTd32oJb~|b{6vRdBmdCikiepWTFta5*azsaTCotIYh65aQ;puCBZp{9^!nClZMxnfW9DdlM1o@|*Vnc$k@Q zP9~F2=E^_S(b0eLnSp_U5U&@E!^%0Ps2y-9tpzb#-;E&fTY9ClZN!0i2o}=y%G6;O!%# zRRQJGSjNEq5r7p$^e7Si)E0~VuXEz6E9QZ=(| zHRKqS^q4u5OHKS|0M{jx$%o5nd%4d{S69~`IyyRb?CbVFBH*Sd1Y3?iDHtM5%BdIG?$$z<|w+iAzN zw6uI)O8I|10Q(`kg>8_CRseWV2yugLV)PP#&m|IxBLSSq%zF`012cb2M6WUPJpitC zE-zHW>N~9AD%PO$2~b#Ju2!u#t60PqJ~eC&orrRk`s~S8ImdZ5DW0OTL+0RO+CYnqp$7|_mj26UdFd55SYfn1I&=QCG}k`Ij44?bVid)6cO!VOz9}a&3_zqzd~|%K=c?a^C3~~+ ztRH`5F!4%I&dRNlYayGQ{r)&9SHdrG8ck_z(UaZ+# z46F%R`fq|L1#nHNRlqMlyCVW0DJBH=)Ur^7$sJ3C4&b=b{!&@{qUX(H(IL}G4NSJw>=^1h3R4su-U@I)fj~AD|v;MjK=6bhzjjhrJ=J&noq@6Y1L#v!q|)i?FrzXFq)pW#5g8J zvTt^DOre3ZYA?FoYn~k)B+3v(xNGQyDFBzNEAX1+f3v|vkL@Bm+H`f*|uG6xEhWLLMDGy;|OgI z0YU7i|(8KKFF1VQbR!^Z;T3|cXV{r4Gau?T1t5uGk;eRk}3`0jxx2R zofOB$O`be?27v$Mk1bxj_@j6{9tUva$ZjA@A;g(p-sKt_Cz_g?YK0Ix6VWLE<~sLU zGqaRZ{zgkmV{{2UGgQ1*Tu^_p6^f%<5)%iJl&obBlcuDaZw_SmU$N=mUpln;HR9mTh2=*UD^i9XH4_<$N{q>T1lF8&v z@pybkB3e)>pA*r%B}SfyeUsp`oF&6Nc2+*Z+i> z|6(Ka0U|opEf#w+nQR5{J(M5NraLpMmxmp5VqC%GUbN@k%U^-~`%w~bh5@7lPn<&4 z&`s0K1dOqrzmYE(hVj)(0(^9Kb`H*&GiU!w#p3@jLa?Vg0`$%(Sewf=nYYmNRLT2b+ zfcy|7rWf44i@d27+PB-jY2}`DwaP9*5pe7TqUcxCR^|z#@!ZFRNIxDkQJb-9pJRYb z8rWwjgMOyiXV#_6FEGr5nPF1CVP45!ypqQR$zbMKt0sR+_lG`K0JYgrdhBoUD8~c7 zMBvm*B=1`U@)-yR0bFBQR$DTetT?4$P8%=F8ENt2#UBA!lKW_A*sVS< z_x1I?OGHzBp5GJ^U0+{c-=Zgb8tV(0=+HaVU-Q3AW^0ibm0KVdr{k4Uqg8l`gB|~8 zDUCrBnWKMS0Y$%JG5Rwp7DP0_45Sbp$3zSu>Z0=(u1laoe)Mb;*`s}~FQwZgpdV~K z9=`O&<{*fy%R&GpRwa8k%Y$v(njpE3Vf3sQLhtJ8TG!m%d=wEaC!*~OMg!)40Phpg z3jqEUi9~*;%Hyq}u|Cn+**VzU+vK+*`R9Lk0Kf;x=H7mYh<=uj?53fy-U$8G zZaLx{BFSdh=`sGUqh$b;WVlFfOI~702TC$IQ2`5Klo_95IO*KcXvOAtSMVV zV}pM~cX#(wD9$&op)qE`j5~?sj~Tp0(ORxoPVr&(47TOUEwwl)vZT2)pd&wc;b3tH zRp%Bvw?4R$VWBL8NPszg6I1%5(B*D(Kg$QOWiJZ}6!)VfqFl-EQXu`B)pJYWb!?$u z2@MSmjSUkK?tPzl=yzF-*`B%+w$z=lB{qLSF_}33wtts0SlUmP#n-c6zvNu|aTJGW z^-V0}Xs=&l87T)$PW@4?_-Pd~%!s0S5i8s4lT4=I1rKGv1z8`(qUon9XqASBhK9z5 zhQZZ0WK15qg}?(v+O#rYj7REJ`}h1u2=|n%h4Q(JsZ8nQtRKb80jl4e?RKUeRkeRX z*)D>B^@wEox2oR+r`%K@yY}t2y{)(|hD>+&t{Zw<6S{_mhQ_7>Bl9#N^Pn=Q2^{8k zFL-IluIE6leL|HE6~)`>;P|azO;FVbMlW%xGY#I9S#@RT9`1Dw-;EM@=i>Ie zSqiwk82h>Z3Gy9A=4Sl&y0WYbn$UkWG&D3eV5C<3v@a@puO_wzO9;@ZEqi&u!$YI@ z(w6P)?iSvZ6dF3iKM%NbZQV|kc7k_!kqcz*Cr;l}6?xNy|8MVZL*%;3IDr43=f2EL zx7j46NY%VlT0aCDK}r-wQHm&vf?tZDLKmbcwrMQ=R$st=5e2o?yx6j-A+>+45&V+2 zG$6DVDWcM9iVb2lX?AC;NsU=|XJ>Zq%X$2e&CJ}l&1{<4G@Jhq26kue%$|Fg<+;zf z&pGE>lkg*%HY{xiD`le}!%ks4|GO$wlZOrQidVN|Kqn%)!i5_BRwa27B38N-Y*i3h zE`SgF9^``avMaaQ1%lf$TZw;O=z?PDHHFQ3=zKSA?p+u~UpMO5V({y|YnY`+?^bwK z7Ji{Q^f>o9p2e@!tUZb5UboV=F`yF>UE$_VOmeBhX!nOJZYfDikvjbVh0y9xdDz-CsS-44r4wgIj&*cK~2X%sJ5w5X>tAWPYx6FO!yK0#u|A*|*w0X6QsjYmA%ya~h7{@}h}14R{}eNPW2bxWg*B7^u2%xG4GcW-InO zm*j}&=D(iI?D>7#dTHeS8mznZ!zmgQfCbg(JJkJhh#-IU5Ir*%%-_{L`P0*vqJ7NJ ziHO#qZgVnHKl-_%b-N(`OK(bBCKDdG7hN{Ij*{au59A(FJrrNLD&64UDEqwr@x2jk zLF!3#IMntX$;`f^tJSB5+6P6XQ9O^_#YpD-wD6pYEqGYG&$IRy=a283zEtfKe(i~f z*0x~N&g*}j)b^wZKL#H?rlHCH;tUA~OL+m(~NqW0t z(GjukH&Sh##MGm=WVT2{KL}NArYaAOPSLROfV0{+VNMD&1_lQ^%$A<&1@c)%_mH^wM~UcbX#RL)7a|Pk zL_}Ai4L9Ajy%qVNa29^vB>0d)f}w`UOG8K|qUEys!QiKr*?p#(UBpD(X|>K1D#?>+ z;{DaV@nGk2^_6bkb)#YI4`%X?Y@uFmK74;aq9y`6t=2uDnjA7)IF?LLCZldA13D4W zRjje~o^iAEGqKg*2LyMd@Ye$vD+aEC0G1h2UOL94KjfTE&C7#dW>nzZ<|crP1nF}k z$qNSe3wWJ3+=-vL%h^BSJMYxQU;jfV^<6MKcZQh}ir%@U0-05G{|Ji@smQZQaOQta zJAQE0ZVfP?6A=--_uMX$Zo1A~x(yQC2H;kQ@HT_i0r87-uk+b8ii_8n6_a@M0>1$k zsaQ*0^c=)qse93}8$9nf|M=%a^KX}a(M@-M)UfVpgN*mv55SN>q@zd{faI5g_?TJv z6wsM-&E4(G(N+d@A|fgXHhrxg`nrFuo9K3v+KmPU%-#$5pEA)ggBr|20KvK7?Xo+E zL13^1Kng=wV5vwF!_uc9ItA;_``d z+6K~J19A!$O?jIB$(eszk~hyJ|9aeA_V)5?OGHG&2)BGCNZh*ddXR39Q?y3R+*X)u z6=-O1F~kcY8o<(6M16Dd2?5TE=<%8#&Mn08qUh}Z(y4>Vm2kfP)}20_?Fck%*23hv t`9*Dd+CCede8lnFK$EdFEf{oV_&-!d*k4EJbb|l@002ovPDHLkV1i`Ugj4_k delta 10023 zcmbt)Ra6{J)a?xJEDcfhC^Lq?DWS2+}{+-0|2GGYrq(OV!ArcAw;BhA4G^gYjMg?VZ zsA=?9171zWOG#i&PjYfonxmv?=;WPOW-Iq?b$@e3fo?hFWC2b`3;-GxIzqr%>4q6 ze*lgr1J^i&p3(0U6Gp7#Wz%`-f?9yQv4n!Id@hjT}5nl)%}@!szwU}fx~Sj zB~|1kC8=H9oULpfEI}Zj%)lfO*=`l0aAo!Sd}37LC;^M&PhPfClm#(T)hY`Z6+&rk zm$(@`^zYc>L+!h|a(YX{VrwgLDnqGn5rOr?)&F*B8DObIdObdCXQHF6JEyR~;PG;< znZtBMjS;TN=%%!xs+bV%TaGAE2!3)}2_tu`uFve8h^P9pluwHHN)GRTM2aZ4kafXA z3X(IFv*E%5cNiniubThxatM{lJU*_=R1UF0UD*U#PKOhdl*R}nqk7dyhYW}RL;&(1 zlqj_{;?Bb}hcI?nNA2oI7j8D$u}JE^W6jyd(Slzk56BL3MMQ zAoxtwY~iNaIq)l(Tthbg%_DBm*epw5zLOdU&Sl5n>wYA>zsP#ni_fABN3-aw07_+D zJaiVxN=(k#qwW-+qYc}@z?;Vxw+XTYmd^1QOr#uCR$w9tx#7Mq{J`OciB;b0ZlAMp z2_Bd%PjLk@*TYX7QXp`#=}!G2CC+0P zx`Z`Z{O0zi1E2t5beg^+;2e)GzV}GXkxQv=WD&|=OOQN<0Ef-EUX*ws8z(2LYQldt zX1lX@#-soLVcC3JGdS)}6E$_4O`xUs7Ba^%=FW~K~Fi`aG5Z*WuO$^3RgdID+PK4@&r zT6&-8@NVa@5a%x~u^{Ak6%S*+)zjGG33sQYHkU%u`i{NMW#hQelB^SuS2RT9*_UAt z&g}V0W0p&ZJ=kUvP*|E->heiFEgcWXRx?y*t{E|2$ry{D!P(AuD=@tPkn9m>{G-5R z(;uVsx-4{xcmV<5G)jAPr|9n)Iz6<;aY_y{bu9s6to|JJY8MiQrq2{P}y z=|TV5Hc7y?qu4p^yyDpZOXkzE(8l15In44MKHQWI6GCzaar|ct#R1sk?Vu2jo-!+% z>6!4&=JX&&Jncr_BG4@WR)~oT`Gf>YTU-tJV|nQi?oMmc$IVDo%4&8al{D?o>um;5k|dFCVTUZ(^IF=C z4mSkLgWPhPe=iNPAUH(r+kqg=*%xV@cJqmz+j^Yes}%?N6tJJgnYhM^4VJb@XjAPE z4~8b9sKGS=CKoOulW zkdE1ho}j}22ZOO6yQG?o$<&#Xk1;ad@D0(NMT`Nq$+V0TfZo6W~J%LX}eyK0#YJd^7d&~>HrsfB0YUrMq zKS0X%V^nKqy}Q(YusVSbBoyk{Sbh9etL0>q3`5 zMEsR^yh4XvAsUXH*J+Jv|48qEQs^6*0dWfiSxl6EU*C-=UPa`n|+MX3ui~C^xKEpqv#B0uy6krjyxQ1>D}>< z(a(cW|H^SfI@OnUmZk+-=9kYV>?ug9&jP=&W{8NVR61MvxrgoRvwtNOi1&yWB`vuV z{YCjgzxh>3%-|&9a=6cBaVsR5@o$?EkZ0v`M*yog@Bn^S6HXI zZ0e!}$%yl0*c;hn%eUP#kL3s$SYOY-HJ5U2cROvc9Uf}3f11{U0$>9SF z=k<8BpWiY`Nhl0=p3yc7b39!^GR{{|T(fz;U1_fC};M+^X;tDSVd~sMfO~@K2nMRh9f6-Btv@IWfWmGbP8WXKK*Qt zJpRfb;fHk|QyXB^y{&q+JJRsFQ4x`YBGKyX?Fl*SP~kZ`KZ6(lGBBtOO6T8v(%D36 z?7#A3O1q_1_!jbM-mAgnF*E7$X+hif8Edthh6-}s*!T3%5L`QEGf(C4hY~dk6byPX z8bq|=O;y_BWPg=YVhe#-_@QU)5F(%daN%&>`7QEo>W*u?1Uef5;il%lc@#8z*exA5 zCYs<*%Z}*4b5f)f281GbHk%xuEBp@r4GbUZ!2EP(`E^!5Ehv%K= zjGAv`yVH&OP1PX0##aGQtyw`LkLLqWaZ%z+vf{0i#!NyC+SM-(9ZC!#?YPZ{Y5gLH zd2nZ@Bed0)XK$K;&UgOXvPAKFBA3e7lR+DehT9PGR7%aPjE@r016Z6hZRn7vh#0+w^710G`h|gbAya!RxI&>XwRD<73fOlXi zWczQDgc}zr7x_0ua*H10R9w_^tx_v8hXRXR5Jn4Vn{1pU%^H7SYwmd93+4^WR2x!n z-!)^87U`%1^)r&GLF^pUv2*^v<_wR8L5j7!Q|r3BeiAlyaW>_(oCNg||Y>>?04Com^j z?S3MbfTdiUjA^*tlXmk#v%TuJLe=V_{NneLctC1WjUeTGlP@z;vm6 z+HAWN$0p7Wd!|Gm5h9NuBBw8n@cqQ8iN0$RV8xU+aB!)&Xd(PD?*_DfT!JXVaDt-2 z<@r4dP^?_yPmZ=#^8Oq;IRBxVv`~+`m+bNb!o>CA%I#cj$yIbVUj(J)_ZfBZDk%@} zxY$@Pbpx(;5amUZ&Y%1L}O{tkI}OUp!M#pnXFe|Gi8@FTfQ&-AeTt?K2!vJ zh;BaWUVecHO4W43)+>6eKV1mC&j*Hfo@SHVUMFTf%zb3qJtU64HyUft>|vC;I(SN8 z{l0gWjvj1C?j%3z2*2H%$?KQk%xF5*$;qkGCqlC<@)%`x?`dl0q?hVJ#p^g*P8bIm zJ1t|!DcI3hNkb(}jrv1KTc}Fy8P*Q9E;bAjJ$)=K#o5cA-AX*ZPdgzBhZ%cy)8 zhJ?UTrjEtAvZ@ayb9HeV8-BSk4t^=1t@Nwm42B0O$oa(Hq}rM?<_+5#6%IX=97iBF zVk$7XFFA9CduH9skVY(XlWYsqeTOIH@pQw5WK6o*ulXay%E~Sk%Tt6zax$s- zgeM$!cBVR)T@=G!vVSk(k79N-slwsvQDNoF)btKCA&L4@xu6z1q_ul%mr@1jWOX=l zWK{ln4P+*pURHKI84?RpOk9MXrQ-DOCJiF!#`K|NZ0py2CR~*oKv3Yr=fYhgK1yI&66%E~kqMre|CsCR5fq z@o@=Sxpje3e3Xs3JGSmWX~!Q>oA$5|kK(b(B$h8D0!@Wi@%*k4+5a584mIR384Kbg zC^Je!4CY_^3?fTyJt^%+V6x5CPbD1S=_Gu^E@$y-^OLh8D^ZfJ;DMY+kr|>$@|Ix@ z4bhSZ{qzMYfS;c9BF!v~ytwQZeW(Vn)nPe!HL2NNSeXVMZGi0d{AJJ+zLsebNnI_<| z%4z`QS3<%`a`q6KD1Rby?IMYC8Ii}fXZYv#YY)!GrvXXtx0Vfw8{gG^rYoz-@yYDR z$*?;3V=x;SB04?y*Ulkl2IG<^m?-!d23=&K$>H`;AllYlnIhf)B;AhBX$~wkzf?w7p-&LHA)o)UWGqH+sCSx-A6jQTCjYtcB>D4~y4v>+N=kLk0=;x_(Kl&(L zyG`PvV1rUCP^k-WJV81&Fo!Qa0V`^pwRw6q_!9Vn9ui!>#tQLM*bL+Ro1)X&nhn61 z9d@%fqU<&1X$bqG^IwVD%WVaLugR`WNa8Dq%9oFhD}{z~sVDxH^R}1*A}-VOgOd3C z*uIA#^Hy>~VRLL4^V{LZiY~03fiKdvjg(uQv0d9~sWm4^(k_t*J6K2Jp|O%(kf+Sz zlgu(|sT-jf!KiKb1p9uwmt;7lrvs2)(#>Pv4-r*MvFlG{m7$*~(_803Bzy1d7F~zx zJTMrs4A>h>6mw%u8nIAIXXYC!+_(Rz?^Ev}altr?CC8)&mbdgy;%8uDuX#qO1Vq!@ zlpv!_s-~1j*aBjbSX(Wz{kct;i_$Zi$9phws;~SctY{ipmG3~NSG9{*5m+o%T8?w6=8-6pLiMOtm%O2zwf`G_YQ^ri{ zqU}ErXp)A@f){((eO6G}b|j4$e}BJS9fcL(GJr}U0+Z@qGZ8UWTR#r)#=+;V{SP^1 zcFg*37i`dQpvERqp6TIQfF_IOd6u;6H@1DUg5JL8x(n_lgEJXwC~#uMetDj?&Ez!y z_2Q4~uUij>AxL-Kh@2{G9YeeKK!3&!2Q-)mj+uss;vJ+laAAS_#v=)z&Olo ze`ZiHNG9DN%68*;95n zg&Ehp_8rjA&eX_&fpKo`Gf5Z8H)@&d_eVxX7H*g~U!=7B0nFV$EW*;dCwo-;HN<~; z2H2L>O5AXHg&sa$R+ih-sy%yh`hDDP_}nJQG4Sxx9waTa1Mt%I74#bAXjK1OLItL{ zD0TF6)aWi!0=wVtiHgIr9bLGCJtyd3ohMoCPV%ElS^z2yPro z7W!ujtxP&JR+aogq}5wneA1BU+9V5Zm!rQ}nv-^sTPT%*h-#Y@DXbFD#b zd{Z5OPL6L8ANKzQsOAGYZ2I&WW$5g9VNP>`AU5WHA!Br2c9bkkus^Q}ir}X|JsPxk z>f*|v|NiT5fVY7Z{7|bjV9}C{8;%(L=4tKuxF6?3kY=By|J%PSLI(z9Im+W%-^^sh zBB}P@WO(M}n02FjpT85wdDoS6VGql#^|luRT=n|(0BdxF_B1k38CT5E4u~^fl$hvz0()mHc^O*Jwek$pEQq_z!~C$k0)2lyh>VoMG2Q5fWNl|BcZF73yCC zlrEq416_up|CwcreXOUgn9J@r=o`aC&Ll>7^lo^^0Typ<6+6EVWVEKBqT-n~?byEp zgq=T!p4Gm0NjSvwgLKSsWgV*&TMMx1Px2+qcU~^3i8cL1-gm+lVC;D1VT7`o(e_4> zR_7Il5Y%CDCS_C3#hrqn6|Ne!f^Elmg{WyGB{uU~ojjoz70trSK3%TDBS9B;?z!hBv+I9tIXu)2$@_a`&2OGu2jPqZI|`Fzp~IYPImzwV|VITo`Q zF=tu!-CVa{VB2Q_QCLkfv+L8>ydABP2Y!)=qqJzFBNLKPF@lSn#1h6DGu$TgHzr@K z6$22aUvtbJqnT(EA7Yw(N{Mwnw|5YqQhC&+9*f#PshH3PO|g+xwrKZyCZ(MK>kcC+ z@4vX(6ZfP14rU7s*KK4Tua;IJ|jdkqQ;9e9rnrARR%S&`WubUt6!uo ztISk_hwo;OeC_5Vtqeb|iAX*Hl}h?WO@_xPpa+Rdm#EL6LmkM4UqPwC3FjVzzSdk| zVjx7>GKg@0J>OIG$E(y(|A^vIH52FJQNkpVn7=!s1dSgK&Uas$4-Sp@$*)GR0dHv5 zUOQ~iZ+|4A!y6Z*AJ-rFT*gN3nK?$EjWBGju(Z6VF+hj+Q1^b%Uvv@RX+-q&^12o= zwirNEhaYCdP>%QzQE~guyBPc>L29fOg}#7R4YQ`efrI5bPe$_*vC^C3ZoR^)dYPw( zOUxW(S|3o@$Pc;Rl!xu>VzG^q+_1v=7W9%$l3DO~2m3Hlyy*Lcp`G@utgOJ=WE@{t zcprQ6fDBGEt_?4R3D6o_2ys1d!Ep!e{?mC?9#cF8zP*0^GWW8Ql=ecy#AZGCt$B&p zKQe#k6Tw|#0c1v)Wz%!bt5Um{bNu1Pje>A3WG70KH~rcNP{llOHYNE*g2_lSgz{W2 zvi$<)d8m-ri0))R{nZFznDoCl9jLO)>R3H>c$tmkOwXPHmW_6sn@g`I&0(n$T|H$8 z^Qrae-VPpu<^jqU_i=<5SzFjb>d2FQZlw~Em_EpzJ30g!y((1|SmyOtHnx)};*G62 zIvON%TB2)CvsN^{4A23u*kw1_#cwU0sjOoo zErpeCi8oe&<2KoLss2<(8{eEil`(_9;WF$_B`}>qYb~&5@!>F$%3GmF{LPUFugKeO z@Jm+FT*6asN=JW<&a%9?u5#4;@p4M! zoW&=*IkGNFasFDbs1Q-CnWD^jTCTT}q{kKHPx4j2wA{l#ckH^~VPqFxOn6!)tMAyW z&phbHd{3%_J!p77RokM(WOi881L37hy$dub_Z${9IfFG1K`P0{Hi`Xd@#g{n(P;z~ zV9X%t_x9r4n*l%iuA?}{UN>c{F(A%?#6)K)z9a^dR`taklz4pHK~m~Ei^n-0X`Fi0 z`K1|6J-OSiZy`aaWRZ8YLE^|4RVEN#x3-{3nJ}&=AT?^n+*h>zkw31n-tSEa)EU7IXS3#j(FO)&RKdimivEfE2Av0ndr z3FC^>Ylplh;_)1}&%v*D5e?9J5e~okp8UG1zs>6TE4O7FQ~7y6RCXFLkO78Yx@Cu< zj4am&WHD5K2#4g45t%A~m9|RdKdaMCwA5Ulru6P>HS`BW>i6oF{z*#WvV}_<^AbDn z4+~?$i}o?{S6-(FL4CsMMa&XZXKvoti2@qDk#+q6D^3ab&}=XNqOyex@D?xk z^dkT3t@yMyOPR+0r=S#(U4RiDjG3>$&Vny~2827)be#9jF@Ht~$=hCPeZnmQGgO-1 z`3CE?iWBvVTU23C9yY|R5{I)8zE{9C+VCy;)_xXHH+=x98WWVsU5Q9Tp)x|LsAWw` zgXR`3j9~Y8yGB1ECHih1AaAgS7}l}vzw8YqPMe%K|BKlCH&O)wHdp@CNwasY_rXtg z)LO%Vc_H32IUN=}6RO~O+Vu^RhUHyp7_PNx?p(2pxf_n+w)I)*ehl1X)+2#MCXdZ| zq7l_Mu0_kB2Jut;V5Z>4-u0I*$85NfSbajjpW^5j(QOGCU|$o?7!s#3C!&PEW;7#r zr#dHohfklkFAn^tKzu;0!`S(tb=H8Ug>Zh~Q+yNGn|SHM^zwfWvO$Yiof9Cd_tih6 z6cLDD?*?x33O?AA8*5BRLOl7SrmZtx*(LJImYCI|&5ECS6W`UAvIx>|-*u~yhgF2! z8iZsbty1G3qM1mDD#xnZ=n=gW=a<~1V-nRcVSpIV0(EuXl6#zxH|)LDRIFrAfZd_!_-h2JH$7dNP_k2o5wEm5WxwAQzo z=|X*0+{uFYpJ0NO!dzEbfU}$Xo4Wwf9fy$g@!IAL6xF3;Y=NqX!agzWn6X9*AbBTh zAP;nmjZ82$>gXcctHwzF)|GDob9JC^M7=f6dIs;|#`*Uj+ zLgL0`>GyGWnyI`I&cC;b>0iCu=<`(&yL`#2m+cX+aw%psA|4Q>V;iMGmCA>$)JE8I z3>VE0$}+rw2YSFzzk$N5{DhrbEp#{^rmgW0X?;1oE(UIJ!zyLe&4^wz-GM+zRR59* zyz711PbX-V-fi+J`Bm-T%HA&dTXPQ2FyvZSxucvjJjIYrUZ!iQjE=?RTFAK{|gAVxHOZNq)#D1#&!vLXuO^UaC`zPwc@s_cRIPdzZ5`X(@ zenWKL{9Dssi{?VCsn!2Fo;fI~I)7o^J3qp;@y8CoLqU#@hCI#HqS(*1nLKg;`0s2o zw2+0$O_arfDfgfc_U>aLLqY60V*x>>7wE`dEawMHtqv6@#Iwx!i0!2*RbT6mRE;S# zItoh+!zFtW7<8d~p7e?uww z%A=S)a*Wtl<_grJvj5Jd1+ZJk5oqF6xs7$h<6lJD-uuFMPj9Kax0Ak=-e&y{g3@U< zeyQgn@Y@+Z!&uV(%a^MRF?+s)E4vGcHYB8Mh%Pna2Bj?want2_!>{0ekw3UeH+U97 zFTJs`KVYX?3vPmLHF)HO=13`vRtt)iG_ScI-%r%E(sUYIPzKK~v8wn&30I;>AOO-p zQ^3ZDtQ15yZ2L%xjaG?GwWzi^sw+d)rF({W)h;E3bY59H^MN>2TC-g3JbvOFbY4eh zwD*@LA&RW(q0SNOmY^{m-l4Y@XKhWdzFJ{_Q4~>raW}5$+zV6M&L2mGo5}UN0W{pd z*t=V3M-0@iXae+E`!3G(@=--ag&4KN9^&;2=bh$)N*7o-YKep-k+3mr@#>SQ*VV(d zk*JW%nbepwh|-!$gOIxXz_SutBE=naoqy`q>*MP?8qa-wP~uqrEhx4L3NX4gy1PB~ z1J;#lajy_<^}F5Bok+aQh7saBySWUfm2!rI5$Rc47I-#8lwUZ-h9k4v&!|H|>T%$8 z^u2QB{XH)OZm`k{LfY6h%DwMDVOYmKImG&1a-uc)|MlUJ-rc?^1Hv}aggH9!1R;=| M)F()#gh}ZC085XbT>t<8 diff --git a/admin/img/logo.png b/admin/img/logo.png index 91f2d31f8a0b3c696e7b4fbd3fc5c425da184ce4..54394a106f2a9d075b44ebf52bab98fc0ecb97d6 100644 GIT binary patch delta 1526 zcmVdB_DrL4#OY_{pS=rg7Q%DICkxl-C)Nb7TUDSUgA@D+U>j=x1?odB83C%}8On!f3X|}z!SQ5+| zGLkW%-T>wi!Z0Bl&mwEsk^=?e9G%!g{_W`ieF5FESr#_)Bdwn9(V5mp;=|B*)s>Inq{OD zaWR))6$7srfPj8P5R{myCo_v#c#f}o`1pDk<5}M4{v3l!!DN6>B%WisVG(Z-&um&c z=Y8TZD@zLTIq`%+7bJeK-v9@P zz<7zW*FE0d*WKH{XWIS!07=Ypmc}OF@Bjc0)w6~Iy8c~0G%+k1000JJOGiWi(EtDd08Q5ImXnqdAAbu12^co1YW$i200N~+ zL_t(o!((J10LCaE(V5we>hpbzy9)I)*l9P z0h3ILB%^Fa>(XVrA1zq4;{&s7Aum>SvSsf7@qhyd&n;w@E#xD~az>f*NMu78Wh#0x z9azZsp9H`tTYqLptmWPqnq|rZ(bfGY12D>#>)^GVS22xg@zR|y&^0p2mYO1~J9qv@ z*MBkr{&<%yF~FvYS+-D`Sl^#Hd%btx{xeH)$+O7jqNF7jRD+pivAT?q%VE*S$jFEk zm3#g@?wE&Z6uUA51H%Qlr_qeSWi%Q2=>Jn}qW>6~n14}19ZeGhy#W((S!19bKpyx{ zj9-XK1ONZi&Q(mrrEXOIp+n~vVg#jJMIbp5$3%=4^bl~1o0Gh2_o?+rmgoI{+_{0A z5Md!EtkK=|^Wn6=?rzh9hGZ@nBjOOn*fkxe>=iPO$xB;I8=hxILYLfq@|*-h=bsaIc1OLg&VdNx2+P4P?6ht^&z{sKtW3tNTvi|!0 zM-W2^6XPG^y#MzX&bok+@$Vz7S{`-nV3K2QK7X(zOz!#1_ZH!yP8bdd$lAIa%_of5 zgZ$^cfB1rE>9XCA$!Tsg$&{+0^)Et5Zk9v4S`H+4IAkii(aqVn|I9Khj#MYMcjQij z<*lqTnM{OwPK>hU#-ueAdxApJRWxF3U%2rHZl0^-6 zgi8lXRblFn9=kMyMYe#QqMDvxEraR%HwJA$W`xW$PGCq{U-)zgs1)fL*L_-tMXtGhLc_E$*L?^nCr#744?Js5dZ)Ig=s@WP)S2WAaHVT zW@&6?004NLeUUv#!%!53PgAv`6$d+rIAo|!c4NRA);4}QDYDGy0}HFmekFthsY*pX2la$kMEqZ-9eC zV6sHn>mKj!@1EPgJ?;7Z0Op-?)k>#Zg#Z8!_Opfpy8WHdK5Ei^P? zW-Vc2H)JhhVlp{mIWjmkW;bP%Wd*1XFf=(eHZV0YHa0deHZhYM1{nc1lQjm&6EHD4 zF)&mzGCDOhIx#UVFgQ9elMn|R6EHD4F)&mzGCDOhIx#UVFgQ9evpxsn0ki)JU_BWwlfoPwCBcJ5}6n_NYBY39)%#700=dPX5I4f}xWE_ah1s>UQo8W)U z*77Zt3C!MfzzF6IF#DXeootfrMZw(dL>YXi5*cPA0^%mXtW+k@4d-qHxDy(-ap)ra zC0i!$O%|oWtw8F1BHByZ!vOxyWJf^aZojoOn|9@AK*(zi0w4oJl7sff#D8wEMCiPN zmmf~G@;AwUFKN#Ju(V+(fUgS^NSY^&ek$Ko5gVbDUHq)$bpGcNDM$V+j8|HLxKsmF zZWVHDbq7csZ=3g*n}Q^`Qs^Dm9HN)92n#QzzBxex?nYLi8X_aBB3BBJ$t^QC#6090y)$r(wxdp8xYwNz)bee%z>ZCx}Eud>;Gp??s*gmL97=RkT2 zoMnrdwqPCu&;U3mm>1bx-dElQO+mt>1(m(MCm~m&hGtJG2UI>Pel>ebm9`O|lu9L` zT5^6wxS=3Szke7$orh7sv;}1JljJ$CV}M2NG+XVr0sa*N4*=X=@J@J9a9=~+ zloT5DzPDu+u)%BJ0QxqTQav7MtA9X(lanzTxVhsFw#4UU{AqWb_`E`OjYm-F1?ohjr$ z5YcYiIeKB@Kd1hVgY%K<`vG&mgxdi#8@JI$ATAL4l!#8)z(Edx&1V(_{|gXbQabB# z{lhSLy*Jgr`jQnSj{ Rr~m)}07*qoL+<=UuBppOX978aSfst45hZ8L1X-_-o59JtH6#l)5pa1{?glR)VP)S2WAaHVT zW@&6?004NLeUUv#!$2IxUsI)8D-L!j;*g;_*+oShrHVzcP}&NuI+$Gg1x*@~6cfPO>}l$fa}GmBYxj<0+8_<9%PS>EUV9D_>1WPnd3o@2UU5pNLBY+5?! zec~`HOA7Hh@q|GaB!1+&?D8AulEVVe3>(?>JaL#%f71yxvx(W;SRB2D{o5C4ecPmxO|R|Sk5 z3#dVb5YyS zJpzWdfs5;oChtW7mpee@NtX=Ck^D4;Vi9;hqi@Os!?!?i&F!tdkJASrOIK2d-P^xs+Wq|iNz8JV#wOtK000jnvxEY_0wiKNWi&Q1GBYh^G-5L?G+{Yp zEjeX2HZ3+ZV=`nlG-NnpIX07L1*i@)Ff}wVGBYtSIW#mhG?N_$838zxHwIG^F)=zY zGE^}$IxsgnF)=GJGdeSqodz2dF)=zYGE^}$IxsgnF)=GJGdeS~%LWJmlk^5$BxYne zH83+aVl8GhV>c}{G&wmfIWak9EnzS+H85j0HfA_AWRr9UNe(eFEif`vF*7g78C4dS^xk524YJ`L;%qM0000@*6o&);Se8x3jzrx3!CcrH2?qsfk{L`R5;6( zRXs}sK@fdAmk<;opooQc;E&QjApU>|@dB2jlE#n9&VS(V&?2!ghFGX*h+q{+uu9C% zSR~7BHn(@?HFvi+`{uowWfpLtqFUH`emkY8x^AyC^GF;p^9WhEe`wv9;C_F2000zL zNpg^XO7_%xJ+p&U7_R_;rAC<9RhUjn(b0m6AgTm5VH)ftg{YzcfB<0pQQuprrN@a< zN>Nl>wZ5k{Mlm5Q?i}A`)mB8{xKj2%0Fc>I!Aqht`zN+KlR=Ea-_P^itljoTTcOqr ztvShH2>luW5g8j&^KK&u<|({2G@^*8q-G$0qLLeD6e^oA%`yv?g5)YR&#<;_&fQ?} zv+vqXwVaiad-X4~RxYpI<|!qAXY*|`3)rcR|JW>9!`v?an}F1;=8_O9wb;{1?|R}L zO^)p;;dnl_-F`pGn|s~v_n|#(wPw+JI&M<4HJY7EA6fJ9<$}VhvPW7bS#kx$TV_Kg oqtUq%5uqsFn2QPHP2Uyp2k#1++bhyTl>h($07*qoM6N<$g6;|*VE_OC delta 1371 zcmV-h1*H0dC+;SYBmu&aB_DrV62l+}{O1%sf&v;mj%n;nZ_wix0?EXtI4+N6Rs_c9 z{ep)XW(F>c)K+U!dhgTL`rfB6Q-Iu=}@CZL(ayu#PmF_yq%&dF)%h==OiMqVEvmpiD`T zsQLh8mw~zlS9J6k5c1;qgAsyXWxUeSpxcGS%#v160j2(uug3 z%dd)oSNJf9K130dn5ic-i&=Qq*FAMp-9>noci*2iq!dgB_(bA4rW+RV2Jy_MrE}gV z4zaSN5T6rI8FWG7N3P2*zi}=(Ebz>bkxkDNhls^e7t3AD%7%YRJWU){RE_e5oXZO5 zEzWAS&f53nFANs6l?>NujU$02B$0v$8Ff@pg@p+18Yw2ybRPHck2(Gnxny!xz{s(H z8dOM*AN&t~&(e@9yuO+rK^S`TYRqopRMmr(1;p01iX5g#y0y{D6t!4V&S0Sg8<6jJh)1poj7O-V#SR5;6(l`(4+Q51#0 z^L95v5JX7`!CfI;;tvQ|Sl9^`DppoPT7y``WFv~5?ix`ntZW23Ed=}g1Fa-zAtLMs z4H6Lz39i|9EM{hBW|M&4=E1x7o_Eff``(D5P-CeMIw^MF#Lk27*?wp&HKN0RjPN8< zG^~rb=1zN~*k3Jy)ths6xC?AU^%Ov;F9fT0Em}8$W0ooy5PwW%LyhKDcUrFp2M^Hd z&9f#vMN9x+A^rp~wbQoRNaJK+Nz_1fJG@Y%Ia>k@jT-@U5eR9+R#2~(&}JSO!3KLv z^1S3*z)q6aAzK%!jq4f!+7$tRM^XR)%L%gKMDB@K-MRM!_a6f9k^+Mmi_}z*Y>+r0 z0#cUmWzaxO83Mv7liWk6piYXcjMTn|IA2^4HULy%D+SNvL*gIEd@L|5^|>@Q!)jHi zATFTFD8y}uD+iJ-0Vc-g%nFve+ui^!?QJceo^i+}XVocEH2)Q4$(gx-3ImoJ+@7W5 zrt%!TEquk@)@F`ihAj&v>X~FIm#6RubOv+|w7f^{kpI0,i._pointerEvent=Boolean(window.PointerEvent),i._addEventListeners(),i}i(o,t);var r=o.prototype;return r.next=function(){this._isSliding||this._slide("next")},r.nextWhenVisible=function(){!document.hidden&&g(this._element)&&this.next()},r.prev=function(){this._isSliding||this._slide("prev")},r.pause=function(t){t||(this._isPaused=!0),Y(".carousel-item-next, .carousel-item-prev",this._element)&&(f(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},r.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},r.to=function(t){var e=this;this._activeElement=Y(".active.carousel-item",this._element);var n=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)B.one(this._element,"slid.bs.carousel",(function(){return e.to(t)}));else{if(n===t)return this.pause(),void this.cycle();var i=t>n?"next":"prev";this._slide(i,this._items[t])}},r.dispose=function(){t.prototype.dispose.call(this),B.off(this._element,".bs.carousel"),this._items=null,this._config=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},r._getConfig=function(t){return t=n({},X,t),p("carousel",t,Q),t},r._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&(b?this.next():this.prev()),e<0&&(b?this.prev():this.next())}},r._addEventListeners=function(){var t=this;this._config.keyboard&&B.on(this._element,"keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&(B.on(this._element,"mouseenter.bs.carousel",(function(e){return t.pause(e)})),B.on(this._element,"mouseleave.bs.carousel",(function(e){return t.cycle(e)}))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()},r._addTouchEventListeners=function(){var t=this,e=function(e){!t._pointerEvent||"pen"!==e.pointerType&&"touch"!==e.pointerType?t._pointerEvent||(t.touchStartX=e.touches[0].clientX):t.touchStartX=e.clientX},n=function(e){!t._pointerEvent||"pen"!==e.pointerType&&"touch"!==e.pointerType||(t.touchDeltaX=e.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};F(".carousel-item img",this._element).forEach((function(t){B.on(t,"dragstart.bs.carousel",(function(t){return t.preventDefault()}))})),this._pointerEvent?(B.on(this._element,"pointerdown.bs.carousel",(function(t){return e(t)})),B.on(this._element,"pointerup.bs.carousel",(function(t){return n(t)})),this._element.classList.add("pointer-event")):(B.on(this._element,"touchstart.bs.carousel",(function(t){return e(t)})),B.on(this._element,"touchmove.bs.carousel",(function(e){return function(e){e.touches&&e.touches.length>1?t.touchDeltaX=0:t.touchDeltaX=e.touches[0].clientX-t.touchStartX}(e)})),B.on(this._element,"touchend.bs.carousel",(function(t){return n(t)})))},r._keydown=function(t){/input|textarea/i.test(t.target.tagName)||("ArrowLeft"===t.key?(t.preventDefault(),b?this.next():this.prev()):"ArrowRight"===t.key&&(t.preventDefault(),b?this.prev():this.next()))},r._getItemIndex=function(t){return this._items=t&&t.parentNode?F(".carousel-item",t.parentNode):[],this._items.indexOf(t)},r._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),r=this._items.length-1;if((i&&0===o||n&&o===r)&&!this._config.wrap)return e;var s=(o+("prev"===t?-1:1))%this._items.length;return-1===s?this._items[this._items.length-1]:this._items[s]},r._triggerSlideEvent=function(t,e){var n=this._getItemIndex(t),i=this._getItemIndex(Y(".active.carousel-item",this._element));return B.trigger(this._element,"slide.bs.carousel",{relatedTarget:t,direction:e,from:i,to:n})},r._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var e=Y(".active",this._indicatorsElement);e.classList.remove("active"),e.removeAttribute("aria-current");for(var n=F("[data-bs-target]",this._indicatorsElement),i=0;i0)for(var i=0;i=0}function _t(t){return((ut(t)?t.ownerDocument:t.document)||window.document).documentElement}function bt(t){return"html"===lt(t)?t:t.assignedSlot||t.parentNode||t.host||_t(t)}function yt(t){if(!ft(t)||"fixed"===mt(t).position)return null;var e=t.offsetParent;if(e){var n=_t(e);if("body"===lt(e)&&"static"===mt(e).position&&"static"!==mt(n).position)return n}return e}function wt(t){for(var e=ct(t),n=yt(t);n&&vt(n)&&"static"===mt(n).position;)n=yt(n);return n&&"body"===lt(n)&&"static"===mt(n).position?e:n||function(t){for(var e=bt(t);ft(e)&&["html","body"].indexOf(lt(e))<0;){var n=mt(e);if("none"!==n.transform||"none"!==n.perspective||n.willChange&&"auto"!==n.willChange)return e;e=e.parentNode}return null}(t)||e}function Et(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function Tt(t,e,n){return Math.max(t,Math.min(e,n))}function kt(t){return Object.assign(Object.assign({},{top:0,right:0,bottom:0,left:0}),t)}function At(t,e){return e.reduce((function(e,n){return e[n]=t,e}),{})}var Lt={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,n=t.state,i=t.name,o=n.elements.arrow,r=n.modifiersData.popperOffsets,s=ht(n.placement),a=Et(s),l=[it,nt].indexOf(s)>=0?"height":"width";if(o&&r){var c=n.modifiersData[i+"#persistent"].padding,u=pt(o),f="y"===a?tt:it,d="y"===a?et:nt,h=n.rects.reference[l]+n.rects.reference[a]-r[a]-n.rects.popper[l],p=r[a]-n.rects.reference[a],g=wt(o),m=g?"y"===a?g.clientHeight||0:g.clientWidth||0:0,v=h/2-p/2,_=c[f],b=m-u[l]-c[d],y=m/2-u[l]/2+v,w=Tt(_,y,b),E=a;n.modifiersData[i]=((e={})[E]=w,e.centerOffset=w-y,e)}},effect:function(t){var e=t.state,n=t.options,i=t.name,o=n.element,r=void 0===o?"[data-popper-arrow]":o,s=n.padding,a=void 0===s?0:s;null!=r&&("string"!=typeof r||(r=e.elements.popper.querySelector(r)))&>(e.elements.popper,r)&&(e.elements.arrow=r,e.modifiersData[i+"#persistent"]={padding:kt("number"!=typeof a?a:At(a,ot))})},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]},Ot={top:"auto",right:"auto",bottom:"auto",left:"auto"};function Dt(t){var e,n=t.popper,i=t.popperRect,o=t.placement,r=t.offsets,s=t.position,a=t.gpuAcceleration,l=t.adaptive,c=t.roundOffsets?function(t){var e=t.x,n=t.y,i=window.devicePixelRatio||1;return{x:Math.round(e*i)/i||0,y:Math.round(n*i)/i||0}}(r):r,u=c.x,f=void 0===u?0:u,d=c.y,h=void 0===d?0:d,p=r.hasOwnProperty("x"),g=r.hasOwnProperty("y"),m=it,v=tt,_=window;if(l){var b=wt(n);b===ct(n)&&(b=_t(n)),o===tt&&(v=et,h-=b.clientHeight-i.height,h*=a?1:-1),o===it&&(m=nt,f-=b.clientWidth-i.width,f*=a?1:-1)}var y,w=Object.assign({position:s},l&&Ot);return a?Object.assign(Object.assign({},w),{},((y={})[v]=g?"0":"",y[m]=p?"0":"",y.transform=(_.devicePixelRatio||1)<2?"translate("+f+"px, "+h+"px)":"translate3d("+f+"px, "+h+"px, 0)",y)):Object.assign(Object.assign({},w),{},((e={})[v]=g?h+"px":"",e[m]=p?f+"px":"",e.transform="",e))}var xt={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,n=t.options,i=n.gpuAcceleration,o=void 0===i||i,r=n.adaptive,s=void 0===r||r,a=n.roundOffsets,l=void 0===a||a,c={placement:ht(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:o};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign(Object.assign({},e.styles.popper),Dt(Object.assign(Object.assign({},c),{},{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:s,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign(Object.assign({},e.styles.arrow),Dt(Object.assign(Object.assign({},c),{},{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign(Object.assign({},e.attributes.popper),{},{"data-popper-placement":e.placement})},data:{}},Ct={passive:!0},St={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,n=t.instance,i=t.options,o=i.scroll,r=void 0===o||o,s=i.resize,a=void 0===s||s,l=ct(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return r&&c.forEach((function(t){t.addEventListener("scroll",n.update,Ct)})),a&&l.addEventListener("resize",n.update,Ct),function(){r&&c.forEach((function(t){t.removeEventListener("scroll",n.update,Ct)})),a&&l.removeEventListener("resize",n.update,Ct)}},data:{}},jt={left:"right",right:"left",bottom:"top",top:"bottom"};function Nt(t){return t.replace(/left|right|bottom|top/g,(function(t){return jt[t]}))}var Pt={start:"end",end:"start"};function It(t){return t.replace(/start|end/g,(function(t){return Pt[t]}))}function Mt(t){var e=t.getBoundingClientRect();return{width:e.width,height:e.height,top:e.top,right:e.right,bottom:e.bottom,left:e.left,x:e.left,y:e.top}}function Bt(t){var e=ct(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function Ht(t){return Mt(_t(t)).left+Bt(t).scrollLeft}function Rt(t){var e=mt(t),n=e.overflow,i=e.overflowX,o=e.overflowY;return/auto|scroll|overlay|hidden/.test(n+o+i)}function Wt(t,e){void 0===e&&(e=[]);var n=function t(e){return["html","body","#document"].indexOf(lt(e))>=0?e.ownerDocument.body:ft(e)&&Rt(e)?e:t(bt(e))}(t),i="body"===lt(n),o=ct(n),r=i?[o].concat(o.visualViewport||[],Rt(n)?n:[]):n,s=e.concat(r);return i?s:s.concat(Wt(bt(r)))}function Kt(t){return Object.assign(Object.assign({},t),{},{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function Ut(t,e){return"viewport"===e?Kt(function(t){var e=ct(t),n=_t(t),i=e.visualViewport,o=n.clientWidth,r=n.clientHeight,s=0,a=0;return i&&(o=i.width,r=i.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(s=i.offsetLeft,a=i.offsetTop)),{width:o,height:r,x:s+Ht(t),y:a}}(t)):ft(e)?function(t){var e=Mt(t);return e.top=e.top+t.clientTop,e.left=e.left+t.clientLeft,e.bottom=e.top+t.clientHeight,e.right=e.left+t.clientWidth,e.width=t.clientWidth,e.height=t.clientHeight,e.x=e.left,e.y=e.top,e}(e):Kt(function(t){var e=_t(t),n=Bt(t),i=t.ownerDocument.body,o=Math.max(e.scrollWidth,e.clientWidth,i?i.scrollWidth:0,i?i.clientWidth:0),r=Math.max(e.scrollHeight,e.clientHeight,i?i.scrollHeight:0,i?i.clientHeight:0),s=-n.scrollLeft+Ht(t),a=-n.scrollTop;return"rtl"===mt(i||e).direction&&(s+=Math.max(e.clientWidth,i?i.clientWidth:0)-o),{width:o,height:r,x:s,y:a}}(_t(t)))}function zt(t){return t.split("-")[1]}function Ft(t){var e,n=t.reference,i=t.element,o=t.placement,r=o?ht(o):null,s=o?zt(o):null,a=n.x+n.width/2-i.width/2,l=n.y+n.height/2-i.height/2;switch(r){case tt:e={x:a,y:n.y-i.height};break;case et:e={x:a,y:n.y+n.height};break;case nt:e={x:n.x+n.width,y:l};break;case it:e={x:n.x-i.width,y:l};break;default:e={x:n.x,y:n.y}}var c=r?Et(r):null;if(null!=c){var u="y"===c?"height":"width";switch(s){case"start":e[c]=e[c]-(n[u]/2-i[u]/2);break;case"end":e[c]=e[c]+(n[u]/2-i[u]/2)}}return e}function Yt(t,e){void 0===e&&(e={});var n=e,i=n.placement,o=void 0===i?t.placement:i,r=n.boundary,s=void 0===r?"clippingParents":r,a=n.rootBoundary,l=void 0===a?"viewport":a,c=n.elementContext,u=void 0===c?"popper":c,f=n.altBoundary,d=void 0!==f&&f,h=n.padding,p=void 0===h?0:h,g=kt("number"!=typeof p?p:At(p,ot)),m="popper"===u?"reference":"popper",v=t.elements.reference,_=t.rects.popper,b=t.elements[d?m:u],y=function(t,e,n){var i="clippingParents"===e?function(t){var e=Wt(bt(t)),n=["absolute","fixed"].indexOf(mt(t).position)>=0&&ft(t)?wt(t):t;return ut(n)?e.filter((function(t){return ut(t)&>(t,n)&&"body"!==lt(t)})):[]}(t):[].concat(e),o=[].concat(i,[n]),r=o[0],s=o.reduce((function(e,n){var i=Ut(t,n);return e.top=Math.max(i.top,e.top),e.right=Math.min(i.right,e.right),e.bottom=Math.min(i.bottom,e.bottom),e.left=Math.max(i.left,e.left),e}),Ut(t,r));return s.width=s.right-s.left,s.height=s.bottom-s.top,s.x=s.left,s.y=s.top,s}(ut(b)?b:b.contextElement||_t(t.elements.popper),s,l),w=Mt(v),E=Ft({reference:w,element:_,strategy:"absolute",placement:o}),T=Kt(Object.assign(Object.assign({},_),E)),k="popper"===u?T:w,A={top:y.top-k.top+g.top,bottom:k.bottom-y.bottom+g.bottom,left:y.left-k.left+g.left,right:k.right-y.right+g.right},L=t.modifiersData.offset;if("popper"===u&&L){var O=L[o];Object.keys(A).forEach((function(t){var e=[nt,et].indexOf(t)>=0?1:-1,n=[tt,et].indexOf(t)>=0?"y":"x";A[t]+=O[n]*e}))}return A}function qt(t,e){void 0===e&&(e={});var n=e,i=n.placement,o=n.boundary,r=n.rootBoundary,s=n.padding,a=n.flipVariations,l=n.allowedAutoPlacements,c=void 0===l?st:l,u=zt(i),f=u?a?rt:rt.filter((function(t){return zt(t)===u})):ot,d=f.filter((function(t){return c.indexOf(t)>=0}));0===d.length&&(d=f);var h=d.reduce((function(e,n){return e[n]=Yt(t,{placement:n,boundary:o,rootBoundary:r,padding:s})[ht(n)],e}),{});return Object.keys(h).sort((function(t,e){return h[t]-h[e]}))}var Vt={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,n=t.options,i=t.name;if(!e.modifiersData[i]._skip){for(var o=n.mainAxis,r=void 0===o||o,s=n.altAxis,a=void 0===s||s,l=n.fallbackPlacements,c=n.padding,u=n.boundary,f=n.rootBoundary,d=n.altBoundary,h=n.flipVariations,p=void 0===h||h,g=n.allowedAutoPlacements,m=e.options.placement,v=ht(m),_=l||(v!==m&&p?function(t){if("auto"===ht(t))return[];var e=Nt(t);return[It(t),e,It(e)]}(m):[Nt(m)]),b=[m].concat(_).reduce((function(t,n){return t.concat("auto"===ht(n)?qt(e,{placement:n,boundary:u,rootBoundary:f,padding:c,flipVariations:p,allowedAutoPlacements:g}):n)}),[]),y=e.rects.reference,w=e.rects.popper,E=new Map,T=!0,k=b[0],A=0;A=0,C=x?"width":"height",S=Yt(e,{placement:L,boundary:u,rootBoundary:f,altBoundary:d,padding:c}),j=x?D?nt:it:D?et:tt;y[C]>w[C]&&(j=Nt(j));var N=Nt(j),P=[];if(r&&P.push(S[O]<=0),a&&P.push(S[j]<=0,S[N]<=0),P.every((function(t){return t}))){k=L,T=!1;break}E.set(L,P)}if(T)for(var I=function(t){var e=b.find((function(e){var n=E.get(e);if(n)return n.slice(0,t).every((function(t){return t}))}));if(e)return k=e,"break"},M=p?3:1;M>0&&"break"!==I(M);M--);e.placement!==k&&(e.modifiersData[i]._skip=!0,e.placement=k,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function Xt(t,e,n){return void 0===n&&(n={x:0,y:0}),{top:t.top-e.height-n.y,right:t.right-e.width+n.x,bottom:t.bottom-e.height+n.y,left:t.left-e.width-n.x}}function Qt(t){return[tt,nt,et,it].some((function(e){return t[e]>=0}))}var $t={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,n=t.name,i=e.rects.reference,o=e.rects.popper,r=e.modifiersData.preventOverflow,s=Yt(e,{elementContext:"reference"}),a=Yt(e,{altBoundary:!0}),l=Xt(s,i),c=Xt(a,o,r),u=Qt(l),f=Qt(c);e.modifiersData[n]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:u,hasPopperEscaped:f},e.attributes.popper=Object.assign(Object.assign({},e.attributes.popper),{},{"data-popper-reference-hidden":u,"data-popper-escaped":f})}},Gt={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,n=t.options,i=t.name,o=n.offset,r=void 0===o?[0,0]:o,s=st.reduce((function(t,n){return t[n]=function(t,e,n){var i=ht(t),o=[it,tt].indexOf(i)>=0?-1:1,r="function"==typeof n?n(Object.assign(Object.assign({},e),{},{placement:t})):n,s=r[0],a=r[1];return s=s||0,a=(a||0)*o,[it,nt].indexOf(i)>=0?{x:a,y:s}:{x:s,y:a}}(n,e.rects,r),t}),{}),a=s[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[i]=s}},Zt={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,n=t.name;e.modifiersData[n]=Ft({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},Jt={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,n=t.options,i=t.name,o=n.mainAxis,r=void 0===o||o,s=n.altAxis,a=void 0!==s&&s,l=n.boundary,c=n.rootBoundary,u=n.altBoundary,f=n.padding,d=n.tether,h=void 0===d||d,p=n.tetherOffset,g=void 0===p?0:p,m=Yt(e,{boundary:l,rootBoundary:c,padding:f,altBoundary:u}),v=ht(e.placement),_=zt(e.placement),b=!_,y=Et(v),w="x"===y?"y":"x",E=e.modifiersData.popperOffsets,T=e.rects.reference,k=e.rects.popper,A="function"==typeof g?g(Object.assign(Object.assign({},e.rects),{},{placement:e.placement})):g,L={x:0,y:0};if(E){if(r){var O="y"===y?tt:it,D="y"===y?et:nt,x="y"===y?"height":"width",C=E[y],S=E[y]+m[O],j=E[y]-m[D],N=h?-k[x]/2:0,P="start"===_?T[x]:k[x],I="start"===_?-k[x]:-T[x],M=e.elements.arrow,B=h&&M?pt(M):{width:0,height:0},H=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},R=H[O],W=H[D],K=Tt(0,T[x],B[x]),U=b?T[x]/2-N-K-R-A:P-K-R-A,z=b?-T[x]/2+N+K+W+A:I+K+W+A,F=e.elements.arrow&&wt(e.elements.arrow),Y=F?"y"===y?F.clientTop||0:F.clientLeft||0:0,q=e.modifiersData.offset?e.modifiersData.offset[e.placement][y]:0,V=E[y]+U-q-Y,X=E[y]+z-q,Q=Tt(h?Math.min(S,V):S,C,h?Math.max(j,X):j);E[y]=Q,L[y]=Q-C}if(a){var $="x"===y?tt:it,G="x"===y?et:nt,Z=E[w],J=Tt(Z+m[$],Z,Z-m[G]);E[w]=J,L[w]=J-Z}e.modifiersData[i]=L}},requiresIfExists:["offset"]};function te(t,e,n){void 0===n&&(n=!1);var i,o,r=_t(e),s=Mt(t),a=ft(e),l={scrollLeft:0,scrollTop:0},c={x:0,y:0};return(a||!a&&!n)&&(("body"!==lt(e)||Rt(r))&&(l=(i=e)!==ct(i)&&ft(i)?{scrollLeft:(o=i).scrollLeft,scrollTop:o.scrollTop}:Bt(i)),ft(e)?((c=Mt(e)).x+=e.clientLeft,c.y+=e.clientTop):r&&(c.x=Ht(r))),{x:s.left+l.scrollLeft-c.x,y:s.top+l.scrollTop-c.y,width:s.width,height:s.height}}var ee={placement:"bottom",modifiers:[],strategy:"absolute"};function ne(){for(var t=arguments.length,e=new Array(t),n=0;n0&&r--,"ArrowDown"===t.key&&rdocument.documentElement.clientHeight;e||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");var n=u(this._dialog);B.off(this._element,"transitionend"),B.one(this._element,"transitionend",(function(){t._element.classList.remove("modal-static"),e||(B.one(t._element,"transitionend",(function(){t._element.style.overflowY=""})),h(t._element,n))})),h(this._element,n),this._element.focus()}},r._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;(!this._isBodyOverflowing&&t&&!b||this._isBodyOverflowing&&!t&&b)&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),(this._isBodyOverflowing&&!t&&!b||!this._isBodyOverflowing&&t&&b)&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},r._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},r._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)
',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:[0,0],container:!1,fallbackPlacements:["top","right","bottom","left"],boundary:"clippingParents",customClass:"",sanitize:!0,sanitizeFn:null,allowList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},Ce={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},Se=function(t){function o(e,n){var i;if(void 0===ae)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");return(i=t.call(this,e)||this)._isEnabled=!0,i._timeout=0,i._hoverState="",i._activeTrigger={},i._popper=null,i.config=i._getConfig(n),i.tip=null,i._setListeners(),i}i(o,t);var r=o.prototype;return r.enable=function(){this._isEnabled=!0},r.disable=function(){this._isEnabled=!1},r.toggleEnabled=function(){this._isEnabled=!this._isEnabled},r.toggle=function(t){if(this._isEnabled)if(t){var e=this._initializeOnDelegatedTarget(t);e._activeTrigger.click=!e._activeTrigger.click,e._isWithActiveTrigger()?e._enter(null,e):e._leave(null,e)}else{if(this.getTipElement().classList.contains("show"))return void this._leave(null,this);this._enter(null,this)}},r.dispose=function(){clearTimeout(this._timeout),B.off(this._element,this.constructor.EVENT_KEY),B.off(this._element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this.tip&&this.tip.parentNode&&this.tip.parentNode.removeChild(this.tip),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.config=null,this.tip=null,t.prototype.dispose.call(this)},r.show=function(){var t=this;if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(this.isWithContent()&&this._isEnabled){var e=B.trigger(this._element,this.constructor.Event.SHOW),n=function t(e){if(!document.documentElement.attachShadow)return null;if("function"==typeof e.getRootNode){var n=e.getRootNode();return n instanceof ShadowRoot?n:null}return e instanceof ShadowRoot?e:e.parentNode?t(e.parentNode):null}(this._element),i=null===n?this._element.ownerDocument.documentElement.contains(this._element):n.contains(this._element);if(!e.defaultPrevented&&i){var o=this.getTipElement(),r=s(this.constructor.NAME);o.setAttribute("id",r),this._element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&o.classList.add("fade");var a="function"==typeof this.config.placement?this.config.placement.call(this,o,this._element):this.config.placement,l=this._getAttachment(a);this._addAttachmentClass(l);var c=this._getContainer();E(o,this.constructor.DATA_KEY,this),this._element.ownerDocument.documentElement.contains(this.tip)||c.appendChild(o),B.trigger(this._element,this.constructor.Event.INSERTED),this._popper=se(this._element,o,this._getPopperConfig(l)),o.classList.add("show");var f,d,p="function"==typeof this.config.customClass?this.config.customClass():this.config.customClass;p&&(f=o.classList).add.apply(f,p.split(" ")),"ontouchstart"in document.documentElement&&(d=[]).concat.apply(d,document.body.children).forEach((function(t){B.on(t,"mouseover",(function(){}))}));var g=function(){var e=t._hoverState;t._hoverState=null,B.trigger(t._element,t.constructor.Event.SHOWN),"out"===e&&t._leave(null,t)};if(this.tip.classList.contains("fade")){var m=u(this.tip);B.one(this.tip,"transitionend",g),h(this.tip,m)}else g()}}},r.hide=function(){var t=this;if(this._popper){var e=this.getTipElement(),n=function(){"show"!==t._hoverState&&e.parentNode&&e.parentNode.removeChild(e),t._cleanTipClass(),t._element.removeAttribute("aria-describedby"),B.trigger(t._element,t.constructor.Event.HIDDEN),t._popper&&(t._popper.destroy(),t._popper=null)};if(!B.trigger(this._element,this.constructor.Event.HIDE).defaultPrevented){var i;if(e.classList.remove("show"),"ontouchstart"in document.documentElement&&(i=[]).concat.apply(i,document.body.children).forEach((function(t){return B.off(t,"mouseover",m)})),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,this.tip.classList.contains("fade")){var o=u(e);B.one(e,"transitionend",n),h(e,o)}else n();this._hoverState=""}}},r.update=function(){null!==this._popper&&this._popper.update()},r.isWithContent=function(){return Boolean(this.getTitle())},r.getTipElement=function(){if(this.tip)return this.tip;var t=document.createElement("div");return t.innerHTML=this.config.template,this.tip=t.children[0],this.tip},r.setContent=function(){var t=this.getTipElement();this.setElementContent(Y(".tooltip-inner",t),this.getTitle()),t.classList.remove("fade","show")},r.setElementContent=function(t,e){if(null!==t)return"object"==typeof e&&d(e)?(e.jquery&&(e=e[0]),void(this.config.html?e.parentNode!==t&&(t.innerHTML="",t.appendChild(e)):t.textContent=e.textContent)):void(this.config.html?(this.config.sanitize&&(e=ke(e,this.config.allowList,this.config.sanitizeFn)),t.innerHTML=e):t.textContent=e)},r.getTitle=function(){var t=this._element.getAttribute("data-bs-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this._element):this.config.title),t},r.updateAttachment=function(t){return"right"===t?"end":"left"===t?"start":t},r._initializeOnDelegatedTarget=function(t,e){var n=this.constructor.DATA_KEY;return(e=e||T(t.delegateTarget,n))||(e=new this.constructor(t.delegateTarget,this._getDelegateConfig()),E(t.delegateTarget,n,e)),e},r._getOffset=function(){var t=this,e=this.config.offset;return"string"==typeof e?e.split(",").map((function(t){return Number.parseInt(t,10)})):"function"==typeof e?function(n){return e(n,t._element)}:e},r._getPopperConfig=function(t){var e=this,i={placement:t,modifiers:[{name:"flip",options:{altBoundary:!0,fallbackPlacements:this.config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this.config.boundary}},{name:"arrow",options:{element:"."+this.constructor.NAME+"-arrow"}},{name:"onChange",enabled:!0,phase:"afterWrite",fn:function(t){return e._handlePopperPlacementChange(t)}}],onFirstUpdate:function(t){t.options.placement!==t.placement&&e._handlePopperPlacementChange(t)}};return n({},i,"function"==typeof this.config.popperConfig?this.config.popperConfig(i):this.config.popperConfig)},r._addAttachmentClass=function(t){this.getTipElement().classList.add("bs-tooltip-"+this.updateAttachment(t))},r._getContainer=function(){return!1===this.config.container?document.body:d(this.config.container)?this.config.container:Y(this.config.container)},r._getAttachment=function(t){return De[t.toUpperCase()]},r._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(e){if("click"===e)B.on(t._element,t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==e){var n="hover"===e?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,i="hover"===e?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;B.on(t._element,n,t.config.selector,(function(e){return t._enter(e)})),B.on(t._element,i,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t._element&&t.hide()},B.on(this._element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=n({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},r._fixTitle=function(){var t=this._element.getAttribute("title"),e=typeof this._element.getAttribute("data-bs-original-title");(t||"string"!==e)&&(this._element.setAttribute("data-bs-original-title",t||""),!t||this._element.getAttribute("aria-label")||this._element.textContent||this._element.setAttribute("aria-label",t),this._element.setAttribute("title",""))},r._enter=function(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),e.getTipElement().classList.contains("show")||"show"===e._hoverState?e._hoverState="show":(clearTimeout(e._timeout),e._hoverState="show",e.config.delay&&e.config.delay.show?e._timeout=setTimeout((function(){"show"===e._hoverState&&e.show()}),e.config.delay.show):e.show())},r._leave=function(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState="out",e.config.delay&&e.config.delay.hide?e._timeout=setTimeout((function(){"out"===e._hoverState&&e.hide()}),e.config.delay.hide):e.hide())},r._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},r._getConfig=function(t){var e=z.getDataAttributes(this._element);return Object.keys(e).forEach((function(t){Le.has(t)&&delete e[t]})),t&&"object"==typeof t.container&&t.container.jquery&&(t.container=t.container[0]),"number"==typeof(t=n({},this.constructor.Default,e,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),p("tooltip",t,this.constructor.DefaultType),t.sanitize&&(t.template=ke(t.template,t.allowList,t.sanitizeFn)),t},r._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},r._cleanTipClass=function(){var t=this.getTipElement(),e=t.getAttribute("class").match(Ae);null!==e&&e.length>0&&e.map((function(t){return t.trim()})).forEach((function(e){return t.classList.remove(e)}))},r._handlePopperPlacementChange=function(t){var e=t.state;e&&(this.tip=e.elements.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(e.placement)))},o.jQueryInterface=function(t){return this.each((function(){var e=T(this,"bs.tooltip"),n="object"==typeof t&&t;if((e||!/dispose|hide/.test(t))&&(e||(e=new o(this,n)),"string"==typeof t)){if(void 0===e[t])throw new TypeError('No method named "'+t+'"');e[t]()}}))},e(o,null,[{key:"Default",get:function(){return xe}},{key:"NAME",get:function(){return"tooltip"}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return Ce}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return Oe}}]),o}(H);y("tooltip",Se);var je=new RegExp("(^|\\s)bs-popover\\S+","g"),Ne=n({},Se.Default,{placement:"right",offset:[0,8],trigger:"click",content:"",template:''}),Pe=n({},Se.DefaultType,{content:"(string|element|function)"}),Ie={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},Me=function(t){function n(){return t.apply(this,arguments)||this}i(n,t);var o=n.prototype;return o.isWithContent=function(){return this.getTitle()||this._getContent()},o.setContent=function(){var t=this.getTipElement();this.setElementContent(Y(".popover-header",t),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this._element)),this.setElementContent(Y(".popover-body",t),e),t.classList.remove("fade","show")},o._addAttachmentClass=function(t){this.getTipElement().classList.add("bs-popover-"+this.updateAttachment(t))},o._getContent=function(){return this._element.getAttribute("data-bs-content")||this.config.content},o._cleanTipClass=function(){var t=this.getTipElement(),e=t.getAttribute("class").match(je);null!==e&&e.length>0&&e.map((function(t){return t.trim()})).forEach((function(e){return t.classList.remove(e)}))},n.jQueryInterface=function(t){return this.each((function(){var e=T(this,"bs.popover"),i="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new n(this,i),E(this,"bs.popover",e)),"string"==typeof t)){if(void 0===e[t])throw new TypeError('No method named "'+t+'"');e[t]()}}))},e(n,null,[{key:"Default",get:function(){return Ne}},{key:"NAME",get:function(){return"popover"}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return Ie}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return Pe}}]),n}(Se);y("popover",Me);var Be={offset:10,method:"auto",target:""},He={offset:"number",method:"string",target:"(string|element)"},Re=function(t){function o(e,n){var i;return(i=t.call(this,e)||this)._scrollElement="BODY"===e.tagName?window:e,i._config=i._getConfig(n),i._selector=i._config.target+" .nav-link, "+i._config.target+" .list-group-item, "+i._config.target+" .dropdown-item",i._offsets=[],i._targets=[],i._activeTarget=null,i._scrollHeight=0,B.on(i._scrollElement,"scroll.bs.scrollspy",(function(){return i._process()})),i.refresh(),i._process(),i}i(o,t);var r=o.prototype;return r.refresh=function(){var t=this,e=this._scrollElement===this._scrollElement.window?"offset":"position",n="auto"===this._config.method?e:this._config.method,i="position"===n?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),F(this._selector).map((function(t){var e=l(t),o=e?Y(e):null;if(o){var r=o.getBoundingClientRect();if(r.width||r.height)return[z[n](o).top+i,e]}return null})).filter((function(t){return t})).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},r.dispose=function(){t.prototype.dispose.call(this),B.off(this._scrollElement,".bs.scrollspy"),this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},r._getConfig=function(t){if("string"!=typeof(t=n({},Be,"object"==typeof t&&t?t:{})).target&&d(t.target)){var e=t.target.id;e||(e=s("scrollspy"),t.target.id=e),t.target="#"+e}return p("scrollspy",t,He),t},r._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},r._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},r._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},r._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;)this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&(void 0===this._offsets[o+1]||t li > .active":".active";e=(e=F(o,i))[e.length-1]}var r=e?B.trigger(e,"hide.bs.tab",{relatedTarget:this._element}):null;if(!(B.trigger(this._element,"show.bs.tab",{relatedTarget:e}).defaultPrevented||null!==r&&r.defaultPrevented)){this._activate(this._element,i);var s=function(){B.trigger(e,"hidden.bs.tab",{relatedTarget:t._element}),B.trigger(t._element,"shown.bs.tab",{relatedTarget:e})};n?this._activate(n,n.parentNode,s):s()}}},o._activate=function(t,e,n){var i=this,o=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?q(e,".active"):F(":scope > li > .active",e))[0],r=n&&o&&o.classList.contains("fade"),s=function(){return i._transitionComplete(t,o,n)};if(o&&r){var a=u(o);o.classList.remove("show"),B.one(o,"transitionend",s),h(o,a)}else s()},o._transitionComplete=function(t,e,n){if(e){e.classList.remove("active");var i=Y(":scope > .dropdown-menu .active",e.parentNode);i&&i.classList.remove("active"),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}t.classList.add("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),v(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&t.parentNode.classList.contains("dropdown-menu")&&(t.closest(".dropdown")&&F(".dropdown-toggle").forEach((function(t){return t.classList.add("active")})),t.setAttribute("aria-expanded",!0)),n&&n()},n.jQueryInterface=function(t){return this.each((function(){var e=T(this,"bs.tab")||new n(this);if("string"==typeof t){if(void 0===e[t])throw new TypeError('No method named "'+t+'"');e[t]()}}))},e(n,null,[{key:"DATA_KEY",get:function(){return"bs.tab"}}]),n}(H);B.on(document,"click.bs.tab.data-api",'[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',(function(t){t.preventDefault(),(T(this,"bs.tab")||new We(this)).show()})),y("tab",We);var Ke={animation:"boolean",autohide:"boolean",delay:"number"},Ue={animation:!0,autohide:!0,delay:5e3},ze=function(t){function o(e,n){var i;return(i=t.call(this,e)||this)._config=i._getConfig(n),i._timeout=null,i._setListeners(),i}i(o,t);var r=o.prototype;return r.show=function(){var t=this;if(!B.trigger(this._element,"show.bs.toast").defaultPrevented){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var e=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),B.trigger(t._element,"shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove("hide"),v(this._element),this._element.classList.add("showing"),this._config.animation){var n=u(this._element);B.one(this._element,"transitionend",e),h(this._element,n)}else e()}},r.hide=function(){var t=this;if(this._element.classList.contains("show")&&!B.trigger(this._element,"hide.bs.toast").defaultPrevented){var e=function(){t._element.classList.add("hide"),B.trigger(t._element,"hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var n=u(this._element);B.one(this._element,"transitionend",e),h(this._element,n)}else e()}},r.dispose=function(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),B.off(this._element,"click.dismiss.bs.toast"),t.prototype.dispose.call(this),this._config=null},r._getConfig=function(t){return t=n({},Ue,z.getDataAttributes(this._element),"object"==typeof t&&t?t:{}),p("toast",t,this.constructor.DefaultType),t},r._setListeners=function(){var t=this;B.on(this._element,"click.dismiss.bs.toast",'[data-bs-dismiss="toast"]',(function(){return t.hide()}))},r._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null},o.jQueryInterface=function(t){return this.each((function(){var e=T(this,"bs.toast");if(e||(e=new o(this,"object"==typeof t&&t)),"string"==typeof t){if(void 0===e[t])throw new TypeError('No method named "'+t+'"');e[t](this)}}))},e(o,null,[{key:"DefaultType",get:function(){return Ke}},{key:"Default",get:function(){return Ue}},{key:"DATA_KEY",get:function(){return"bs.toast"}}]),o}(H);return y("toast",ze),{Alert:R,Button:W,Carousel:$,Collapse:J,Dropdown:ve,Modal:ye,Popover:Me,ScrollSpy:Re,Tab:We,Toast:ze,Tooltip:Se}})); +/*! + * Bootstrap v5.0.0-beta2 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";function t(t,e){for(var n=0;n0,i._pointerEvent=Boolean(window.PointerEvent),i._addEventListeners(),i}i(o,t);var r=o.prototype;return r.next=function(){this._isSliding||this._slide("next")},r.nextWhenVisible=function(){!document.hidden&&g(this._element)&&this.next()},r.prev=function(){this._isSliding||this._slide("prev")},r.pause=function(t){t||(this._isPaused=!0),Y(".carousel-item-next, .carousel-item-prev",this._element)&&(f(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},r.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},r.to=function(t){var e=this;this._activeElement=Y(".active.carousel-item",this._element);var n=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)B.one(this._element,"slid.bs.carousel",(function(){return e.to(t)}));else{if(n===t)return this.pause(),void this.cycle();var i=t>n?"next":"prev";this._slide(i,this._items[t])}},r.dispose=function(){t.prototype.dispose.call(this),B.off(this._element,".bs.carousel"),this._items=null,this._config=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},r._getConfig=function(t){return t=n({},X,t),p("carousel",t,Q),t},r._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&(b?this.next():this.prev()),e<0&&(b?this.prev():this.next())}},r._addEventListeners=function(){var t=this;this._config.keyboard&&B.on(this._element,"keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&(B.on(this._element,"mouseenter.bs.carousel",(function(e){return t.pause(e)})),B.on(this._element,"mouseleave.bs.carousel",(function(e){return t.cycle(e)}))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()},r._addTouchEventListeners=function(){var t=this,e=function(e){!t._pointerEvent||"pen"!==e.pointerType&&"touch"!==e.pointerType?t._pointerEvent||(t.touchStartX=e.touches[0].clientX):t.touchStartX=e.clientX},n=function(e){!t._pointerEvent||"pen"!==e.pointerType&&"touch"!==e.pointerType||(t.touchDeltaX=e.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};F(".carousel-item img",this._element).forEach((function(t){B.on(t,"dragstart.bs.carousel",(function(t){return t.preventDefault()}))})),this._pointerEvent?(B.on(this._element,"pointerdown.bs.carousel",(function(t){return e(t)})),B.on(this._element,"pointerup.bs.carousel",(function(t){return n(t)})),this._element.classList.add("pointer-event")):(B.on(this._element,"touchstart.bs.carousel",(function(t){return e(t)})),B.on(this._element,"touchmove.bs.carousel",(function(e){return function(e){e.touches&&e.touches.length>1?t.touchDeltaX=0:t.touchDeltaX=e.touches[0].clientX-t.touchStartX}(e)})),B.on(this._element,"touchend.bs.carousel",(function(t){return n(t)})))},r._keydown=function(t){/input|textarea/i.test(t.target.tagName)||("ArrowLeft"===t.key?(t.preventDefault(),b?this.next():this.prev()):"ArrowRight"===t.key&&(t.preventDefault(),b?this.prev():this.next()))},r._getItemIndex=function(t){return this._items=t&&t.parentNode?F(".carousel-item",t.parentNode):[],this._items.indexOf(t)},r._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),r=this._items.length-1;if((i&&0===o||n&&o===r)&&!this._config.wrap)return e;var s=(o+("prev"===t?-1:1))%this._items.length;return-1===s?this._items[this._items.length-1]:this._items[s]},r._triggerSlideEvent=function(t,e){var n=this._getItemIndex(t),i=this._getItemIndex(Y(".active.carousel-item",this._element));return B.trigger(this._element,"slide.bs.carousel",{relatedTarget:t,direction:e,from:i,to:n})},r._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var e=Y(".active",this._indicatorsElement);e.classList.remove("active"),e.removeAttribute("aria-current");for(var n=F("[data-bs-target]",this._indicatorsElement),i=0;i0)for(var i=0;i=0}function _t(t){return((ut(t)?t.ownerDocument:t.document)||window.document).documentElement}function bt(t){return"html"===lt(t)?t:t.assignedSlot||t.parentNode||t.host||_t(t)}function yt(t){if(!ft(t)||"fixed"===mt(t).position)return null;var e=t.offsetParent;if(e){var n=_t(e);if("body"===lt(e)&&"static"===mt(e).position&&"static"!==mt(n).position)return n}return e}function wt(t){for(var e=ct(t),n=yt(t);n&&vt(n)&&"static"===mt(n).position;)n=yt(n);return n&&"body"===lt(n)&&"static"===mt(n).position?e:n||function(t){for(var e=bt(t);ft(e)&&["html","body"].indexOf(lt(e))<0;){var n=mt(e);if("none"!==n.transform||"none"!==n.perspective||n.willChange&&"auto"!==n.willChange)return e;e=e.parentNode}return null}(t)||e}function Et(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function Tt(t,e,n){return Math.max(t,Math.min(e,n))}function kt(t){return Object.assign(Object.assign({},{top:0,right:0,bottom:0,left:0}),t)}function At(t,e){return e.reduce((function(e,n){return e[n]=t,e}),{})}var Lt={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,n=t.state,i=t.name,o=n.elements.arrow,r=n.modifiersData.popperOffsets,s=ht(n.placement),a=Et(s),l=[it,nt].indexOf(s)>=0?"height":"width";if(o&&r){var c=n.modifiersData[i+"#persistent"].padding,u=pt(o),f="y"===a?tt:it,d="y"===a?et:nt,h=n.rects.reference[l]+n.rects.reference[a]-r[a]-n.rects.popper[l],p=r[a]-n.rects.reference[a],g=wt(o),m=g?"y"===a?g.clientHeight||0:g.clientWidth||0:0,v=h/2-p/2,_=c[f],b=m-u[l]-c[d],y=m/2-u[l]/2+v,w=Tt(_,y,b),E=a;n.modifiersData[i]=((e={})[E]=w,e.centerOffset=w-y,e)}},effect:function(t){var e=t.state,n=t.options,i=t.name,o=n.element,r=void 0===o?"[data-popper-arrow]":o,s=n.padding,a=void 0===s?0:s;null!=r&&("string"!=typeof r||(r=e.elements.popper.querySelector(r)))&>(e.elements.popper,r)&&(e.elements.arrow=r,e.modifiersData[i+"#persistent"]={padding:kt("number"!=typeof a?a:At(a,ot))})},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]},Ot={top:"auto",right:"auto",bottom:"auto",left:"auto"};function Dt(t){var e,n=t.popper,i=t.popperRect,o=t.placement,r=t.offsets,s=t.position,a=t.gpuAcceleration,l=t.adaptive,c=t.roundOffsets?function(t){var e=t.x,n=t.y,i=window.devicePixelRatio||1;return{x:Math.round(e*i)/i||0,y:Math.round(n*i)/i||0}}(r):r,u=c.x,f=void 0===u?0:u,d=c.y,h=void 0===d?0:d,p=r.hasOwnProperty("x"),g=r.hasOwnProperty("y"),m=it,v=tt,_=window;if(l){var b=wt(n);b===ct(n)&&(b=_t(n)),o===tt&&(v=et,h-=b.clientHeight-i.height,h*=a?1:-1),o===it&&(m=nt,f-=b.clientWidth-i.width,f*=a?1:-1)}var y,w=Object.assign({position:s},l&&Ot);return a?Object.assign(Object.assign({},w),{},((y={})[v]=g?"0":"",y[m]=p?"0":"",y.transform=(_.devicePixelRatio||1)<2?"translate("+f+"px, "+h+"px)":"translate3d("+f+"px, "+h+"px, 0)",y)):Object.assign(Object.assign({},w),{},((e={})[v]=g?h+"px":"",e[m]=p?f+"px":"",e.transform="",e))}var xt={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,n=t.options,i=n.gpuAcceleration,o=void 0===i||i,r=n.adaptive,s=void 0===r||r,a=n.roundOffsets,l=void 0===a||a,c={placement:ht(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:o};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign(Object.assign({},e.styles.popper),Dt(Object.assign(Object.assign({},c),{},{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:s,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign(Object.assign({},e.styles.arrow),Dt(Object.assign(Object.assign({},c),{},{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign(Object.assign({},e.attributes.popper),{},{"data-popper-placement":e.placement})},data:{}},Ct={passive:!0},St={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,n=t.instance,i=t.options,o=i.scroll,r=void 0===o||o,s=i.resize,a=void 0===s||s,l=ct(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return r&&c.forEach((function(t){t.addEventListener("scroll",n.update,Ct)})),a&&l.addEventListener("resize",n.update,Ct),function(){r&&c.forEach((function(t){t.removeEventListener("scroll",n.update,Ct)})),a&&l.removeEventListener("resize",n.update,Ct)}},data:{}},jt={left:"right",right:"left",bottom:"top",top:"bottom"};function Nt(t){return t.replace(/left|right|bottom|top/g,(function(t){return jt[t]}))}var Pt={start:"end",end:"start"};function It(t){return t.replace(/start|end/g,(function(t){return Pt[t]}))}function Mt(t){var e=t.getBoundingClientRect();return{width:e.width,height:e.height,top:e.top,right:e.right,bottom:e.bottom,left:e.left,x:e.left,y:e.top}}function Bt(t){var e=ct(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function Ht(t){return Mt(_t(t)).left+Bt(t).scrollLeft}function Rt(t){var e=mt(t),n=e.overflow,i=e.overflowX,o=e.overflowY;return/auto|scroll|overlay|hidden/.test(n+o+i)}function Wt(t,e){void 0===e&&(e=[]);var n=function t(e){return["html","body","#document"].indexOf(lt(e))>=0?e.ownerDocument.body:ft(e)&&Rt(e)?e:t(bt(e))}(t),i="body"===lt(n),o=ct(n),r=i?[o].concat(o.visualViewport||[],Rt(n)?n:[]):n,s=e.concat(r);return i?s:s.concat(Wt(bt(r)))}function Kt(t){return Object.assign(Object.assign({},t),{},{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function Ut(t,e){return"viewport"===e?Kt(function(t){var e=ct(t),n=_t(t),i=e.visualViewport,o=n.clientWidth,r=n.clientHeight,s=0,a=0;return i&&(o=i.width,r=i.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(s=i.offsetLeft,a=i.offsetTop)),{width:o,height:r,x:s+Ht(t),y:a}}(t)):ft(e)?function(t){var e=Mt(t);return e.top=e.top+t.clientTop,e.left=e.left+t.clientLeft,e.bottom=e.top+t.clientHeight,e.right=e.left+t.clientWidth,e.width=t.clientWidth,e.height=t.clientHeight,e.x=e.left,e.y=e.top,e}(e):Kt(function(t){var e=_t(t),n=Bt(t),i=t.ownerDocument.body,o=Math.max(e.scrollWidth,e.clientWidth,i?i.scrollWidth:0,i?i.clientWidth:0),r=Math.max(e.scrollHeight,e.clientHeight,i?i.scrollHeight:0,i?i.clientHeight:0),s=-n.scrollLeft+Ht(t),a=-n.scrollTop;return"rtl"===mt(i||e).direction&&(s+=Math.max(e.clientWidth,i?i.clientWidth:0)-o),{width:o,height:r,x:s,y:a}}(_t(t)))}function zt(t){return t.split("-")[1]}function Ft(t){var e,n=t.reference,i=t.element,o=t.placement,r=o?ht(o):null,s=o?zt(o):null,a=n.x+n.width/2-i.width/2,l=n.y+n.height/2-i.height/2;switch(r){case tt:e={x:a,y:n.y-i.height};break;case et:e={x:a,y:n.y+n.height};break;case nt:e={x:n.x+n.width,y:l};break;case it:e={x:n.x-i.width,y:l};break;default:e={x:n.x,y:n.y}}var c=r?Et(r):null;if(null!=c){var u="y"===c?"height":"width";switch(s){case"start":e[c]=e[c]-(n[u]/2-i[u]/2);break;case"end":e[c]=e[c]+(n[u]/2-i[u]/2)}}return e}function Yt(t,e){void 0===e&&(e={});var n=e,i=n.placement,o=void 0===i?t.placement:i,r=n.boundary,s=void 0===r?"clippingParents":r,a=n.rootBoundary,l=void 0===a?"viewport":a,c=n.elementContext,u=void 0===c?"popper":c,f=n.altBoundary,d=void 0!==f&&f,h=n.padding,p=void 0===h?0:h,g=kt("number"!=typeof p?p:At(p,ot)),m="popper"===u?"reference":"popper",v=t.elements.reference,_=t.rects.popper,b=t.elements[d?m:u],y=function(t,e,n){var i="clippingParents"===e?function(t){var e=Wt(bt(t)),n=["absolute","fixed"].indexOf(mt(t).position)>=0&&ft(t)?wt(t):t;return ut(n)?e.filter((function(t){return ut(t)&>(t,n)&&"body"!==lt(t)})):[]}(t):[].concat(e),o=[].concat(i,[n]),r=o[0],s=o.reduce((function(e,n){var i=Ut(t,n);return e.top=Math.max(i.top,e.top),e.right=Math.min(i.right,e.right),e.bottom=Math.min(i.bottom,e.bottom),e.left=Math.max(i.left,e.left),e}),Ut(t,r));return s.width=s.right-s.left,s.height=s.bottom-s.top,s.x=s.left,s.y=s.top,s}(ut(b)?b:b.contextElement||_t(t.elements.popper),s,l),w=Mt(v),E=Ft({reference:w,element:_,strategy:"absolute",placement:o}),T=Kt(Object.assign(Object.assign({},_),E)),k="popper"===u?T:w,A={top:y.top-k.top+g.top,bottom:k.bottom-y.bottom+g.bottom,left:y.left-k.left+g.left,right:k.right-y.right+g.right},L=t.modifiersData.offset;if("popper"===u&&L){var O=L[o];Object.keys(A).forEach((function(t){var e=[nt,et].indexOf(t)>=0?1:-1,n=[tt,et].indexOf(t)>=0?"y":"x";A[t]+=O[n]*e}))}return A}function qt(t,e){void 0===e&&(e={});var n=e,i=n.placement,o=n.boundary,r=n.rootBoundary,s=n.padding,a=n.flipVariations,l=n.allowedAutoPlacements,c=void 0===l?st:l,u=zt(i),f=u?a?rt:rt.filter((function(t){return zt(t)===u})):ot,d=f.filter((function(t){return c.indexOf(t)>=0}));0===d.length&&(d=f);var h=d.reduce((function(e,n){return e[n]=Yt(t,{placement:n,boundary:o,rootBoundary:r,padding:s})[ht(n)],e}),{});return Object.keys(h).sort((function(t,e){return h[t]-h[e]}))}var Vt={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,n=t.options,i=t.name;if(!e.modifiersData[i]._skip){for(var o=n.mainAxis,r=void 0===o||o,s=n.altAxis,a=void 0===s||s,l=n.fallbackPlacements,c=n.padding,u=n.boundary,f=n.rootBoundary,d=n.altBoundary,h=n.flipVariations,p=void 0===h||h,g=n.allowedAutoPlacements,m=e.options.placement,v=ht(m),_=l||(v!==m&&p?function(t){if("auto"===ht(t))return[];var e=Nt(t);return[It(t),e,It(e)]}(m):[Nt(m)]),b=[m].concat(_).reduce((function(t,n){return t.concat("auto"===ht(n)?qt(e,{placement:n,boundary:u,rootBoundary:f,padding:c,flipVariations:p,allowedAutoPlacements:g}):n)}),[]),y=e.rects.reference,w=e.rects.popper,E=new Map,T=!0,k=b[0],A=0;A=0,C=x?"width":"height",S=Yt(e,{placement:L,boundary:u,rootBoundary:f,altBoundary:d,padding:c}),j=x?D?nt:it:D?et:tt;y[C]>w[C]&&(j=Nt(j));var N=Nt(j),P=[];if(r&&P.push(S[O]<=0),a&&P.push(S[j]<=0,S[N]<=0),P.every((function(t){return t}))){k=L,T=!1;break}E.set(L,P)}if(T)for(var I=function(t){var e=b.find((function(e){var n=E.get(e);if(n)return n.slice(0,t).every((function(t){return t}))}));if(e)return k=e,"break"},M=p?3:1;M>0&&"break"!==I(M);M--);e.placement!==k&&(e.modifiersData[i]._skip=!0,e.placement=k,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function Xt(t,e,n){return void 0===n&&(n={x:0,y:0}),{top:t.top-e.height-n.y,right:t.right-e.width+n.x,bottom:t.bottom-e.height+n.y,left:t.left-e.width-n.x}}function Qt(t){return[tt,nt,et,it].some((function(e){return t[e]>=0}))}var $t={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,n=t.name,i=e.rects.reference,o=e.rects.popper,r=e.modifiersData.preventOverflow,s=Yt(e,{elementContext:"reference"}),a=Yt(e,{altBoundary:!0}),l=Xt(s,i),c=Xt(a,o,r),u=Qt(l),f=Qt(c);e.modifiersData[n]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:u,hasPopperEscaped:f},e.attributes.popper=Object.assign(Object.assign({},e.attributes.popper),{},{"data-popper-reference-hidden":u,"data-popper-escaped":f})}},Gt={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,n=t.options,i=t.name,o=n.offset,r=void 0===o?[0,0]:o,s=st.reduce((function(t,n){return t[n]=function(t,e,n){var i=ht(t),o=[it,tt].indexOf(i)>=0?-1:1,r="function"==typeof n?n(Object.assign(Object.assign({},e),{},{placement:t})):n,s=r[0],a=r[1];return s=s||0,a=(a||0)*o,[it,nt].indexOf(i)>=0?{x:a,y:s}:{x:s,y:a}}(n,e.rects,r),t}),{}),a=s[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[i]=s}},Zt={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,n=t.name;e.modifiersData[n]=Ft({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},Jt={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,n=t.options,i=t.name,o=n.mainAxis,r=void 0===o||o,s=n.altAxis,a=void 0!==s&&s,l=n.boundary,c=n.rootBoundary,u=n.altBoundary,f=n.padding,d=n.tether,h=void 0===d||d,p=n.tetherOffset,g=void 0===p?0:p,m=Yt(e,{boundary:l,rootBoundary:c,padding:f,altBoundary:u}),v=ht(e.placement),_=zt(e.placement),b=!_,y=Et(v),w="x"===y?"y":"x",E=e.modifiersData.popperOffsets,T=e.rects.reference,k=e.rects.popper,A="function"==typeof g?g(Object.assign(Object.assign({},e.rects),{},{placement:e.placement})):g,L={x:0,y:0};if(E){if(r){var O="y"===y?tt:it,D="y"===y?et:nt,x="y"===y?"height":"width",C=E[y],S=E[y]+m[O],j=E[y]-m[D],N=h?-k[x]/2:0,P="start"===_?T[x]:k[x],I="start"===_?-k[x]:-T[x],M=e.elements.arrow,B=h&&M?pt(M):{width:0,height:0},H=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},R=H[O],W=H[D],K=Tt(0,T[x],B[x]),U=b?T[x]/2-N-K-R-A:P-K-R-A,z=b?-T[x]/2+N+K+W+A:I+K+W+A,F=e.elements.arrow&&wt(e.elements.arrow),Y=F?"y"===y?F.clientTop||0:F.clientLeft||0:0,q=e.modifiersData.offset?e.modifiersData.offset[e.placement][y]:0,V=E[y]+U-q-Y,X=E[y]+z-q,Q=Tt(h?Math.min(S,V):S,C,h?Math.max(j,X):j);E[y]=Q,L[y]=Q-C}if(a){var $="x"===y?tt:it,G="x"===y?et:nt,Z=E[w],J=Tt(Z+m[$],Z,Z-m[G]);E[w]=J,L[w]=J-Z}e.modifiersData[i]=L}},requiresIfExists:["offset"]};function te(t,e,n){void 0===n&&(n=!1);var i,o,r=_t(e),s=Mt(t),a=ft(e),l={scrollLeft:0,scrollTop:0},c={x:0,y:0};return(a||!a&&!n)&&(("body"!==lt(e)||Rt(r))&&(l=(i=e)!==ct(i)&&ft(i)?{scrollLeft:(o=i).scrollLeft,scrollTop:o.scrollTop}:Bt(i)),ft(e)?((c=Mt(e)).x+=e.clientLeft,c.y+=e.clientTop):r&&(c.x=Ht(r))),{x:s.left+l.scrollLeft-c.x,y:s.top+l.scrollTop-c.y,width:s.width,height:s.height}}var ee={placement:"bottom",modifiers:[],strategy:"absolute"};function ne(){for(var t=arguments.length,e=new Array(t),n=0;n0&&r--,"ArrowDown"===t.key&&rdocument.documentElement.clientHeight;e||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");var n=u(this._dialog);B.off(this._element,"transitionend"),B.one(this._element,"transitionend",(function(){t._element.classList.remove("modal-static"),e||(B.one(t._element,"transitionend",(function(){t._element.style.overflowY=""})),h(t._element,n))})),h(this._element,n),this._element.focus()}},r._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;(!this._isBodyOverflowing&&t&&!b||this._isBodyOverflowing&&!t&&b)&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),(this._isBodyOverflowing&&!t&&!b||!this._isBodyOverflowing&&t&&b)&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},r._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},r._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)
',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:[0,0],container:!1,fallbackPlacements:["top","right","bottom","left"],boundary:"clippingParents",customClass:"",sanitize:!0,sanitizeFn:null,allowList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},Ce={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},Se=function(t){function o(e,n){var i;if(void 0===ae)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");return(i=t.call(this,e)||this)._isEnabled=!0,i._timeout=0,i._hoverState="",i._activeTrigger={},i._popper=null,i.config=i._getConfig(n),i.tip=null,i._setListeners(),i}i(o,t);var r=o.prototype;return r.enable=function(){this._isEnabled=!0},r.disable=function(){this._isEnabled=!1},r.toggleEnabled=function(){this._isEnabled=!this._isEnabled},r.toggle=function(t){if(this._isEnabled)if(t){var e=this._initializeOnDelegatedTarget(t);e._activeTrigger.click=!e._activeTrigger.click,e._isWithActiveTrigger()?e._enter(null,e):e._leave(null,e)}else{if(this.getTipElement().classList.contains("show"))return void this._leave(null,this);this._enter(null,this)}},r.dispose=function(){clearTimeout(this._timeout),B.off(this._element,this.constructor.EVENT_KEY),B.off(this._element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this.tip&&this.tip.parentNode&&this.tip.parentNode.removeChild(this.tip),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.config=null,this.tip=null,t.prototype.dispose.call(this)},r.show=function(){var t=this;if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(this.isWithContent()&&this._isEnabled){var e=B.trigger(this._element,this.constructor.Event.SHOW),n=function t(e){if(!document.documentElement.attachShadow)return null;if("function"==typeof e.getRootNode){var n=e.getRootNode();return n instanceof ShadowRoot?n:null}return e instanceof ShadowRoot?e:e.parentNode?t(e.parentNode):null}(this._element),i=null===n?this._element.ownerDocument.documentElement.contains(this._element):n.contains(this._element);if(!e.defaultPrevented&&i){var o=this.getTipElement(),r=s(this.constructor.NAME);o.setAttribute("id",r),this._element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&o.classList.add("fade");var a="function"==typeof this.config.placement?this.config.placement.call(this,o,this._element):this.config.placement,l=this._getAttachment(a);this._addAttachmentClass(l);var c=this._getContainer();E(o,this.constructor.DATA_KEY,this),this._element.ownerDocument.documentElement.contains(this.tip)||c.appendChild(o),B.trigger(this._element,this.constructor.Event.INSERTED),this._popper=se(this._element,o,this._getPopperConfig(l)),o.classList.add("show");var f,d,p="function"==typeof this.config.customClass?this.config.customClass():this.config.customClass;p&&(f=o.classList).add.apply(f,p.split(" ")),"ontouchstart"in document.documentElement&&(d=[]).concat.apply(d,document.body.children).forEach((function(t){B.on(t,"mouseover",(function(){}))}));var g=function(){var e=t._hoverState;t._hoverState=null,B.trigger(t._element,t.constructor.Event.SHOWN),"out"===e&&t._leave(null,t)};if(this.tip.classList.contains("fade")){var m=u(this.tip);B.one(this.tip,"transitionend",g),h(this.tip,m)}else g()}}},r.hide=function(){var t=this;if(this._popper){var e=this.getTipElement(),n=function(){"show"!==t._hoverState&&e.parentNode&&e.parentNode.removeChild(e),t._cleanTipClass(),t._element.removeAttribute("aria-describedby"),B.trigger(t._element,t.constructor.Event.HIDDEN),t._popper&&(t._popper.destroy(),t._popper=null)};if(!B.trigger(this._element,this.constructor.Event.HIDE).defaultPrevented){var i;if(e.classList.remove("show"),"ontouchstart"in document.documentElement&&(i=[]).concat.apply(i,document.body.children).forEach((function(t){return B.off(t,"mouseover",m)})),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,this.tip.classList.contains("fade")){var o=u(e);B.one(e,"transitionend",n),h(e,o)}else n();this._hoverState=""}}},r.update=function(){null!==this._popper&&this._popper.update()},r.isWithContent=function(){return Boolean(this.getTitle())},r.getTipElement=function(){if(this.tip)return this.tip;var t=document.createElement("div");return t.innerHTML=this.config.template,this.tip=t.children[0],this.tip},r.setContent=function(){var t=this.getTipElement();this.setElementContent(Y(".tooltip-inner",t),this.getTitle()),t.classList.remove("fade","show")},r.setElementContent=function(t,e){if(null!==t)return"object"==typeof e&&d(e)?(e.jquery&&(e=e[0]),void(this.config.html?e.parentNode!==t&&(t.innerHTML="",t.appendChild(e)):t.textContent=e.textContent)):void(this.config.html?(this.config.sanitize&&(e=ke(e,this.config.allowList,this.config.sanitizeFn)),t.innerHTML=e):t.textContent=e)},r.getTitle=function(){var t=this._element.getAttribute("data-bs-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this._element):this.config.title),t},r.updateAttachment=function(t){return"right"===t?"end":"left"===t?"start":t},r._initializeOnDelegatedTarget=function(t,e){var n=this.constructor.DATA_KEY;return(e=e||T(t.delegateTarget,n))||(e=new this.constructor(t.delegateTarget,this._getDelegateConfig()),E(t.delegateTarget,n,e)),e},r._getOffset=function(){var t=this,e=this.config.offset;return"string"==typeof e?e.split(",").map((function(t){return Number.parseInt(t,10)})):"function"==typeof e?function(n){return e(n,t._element)}:e},r._getPopperConfig=function(t){var e=this,i={placement:t,modifiers:[{name:"flip",options:{altBoundary:!0,fallbackPlacements:this.config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this.config.boundary}},{name:"arrow",options:{element:"."+this.constructor.NAME+"-arrow"}},{name:"onChange",enabled:!0,phase:"afterWrite",fn:function(t){return e._handlePopperPlacementChange(t)}}],onFirstUpdate:function(t){t.options.placement!==t.placement&&e._handlePopperPlacementChange(t)}};return n({},i,"function"==typeof this.config.popperConfig?this.config.popperConfig(i):this.config.popperConfig)},r._addAttachmentClass=function(t){this.getTipElement().classList.add("bs-tooltip-"+this.updateAttachment(t))},r._getContainer=function(){return!1===this.config.container?document.body:d(this.config.container)?this.config.container:Y(this.config.container)},r._getAttachment=function(t){return De[t.toUpperCase()]},r._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(e){if("click"===e)B.on(t._element,t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==e){var n="hover"===e?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,i="hover"===e?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;B.on(t._element,n,t.config.selector,(function(e){return t._enter(e)})),B.on(t._element,i,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t._element&&t.hide()},B.on(this._element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=n({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},r._fixTitle=function(){var t=this._element.getAttribute("title"),e=typeof this._element.getAttribute("data-bs-original-title");(t||"string"!==e)&&(this._element.setAttribute("data-bs-original-title",t||""),!t||this._element.getAttribute("aria-label")||this._element.textContent||this._element.setAttribute("aria-label",t),this._element.setAttribute("title",""))},r._enter=function(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),e.getTipElement().classList.contains("show")||"show"===e._hoverState?e._hoverState="show":(clearTimeout(e._timeout),e._hoverState="show",e.config.delay&&e.config.delay.show?e._timeout=setTimeout((function(){"show"===e._hoverState&&e.show()}),e.config.delay.show):e.show())},r._leave=function(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState="out",e.config.delay&&e.config.delay.hide?e._timeout=setTimeout((function(){"out"===e._hoverState&&e.hide()}),e.config.delay.hide):e.hide())},r._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},r._getConfig=function(t){var e=z.getDataAttributes(this._element);return Object.keys(e).forEach((function(t){Le.has(t)&&delete e[t]})),t&&"object"==typeof t.container&&t.container.jquery&&(t.container=t.container[0]),"number"==typeof(t=n({},this.constructor.Default,e,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),p("tooltip",t,this.constructor.DefaultType),t.sanitize&&(t.template=ke(t.template,t.allowList,t.sanitizeFn)),t},r._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},r._cleanTipClass=function(){var t=this.getTipElement(),e=t.getAttribute("class").match(Ae);null!==e&&e.length>0&&e.map((function(t){return t.trim()})).forEach((function(e){return t.classList.remove(e)}))},r._handlePopperPlacementChange=function(t){var e=t.state;e&&(this.tip=e.elements.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(e.placement)))},o.jQueryInterface=function(t){return this.each((function(){var e=T(this,"bs.tooltip"),n="object"==typeof t&&t;if((e||!/dispose|hide/.test(t))&&(e||(e=new o(this,n)),"string"==typeof t)){if(void 0===e[t])throw new TypeError('No method named "'+t+'"');e[t]()}}))},e(o,null,[{key:"Default",get:function(){return xe}},{key:"NAME",get:function(){return"tooltip"}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return Ce}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return Oe}}]),o}(H);y("tooltip",Se);var je=new RegExp("(^|\\s)bs-popover\\S+","g"),Ne=n({},Se.Default,{placement:"right",offset:[0,8],trigger:"click",content:"",template:''}),Pe=n({},Se.DefaultType,{content:"(string|element|function)"}),Ie={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},Me=function(t){function n(){return t.apply(this,arguments)||this}i(n,t);var o=n.prototype;return o.isWithContent=function(){return this.getTitle()||this._getContent()},o.setContent=function(){var t=this.getTipElement();this.setElementContent(Y(".popover-header",t),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this._element)),this.setElementContent(Y(".popover-body",t),e),t.classList.remove("fade","show")},o._addAttachmentClass=function(t){this.getTipElement().classList.add("bs-popover-"+this.updateAttachment(t))},o._getContent=function(){return this._element.getAttribute("data-bs-content")||this.config.content},o._cleanTipClass=function(){var t=this.getTipElement(),e=t.getAttribute("class").match(je);null!==e&&e.length>0&&e.map((function(t){return t.trim()})).forEach((function(e){return t.classList.remove(e)}))},n.jQueryInterface=function(t){return this.each((function(){var e=T(this,"bs.popover"),i="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new n(this,i),E(this,"bs.popover",e)),"string"==typeof t)){if(void 0===e[t])throw new TypeError('No method named "'+t+'"');e[t]()}}))},e(n,null,[{key:"Default",get:function(){return Ne}},{key:"NAME",get:function(){return"popover"}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return Ie}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return Pe}}]),n}(Se);y("popover",Me);var Be={offset:10,method:"auto",target:""},He={offset:"number",method:"string",target:"(string|element)"},Re=function(t){function o(e,n){var i;return(i=t.call(this,e)||this)._scrollElement="BODY"===e.tagName?window:e,i._config=i._getConfig(n),i._selector=i._config.target+" .nav-link, "+i._config.target+" .list-group-item, "+i._config.target+" .dropdown-item",i._offsets=[],i._targets=[],i._activeTarget=null,i._scrollHeight=0,B.on(i._scrollElement,"scroll.bs.scrollspy",(function(){return i._process()})),i.refresh(),i._process(),i}i(o,t);var r=o.prototype;return r.refresh=function(){var t=this,e=this._scrollElement===this._scrollElement.window?"offset":"position",n="auto"===this._config.method?e:this._config.method,i="position"===n?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),F(this._selector).map((function(t){var e=l(t),o=e?Y(e):null;if(o){var r=o.getBoundingClientRect();if(r.width||r.height)return[z[n](o).top+i,e]}return null})).filter((function(t){return t})).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},r.dispose=function(){t.prototype.dispose.call(this),B.off(this._scrollElement,".bs.scrollspy"),this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},r._getConfig=function(t){if("string"!=typeof(t=n({},Be,"object"==typeof t&&t?t:{})).target&&d(t.target)){var e=t.target.id;e||(e=s("scrollspy"),t.target.id=e),t.target="#"+e}return p("scrollspy",t,He),t},r._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},r._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},r._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},r._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;)this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&(void 0===this._offsets[o+1]||t li > .active":".active";e=(e=F(o,i))[e.length-1]}var r=e?B.trigger(e,"hide.bs.tab",{relatedTarget:this._element}):null;if(!(B.trigger(this._element,"show.bs.tab",{relatedTarget:e}).defaultPrevented||null!==r&&r.defaultPrevented)){this._activate(this._element,i);var s=function(){B.trigger(e,"hidden.bs.tab",{relatedTarget:t._element}),B.trigger(t._element,"shown.bs.tab",{relatedTarget:e})};n?this._activate(n,n.parentNode,s):s()}}},o._activate=function(t,e,n){var i=this,o=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?q(e,".active"):F(":scope > li > .active",e))[0],r=n&&o&&o.classList.contains("fade"),s=function(){return i._transitionComplete(t,o,n)};if(o&&r){var a=u(o);o.classList.remove("show"),B.one(o,"transitionend",s),h(o,a)}else s()},o._transitionComplete=function(t,e,n){if(e){e.classList.remove("active");var i=Y(":scope > .dropdown-menu .active",e.parentNode);i&&i.classList.remove("active"),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}t.classList.add("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),v(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&t.parentNode.classList.contains("dropdown-menu")&&(t.closest(".dropdown")&&F(".dropdown-toggle").forEach((function(t){return t.classList.add("active")})),t.setAttribute("aria-expanded",!0)),n&&n()},n.jQueryInterface=function(t){return this.each((function(){var e=T(this,"bs.tab")||new n(this);if("string"==typeof t){if(void 0===e[t])throw new TypeError('No method named "'+t+'"');e[t]()}}))},e(n,null,[{key:"DATA_KEY",get:function(){return"bs.tab"}}]),n}(H);B.on(document,"click.bs.tab.data-api",'[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',(function(t){t.preventDefault(),(T(this,"bs.tab")||new We(this)).show()})),y("tab",We);var Ke={animation:"boolean",autohide:"boolean",delay:"number"},Ue={animation:!0,autohide:!0,delay:5e3},ze=function(t){function o(e,n){var i;return(i=t.call(this,e)||this)._config=i._getConfig(n),i._timeout=null,i._setListeners(),i}i(o,t);var r=o.prototype;return r.show=function(){var t=this;if(!B.trigger(this._element,"show.bs.toast").defaultPrevented){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var e=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),B.trigger(t._element,"shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove("hide"),v(this._element),this._element.classList.add("showing"),this._config.animation){var n=u(this._element);B.one(this._element,"transitionend",e),h(this._element,n)}else e()}},r.hide=function(){var t=this;if(this._element.classList.contains("show")&&!B.trigger(this._element,"hide.bs.toast").defaultPrevented){var e=function(){t._element.classList.add("hide"),B.trigger(t._element,"hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var n=u(this._element);B.one(this._element,"transitionend",e),h(this._element,n)}else e()}},r.dispose=function(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),B.off(this._element,"click.dismiss.bs.toast"),t.prototype.dispose.call(this),this._config=null},r._getConfig=function(t){return t=n({},Ue,z.getDataAttributes(this._element),"object"==typeof t&&t?t:{}),p("toast",t,this.constructor.DefaultType),t},r._setListeners=function(){var t=this;B.on(this._element,"click.dismiss.bs.toast",'[data-bs-dismiss="toast"]',(function(){return t.hide()}))},r._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null},o.jQueryInterface=function(t){return this.each((function(){var e=T(this,"bs.toast");if(e||(e=new o(this,"object"==typeof t&&t)),"string"==typeof t){if(void 0===e[t])throw new TypeError('No method named "'+t+'"');e[t](this)}}))},e(o,null,[{key:"DefaultType",get:function(){return Ke}},{key:"Default",get:function(){return Ue}},{key:"DATA_KEY",get:function(){return"bs.toast"}}]),o}(H);return y("toast",ze),{Alert:R,Button:W,Carousel:$,Collapse:J,Dropdown:ve,Modal:ye,Popover:Me,ScrollSpy:Re,Tab:We,Toast:ze,Tooltip:Se}})); //# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/admin/js/ssbhesabix-admin.js b/admin/js/ssbhesabix-admin.js index 15109a0..fb3df6d 100644 --- a/admin/js/ssbhesabix-admin.js +++ b/admin/js/ssbhesabix-admin.js @@ -1,863 +1,867 @@ -jQuery(function ($) { - $('.progress').hide(); - 'use strict'; -//===================================================================================================================== - $(function () { - // AJAX - Export Products - $('#ssbhesabix_export_products').submit(function () { - // show processing status - $('#ssbhesabix-export-product-submit').attr('disabled', 'disabled'); - $('#ssbhesabix-export-product-submit').removeClass('button-primary'); - $('#ssbhesabix-export-product-submit').html(' خروج محصولات...'); - $('#ssbhesabix-export-product-submit i.spinner').show(); - - $('#exportProductsProgress').show(); - $('#exp ortProductsProgressBar').css('width', 0 + '%').attr('aria-valuenow', 0); - - exportProducts(1, 1, 1, 0); - - return false; - }); - }); -//===================================================================================================================== - function exportProducts(batch, totalBatch, total, updateCount) { - const data = { - 'action': 'adminExportProducts', - 'batch': batch, - 'totalBatch': totalBatch, - 'total': total, - 'updateCount': updateCount - }; - $.post(ajaxurl, data, function (response) { - if (response !== 'failed') { - const res = JSON.parse(response); - res.batch = parseInt(res.batch); - if (res.batch < res.totalBatch) { - let progress = (res.batch * 100) / res.totalBatch; - progress = Math.round(progress); - $('#exportProductsProgressBar').css('width', progress + '%').attr('aria-valuenow', progress); - exportProducts(res.batch + 1, res.totalBatch, res.total, res.updateCount); - return false; - } else { - $('#exportProductsProgressBar').css('width', 100 + '%').attr('aria-valuenow', 100); - setTimeout(() => { - top.location.replace(res.redirectUrl); - }, 1000); - return false; - } - } else { - alert('خطا در استخراج محصولات'); - return false; - } - }); - } -//===================================================================================================================== - $(function () { - // AJAX - Import Products - $('#ssbhesabix_import_products').submit(function () { - // show processing status - $('#ssbhesabix-import-product-submit').attr('disabled', 'disabled'); - $('#ssbhesabix-import-product-submit').removeClass('button-primary'); - $('#ssbhesabix-import-product-submit').html(' در حال ورود کالاها از حسابیکس, لطفاً صبر کنید...'); - $('#ssbhesabix-import-product-submit i.spinner').show(); - - $('#importProductsProgress').show(); - $('#importProductsProgressBar').css('width', 0 + '%').attr('aria-valuenow', 0); - - importProducts(1, 1, 1, 0); - - return false; - }); - }); -//===================================================================================================================== - function importProducts(batch, totalBatch, total, updateCount) { - var data = { - 'action': 'adminImportProducts', - 'batch': batch, - 'totalBatch': totalBatch, - 'total': total, - 'updateCount': updateCount - }; - $.post(ajaxurl, data, function (response) { - if ('failed' !== response) { - const res = JSON.parse(response); - res.batch = parseInt(res.batch); - if (res.batch < res.totalBatch) { - let progress = (res.batch * 100) / res.totalBatch; - progress = Math.round(progress); - $('#importProductsProgressBar').css('width', progress + '%').attr('aria-valuenow', progress); - //alert('batch: ' + res.batch + ', totalBatch: ' + res.totalBatch + ', total: ' + res.total); - importProducts(res.batch + 1, res.totalBatch, res.total, res.updateCount); - return false; - } else { - $('#importProductsProgressBar').css('width', 100 + '%').attr('aria-valuenow', 100); - setTimeout(() => { - top.location.replace(res.redirectUrl); - }, 1000); - return false; - } - } else { - alert('خطا در وارد کردن محصولات'); - return false; - } - }); - } -//===================================================================================================================== - $(function () { - // AJAX - Export Products opening quantity - $('#ssbhesabix_export_products_opening_quantity').submit(function () { - // show processing status - $('#ssbhesabix-export-product-opening-quantity-submit').attr('disabled', 'disabled'); - $('#ssbhesabix-export-product-opening-quantity-submit').removeClass('button-primary'); - $('#ssbhesabix-export-product-opening-quantity-submit').html(' استخراج موجودی اول دوره...'); - $('#ssbhesabix-export-product-opening-quantity-submit i.spinner').show(); - - $('#exportProductsOpeningQuantityProgress').show(); - $('#exportProductsOpeningQuantityProgressBar').css('width', 0 + '%').attr('aria-valuenow', 0); - - exportProductsOpeningQuantity(1, 1, 1); - - return false; - }); - }); - - function exportProductsOpeningQuantity(batch, totalBatch, total) { - var data = { - 'action': 'adminExportProductsOpeningQuantity', - 'batch': batch, - 'totalBatch': totalBatch, - 'total': total - }; - $.post(ajaxurl, data, function (response) { - if ('failed' !== response) { - const res = JSON.parse(response); - res.batch = parseInt(res.batch); - if (res.batch < res.totalBatch) { - let progress = (res.batch * 100) / res.totalBatch; - progress = Math.round(progress); - $('#exportProductsOpeningQuantityProgressBar').css('width', progress + '%').attr('aria-valuenow', progress); - exportProductsOpeningQuantity(res.batch + 1, res.totalBatch, res.total); - return false; - } else { - $('#exportProductsOpeningQuantityProgressBar').css('width', 100 + '%').attr('aria-valuenow', 100); - setTimeout(() => { - top.location.replace(res.redirectUrl); - }, 1000); - return false; - } - } else { - alert('خطا در استخراج موجودی اول دوره'); - return false; - } - }); - } -//===================================================================================================================== - $(function () { - // AJAX - Export Customers - $('#ssbhesabix_export_customers').submit(function () { - // show processing status - $('#ssbhesabix-export-customer-submit').attr('disabled', 'disabled'); - $('#ssbhesabix-export-customer-submit').removeClass('button-primary'); - $('#ssbhesabix-export-customer-submit').html(' خروجی مشتریان، لطفاً صبر کنید...'); - $('#ssbhesabix-export-customer-submit i.spinner').show(); - - $('#exportCustomersProgress').show(); - $('#exportCustomersProgressBar').css('width', 0 + '%').attr('aria-valuenow', 0); - - exportCustomers(1, 1, 1, 0); - - return false; - }); - }); - - function exportCustomers(batch, totalBatch, total, updateCount) { - const data = { - 'action': 'adminExportCustomers', - 'batch': batch, - 'totalBatch': totalBatch, - 'total': total, - 'updateCount': updateCount - }; - $.post(ajaxurl, data, function (response) { - if (response !== 'failed') { - const res = JSON.parse(response); - res.batch = parseInt(res.batch); - if (res.batch < res.totalBatch) { - let progress = (res.batch * 100) / res.totalBatch; - progress = Math.round(progress); - $('#exportCustomersProgressBar').css('width', progress + '%').attr('aria-valuenow', progress); - exportCustomers(res.batch + 1, res.totalBatch, res.total, res.updateCount); - return false; - } else { - $('#exportCustomersProgressBar').css('width', 100 + '%').attr('aria-valuenow', 100); - setTimeout(() => { - top.location.replace(res.redirectUrl); - }, 1000); - return false; - } - } else { - alert('خطا در استخراج مشتریان'); - return false; - } - }); - } -//===================================================================================================================== - $(function () { - // AJAX - Sync Changes - $('#ssbhesabix_sync_changes').submit(function () { - // show processing status - $('#ssbhesabix-sync-changes-submit').attr('disabled', 'disabled'); - $('#ssbhesabix-sync-changes-submit').removeClass('button-primary'); - $('#ssbhesabix-sync-changes-submit').html(' همسان سازی تغییرات...'); - $('#ssbhesabix-sync-changes-submit i.spinner').show(); - - var data = { - 'action': 'adminSyncChanges' - }; - - // post it - $.post(ajaxurl, data, function (response) { - if ('failed' !== response) { - var redirectUrl = response; - - /** Debug **/ - // console.log(redirectUrl); - // return false; - - top.location.replace(redirectUrl); - return false; - } else { - alert('خطا در همگام سازی تغییرات'); - return false; - } - }); - /*End Post*/ - return false; - }); - }); -//===================================================================================================================== - $(function () { - // AJAX - Sync Products - $('#ssbhesabix_sync_products').submit(function () { - - // show processing status - $('#ssbhesabix-sync-products-submit').attr('disabled', 'disabled'); - $('#ssbhesabix-sync-products-submit').removeClass('button-primary'); - $('#ssbhesabix-sync-products-submit').html(' همسان سازی محصولات...'); - $('#ssbhesabix-sync-products-submit i.spinner').show(); - - $('#syncProductsProgress').show(); - $('#syncProductsProgressBar').css('width', 0 + '%').attr('aria-valuenow', 0); - - syncProducts(1, 1, 1); - - return false; - }); - }); -//===================================================================================================================== - function syncProducts(batch, totalBatch, total) { - const data = { - 'action': 'adminSyncProducts', - 'batch': batch, - 'totalBatch': totalBatch, - 'total': total - }; - //$.post(URL, DATA, CALLBACK) - $.post(ajaxurl, data, function (response) { - if (response !== 'failed') { - const res = JSON.parse(response); - res.batch = parseInt(res.batch); - if (res.batch < res.totalBatch) { - let progress = (res.batch * 100) / res.totalBatch; - progress = Math.round(progress); - $('#syncProductsProgressBar').css('width', progress + '%').attr('aria-valuenow', progress); - //alert('batch: ' + res.batch + ', totalBatch: ' + res.totalBatch + ', total: ' + res.total); - syncProducts(res.batch + 1, res.totalBatch, res.total); - return false; - } else { - $('#syncProductsProgressBar').css('width', 100 + '%').attr('aria-valuenow', 100); - setTimeout(() => { - top.location.replace(res.redirectUrl); - }, 1000); - return false; - } - } else { - alert('خطا در همگام سازی محصولات'); - return false; - } - }); - } -//===================================================================================================================== - $(function () { - // AJAX - Sync Orders - $('#ssbhesabix_sync_orders').submit(function () { - // show processing status - $('#ssbhesabix-sync-orders-submit').attr('disabled', 'disabled'); - $('#ssbhesabix-sync-orders-submit').removeClass('button-primary'); - $('#ssbhesabix-sync-orders-submit').html(' همسان سازی سفارشات...'); - $('#ssbhesabix-sync-orders-submit i.spinner').show(); - - $('#syncOrdersProgress').show(); - $('#syncOrdersProgressBar').css('width', 0 + '%').attr('aria-valuenow', 0); - - syncOrders(1, 1, 1, 0); - - return false; - }); - }); - - function syncOrders(batch, totalBatch, total, updateCount) { - var date = $('#ssbhesabix_sync_order_date').val(); - - const data = { - 'action': 'adminSyncOrders', - 'date': date, - 'batch': batch, - 'totalBatch': totalBatch, - 'total': total, - 'updateCount': updateCount - }; - $.post(ajaxurl, data, function (response) { - if (response !== 'failed') { - const res = JSON.parse(response); - res.batch = parseInt(res.batch); - if (res.batch < res.totalBatch) { - let progress = (res.batch * 100) / res.totalBatch; - progress = Math.round(progress); - $('#syncOrdersProgressBar').css('width', progress + '%').attr('aria-valuenow', progress); - syncOrders(res.batch + 1, res.totalBatch, res.total, res.updateCount); - return false; - } else { - $('#syncOrdersProgressBar').css('width', 100 + '%').attr('aria-valuenow', 100); - setTimeout(() => { - top.location.replace(res.redirectUrl); - }, 1000); - return false; - } - } else { - alert('خطا در همگام سازی سفارشات'); - return false; - } - }); - } -//===================================================================================================================== - $(function () { - // AJAX - Sync Products - $('#ssbhesabix_update_products').submit(function () { - // show processing status - $('#ssbhesabix-update-products-submit').attr('disabled', 'disabled'); - $('#ssbhesabix-update-products-submit').removeClass('button-primary'); - $('#ssbhesabix-update-products-submit').html(' بروزرسانی محصولات...'); - $('#ssbhesabix-update-products-submit i.spinner').show(); - - $('#updateProductsProgress').show(); - $('#updateProductsProgressBar').css('width', 0 + '%').attr('aria-valuenow', 0); - - updateProducts(1, 1, 1); - - return false; - }); - }); -//===================================================================================================================== - function updateProducts(batch, totalBatch, total) { - var data = { - 'action': 'adminUpdateProducts', - 'batch': batch, - 'totalBatch': totalBatch, - 'total': total - }; - $.post(ajaxurl, data, function (response) { - if ('failed' !== response) { - const res = JSON.parse(response); - res.batch = parseInt(res.batch); - if (res.batch < res.totalBatch) { - let progress = (res.batch * 100) / res.totalBatch; - progress = Math.round(progress); - $('#updateProductsProgressBar').css('width', progress + '%').attr('aria-valuenow', progress); - updateProducts(res.batch + 1, res.totalBatch, res.total); - return false; - } else { - $('#updateProductsProgressBar').css('width', 100 + '%').attr('aria-valuenow', 100); - setTimeout(() => { - top.location.replace(res.redirectUrl); - }, 1000); - return false; - } - } else { - alert('خطا در بروزرسانی محصولات'); - return false; - } - }); - } - -//===================================================================================================================== - - // $(function () { - // // AJAX - Sync Products with ID filter - // $('#ssbhesabix_update_products_with_filter').submit(function (e) { - // - // // Show processing status - // var submitButton = $('#ssbhesabix-update-products-with-filter-submit'); - // submitButton.removeClass('button-primary'); - // submitButton.html(' بروزرسانی محصولات...'); - // }); - // }); - - - - $(function () { - // AJAX - Sync Products - $('#ssbhesabix_update_products_with_filter').submit(function () { - let submitButton = $('#ssbhesabix-update-products-with-filter-submit'); - let offset = document.getElementById("ssbhesabix-update-products-offset").value; - let rpp = document.getElementById("ssbhesabix-update-products-rpp").value; - submitButton.removeClass('button-primary'); - submitButton.html(' بروزرسانی محصولات لطفا صبر کنید...'); - $('#ssbhesabix-update-products-with-filter-submit').attr('disabled', 'disabled'); - - updateProductsWithFilter(offset, rpp); - - return false; - }); - }); -//===================================================================================================================== - function updateProductsWithFilter(offset, rpp) { - var data = { - 'action': 'adminUpdateProductsWithFilter', - 'offset': offset, - 'rpp': rpp, - }; - if(offset && rpp) { - $.post(ajaxurl, data, function (response) { - if ('failed' !== response) { - const res = JSON.parse(response); - if(!res.error) { - top.location.replace(res.redirectUrl); - } - } else { - alert('خطا در بروزرسانی محصولات'); - return false; - } - }); - } else { - alert('فیلد ها را به درستی وارد نمایید'); - submitButton.addClass('button-primary'); - submitButton.html('بروزرسانی محصولات در حسابیکس بر اساس فروشگاه در بازه ID مشخص شده'); - $('#ssbhesabix-update-products-with-filter-submit').removeAttr('disabled'); - return false; - } - } - -//===================================================================================================================== - $(function () { - // AJAX - Clean log - $('#ssbhesabix_clean_log').submit(function (e) { - // show processing status - $('#ssbhesabix-log-clean-submit').attr('disabled', 'disabled'); - $('#ssbhesabix-log-clean-submit').removeClass('button-primary'); - $('#ssbhesabix-log-clean-submit').html(' پاک کردن فایل لاگ، لطفاً صبر کنید...'); - $('#ssbhesabix-log-clean-submit i.spinner').show(); - - var data = { - 'action': 'adminCleanLogFile' - }; - - // post it - $.post(ajaxurl, data, function (response) { - if ('failed' !== response) { - var redirectUrl = response; - - /** Debug **/ - // console.log(redirectUrl); - // return false; - - top.location.replace(redirectUrl); - return false; - } else { - alert('خطا در پاکسازی فایل لاگ'); - return false; - } - }); - /*End Post*/ - return false; - }); - }); -//===================================================================================================================== - $(function () { - // AJAX - Sync Products Manually - $('#ssbhesabix_sync_products_manually').submit(function () { - // show processing status - $('#ssbhesabix_sync_products_manually-submit').attr('disabled', 'disabled'); - $('#ssbhesabix_sync_products_manually-submit').removeClass('button-primary'); - $('#ssbhesabix_sync_products_manually-submit').html(' ذخیره کردن اطلاعات...'); - $('#ssbhesabix_sync_products_manually i.spinner').show(); - - const inputArray = []; - const inputs = $('.code-input'); - console.log(inputs); - for (var n = 0; n < inputs.length; n++) { - var i = inputs[n]; - console.log(i); - const obj = { - id: $(i).attr('id'), - hesabix_id: $(i).val(), - parent_id: $(i).attr('data-parent-id') - } - inputArray.push(obj); - } - - const page = $('#pageNumber').val(); - const rpp = $('#goToPage').attr('data-rpp'); - - var data = { - 'action': 'adminSyncProductsManually', - 'data': JSON.stringify(inputArray), - 'page': page, - 'rpp': rpp - }; - - // post it - $.post(ajaxurl, data, function (response) { - if ('failed' !== response) { - var redirectUrl = response; - - /** Debug **/ - // console.log(redirectUrl); - // return false; - - top.location.replace(redirectUrl); - return false; - } else { - alert('خطا در ذخیره اطلاعات'); - return false; - } - }); - /*End Post*/ - return false; - }); - - $("#goToPage").click(function () { - const page = $('#pageNumber').val(); - const rpp = $('#goToPage').attr('data-rpp'); - window.location.href = "?page=hesabix-sync-products-manually&p=" + page + "&rpp=" + rpp; - }); - - $("#show-tips-btn").click(function () { - $('#tips-alert').removeClass('d-none'); - $('#tips-alert').addClass('d-block'); - }); - - $("#hide-tips-btn").click(function () { - $('#tips-alert').removeClass('d-block'); - $('#tips-alert').addClass('d-none'); - }); - }); - - $(".btn-submit-invoice").on( "click", function() { - var orderId = $(this).attr("data-order-id"); - - var btnEl = $('.btn-submit-invoice[data-order-id=' + orderId + ']'); - - btnEl.attr('aria-disabled', true); - btnEl.addClass('disabled'); - btnEl.html('ثبت فاکتور...'); - //btnEl.show(); - - submitInvoice(orderId); - }); -//===================================================================================================================== - function submitInvoice(orderId) { - var data = { - 'action': 'adminSubmitInvoice', - 'orderId': orderId - }; - $.post(ajaxurl, data, function (response) { - if ('failed' !== response) { - const res = JSON.parse(response); - // refresh page - location.reload(); - } else { - alert('خطا در ثبت فاکتور'); - return false; - } - }); - } - - // change business warning - var oldApiKey = ''; - $("#changeBusinessWarning").hide(); - - $("#ssbhesabix_account_api").focusin( function () { - oldApiKey = $("#ssbhesabix_account_api" ).val(); - }); - $("#ssbhesabix_account_api").focusout( function () { - var newApiKey = $("#ssbhesabix_account_api" ).val(); - if(oldApiKey != '' && oldApiKey != newApiKey) { - $("#changeBusinessWarning").show(); - } - }); -//===================================================================================================================== - $(function () { - // AJAX - clear all plugin data - $('#hesabix-clear-plugin-data').click(function () { - if (confirm('هشدار: با انجام این عملیات کلیه اطلاعات افزونه شامل روابط بین کالاها، مشتریان و فاکتور ها و همینطور تنظیمات افزونه حذف می گردد.' + - 'آیا از انجام این عملیات مطمئن هستید؟')) { - $('#hesabix-clear-plugin-data').addClass('disabled'); - $('#hesabix-clear-plugin-data').html('حذف دیتای افزونه...'); - var data = { - 'action': 'adminClearPluginData' - }; - $.post(ajaxurl, data, function (response) { - $('#hesabix-clear-plugin-data').removeClass('disabled'); - $('#hesabix-clear-plugin-data').html('حذف دیتای افزونه'); - if ('failed' !== response) { - alert('دیتای افزونه با موفقیت حذف شد.'); - return false; - } else { - alert('خطا در هنگام حذف دیتای افزونه.'); - return false; - } - }); - } else { - // Do nothing! - } - return false; - }); - - $('#hesabix-install-plugin-data').click(function () { - if (confirm('با انجام این عملیات جدول افزونه در دیتابیس وردپرس ایجاد' + - ' و تنظیمات پیش فرض افزونه تنظیم می گردد.' + - ' آیا از انجام این عملیات مطمئن هستید؟')) { - $('#hesabix-install-plugin-data').addClass('disabled'); - $('#hesabix-install-plugin-data').html('نصب دیتای افزونه...'); - var data = { - 'action': 'adminInstallPluginData' - }; - $.post(ajaxurl, data, function (response) { - $('#hesabix-install-plugin-data').removeClass('disabled'); - $('#hesabix-install-plugin-data').html('نصب دیتای افزونه'); - if ('failed' !== response) { - alert('دیتای افزونه با موفقیت نصب شد.'); - return false; - } else { - alert('خطا در هنگام نصب دیتای افزونه.'); - return false; - } - }); - } else { - // Do nothing! - } - return false; - }); - }); -//===================================================================================================================== - $(function () { - //SAVE - $(".hesabix-item-save").on('click', function (){ - const productId = $("#panel_product_data_hesabix").data('product-id'); - const attributeId = $(this).data('id'); - const code = $("#hesabix-item-" + attributeId).val(); - var data = { - 'action': 'adminChangeProductCode', - 'productId': productId, - 'attributeId': attributeId, - 'code': code, - }; - $(this).prop('disabled', true); - const _this = this; - $.post(ajaxurl, data, function (response) { - $(_this).prop('disabled', false); - if ('failed' !== response) { - const res = JSON.parse(response); - alert(res.error ? res.message : 'کد کالای متصل با موفقیت تغییر کرد.'); - if(productId === attributeId) - $("#ssbhesabix_hesabix_item_code_0").val(code); - else - $("#ssbhesabix_hesabix_item_code_" + attributeId).val(code); - return false; - } else { - alert('خطا در هنگام تغییر کد کالای متصل.'); - return false; - } - }); - }); - //DELETE LINK - $(".hesabix-item-delete-link").on('click', function (){ - const productId = $("#panel_product_data_hesabix").data('product-id'); - const attributeId = $(this).data('id'); - var data = { - 'action': 'adminDeleteProductLink', - 'productId': productId, - 'attributeId': attributeId - }; - $(this).prop('disabled', true); - const _this = this; - $.post(ajaxurl, data, function (response) { - $(_this).prop('disabled', false); - if ('failed' !== response) { - const res = JSON.parse(response); - $("#hesabix-item-" + attributeId).val(''); - if(productId === attributeId) - $("#ssbhesabix_hesabix_item_code_0").val(''); - else - $("#ssbhesabix_hesabix_item_code_" + attributeId).val(''); - setTimeout(function (){ - alert(res.error ? res.message : 'ارتباط محصول با موفقیت حذف شد'); - }, 100); - return false; - } else { - alert('خطا در هنگام حذف ارتباط'); - return false; - } - }); - }); - //UPDATE - $(".hesabix-item-update").on('click', function (){ - const productId = $("#panel_product_data_hesabix").data('product-id'); - const attributeId = $(this).data('id'); - var data = { - 'action': 'adminUpdateProduct', - 'productId': productId, - 'attributeId': attributeId - }; - $(this).prop('disabled', true); - const _this = this; - $.post(ajaxurl, data, function (response) { - $(_this).prop('disabled', false); - if ('failed' !== response) { - const res = JSON.parse(response); - if(res.newPrice != null) - $("#hesabix-item-price-" + attributeId).text(res.newPrice); - if(res.newQuantity != null) - $("#hesabix-item-quantity-" + attributeId).text(res.newQuantity); - if(res.error) - alert(res.message); - return false; - } else { - alert('خطا در هنگام بروزرسانی محصول'); - return false; - } - }); - }); - //SAVE ALL - $("#hesabix-item-save-all").on('click', function (){ - const productId = $("#panel_product_data_hesabix").data('product-id'); - const itemsCode = $(".hesabix-item-code"); - const itemsData = []; - for (let i = 0; i < itemsCode.length; i++) { - const item = itemsCode[i]; - const attributeId = $(item).data('id'); - const code = $(item).val(); - itemsData.push({attributeId: attributeId, code: code}); - } - - var data = { - 'action': 'adminChangeProductsCode', - 'productId': productId, - 'itemsData': itemsData - }; - $(this).prop('disabled', true); - const _this = this; - $.post(ajaxurl, data, function (response) { - $(_this).prop('disabled', false); - if ('failed' !== response) { - const res = JSON.parse(response); - alert(res.error ? res.message : 'کد کالاهای متصل با موفقیت تغییر کرد.'); - location.reload(); - return false; - } else { - alert('خطا در هنگام تغییر کد کالاهای متصل'); - return false; - } - }); - }); - //DELETE - $("#hesabix-item-delete-link-all").on('click', function (){ - const productId = $("#panel_product_data_hesabix").data('product-id'); - var data = { - 'action': 'adminDeleteProductsLink', - 'productId': productId - }; - $(this).prop('disabled', true); - const _this = this; - $.post(ajaxurl, data, function (response) { - $(_this).prop('disabled', false); - if ('failed' !== response) { - const res = JSON.parse(response); - const itemsCode = $(".hesabix-item-code"); - for (let i = 0; i < itemsCode.length; i++) { - const item = itemsCode[i]; - $(item).val(''); - } - $('[id^="ssbhesabix_hesabix_item_code_"]').val(''); - setTimeout(function (){ - alert(res.error ? res.message : 'ارتباط محصولات با موفقیت حذف شد.'); - }, 100); - return false; - } else { - alert('خطا در هنگام حذف ارتباط'); - return false; - } - }); - }); - //UPDATE ALL - $("#hesabix-item-update-all").on('click', function (){ - const productId = $("#panel_product_data_hesabix").data('product-id'); - var data = { - 'action': 'adminUpdateProductAndVariations', - 'productId': productId - }; - $(this).prop('disabled', true); - const _this = this; - $.post(ajaxurl, data, function (response) { - $(_this).prop('disabled', false); - if ('failed' !== response) { - const res = JSON.parse(response); - if(res.error) - { - alert(res.message); - return false; - } - for (let i = 0; i < res.newData.length; i++) { - if(res.newData[i].newPrice != null) - $("#hesabix-item-price-" + res.newData[i].attributeId).text(res.newData[i].newPrice); - if(res.newData[i].newQuantity != null) - $("#hesabix-item-quantity-" + res.newData[i].attributeId).text(res.newData[i].newQuantity); - } - return false; - } else { - alert('خطا در هنگام بروزرسانی محصول'); - return false; - } - }); - }); - }); -//===================================================================================================================== - $(function (){ - let radio = $('input:radio[name="addFieldsRadio"]'); - let radioChecked = $('input:radio[name="addFieldsRadio"]:checked'); - let textInput = $('.contact_text_input'); - - if(radioChecked.val() === '2'){ - textInput.prop( "disabled", false ); - }else { - textInput.prop( "disabled", true ); - } - $(radio).on('click',function (){ - if($(this).val() === '2'){ - textInput.prop( "disabled", false ); - }else { - textInput.prop( "disabled", true ); - } - }); - - }); -}); -//===================================================================================================================== -function hesabixTutorialJumpTo(time) { - let vidEl = document.getElementById('hesabix-tutorial-video'); - vidEl.play(); - vidEl.pause(); - vidEl.currentTime = time; - vidEl.play(); -} +jQuery(function ($) { + $('.progress').hide(); + 'use strict'; +//===================================================================================================================== + $(function () { + // AJAX - Export Products + $('#ssbhesabix_export_products').submit(function () { + // show processing status + $('#ssbhesabix-export-product-submit').attr('disabled', 'disabled'); + $('#ssbhesabix-export-product-submit').removeClass('button-primary'); + $('#ssbhesabix-export-product-submit').html(' خروج محصولات...'); + $('#ssbhesabix-export-product-submit i.spinner').show(); + + $('#exportProductsProgress').show(); + $('#exp ortProductsProgressBar').css('width', 0 + '%').attr('aria-valuenow', 0); + + exportProducts(1, 1, 1, 0); + + return false; + }); + }); +//===================================================================================================================== + function exportProducts(batch, totalBatch, total, updateCount) { + const data = { + 'action': 'adminExportProducts', + 'batch': batch, + 'totalBatch': totalBatch, + 'total': total, + 'updateCount': updateCount + }; + $.post(ajaxurl, data, function (response) { + if (response !== 'failed') { + const res = JSON.parse(response); + res.batch = parseInt(res.batch); + if (res.batch < res.totalBatch) { + let progress = (res.batch * 100) / res.totalBatch; + progress = Math.round(progress); + $('#exportProductsProgressBar').css('width', progress + '%').attr('aria-valuenow', progress); + exportProducts(res.batch + 1, res.totalBatch, res.total, res.updateCount); + return false; + } else { + $('#exportProductsProgressBar').css('width', 100 + '%').attr('aria-valuenow', 100); + setTimeout(() => { + top.location.replace(res.redirectUrl); + }, 1000); + return false; + } + } else { + alert('خطا در استخراج محصولات'); + return false; + } + }); + } +//===================================================================================================================== + $(function () { + // AJAX - Import Products + $('#ssbhesabix_import_products').submit(function () { + // show processing status + $('#ssbhesabix-import-product-submit').attr('disabled', 'disabled'); + $('#ssbhesabix-import-product-submit').removeClass('button-primary'); + $('#ssbhesabix-import-product-submit').html(' در حال ورود کالاها از حسابیکس, لطفاً صبر کنید...'); + $('#ssbhesabix-import-product-submit i.spinner').show(); + + $('#importProductsProgress').show(); + $('#importProductsProgressBar').css('width', 0 + '%').attr('aria-valuenow', 0); + + importProducts(1, 1, 1, 0); + + return false; + }); + }); +//===================================================================================================================== + function importProducts(batch, totalBatch, total, updateCount) { + var data = { + 'action': 'adminImportProducts', + 'batch': batch, + 'totalBatch': totalBatch, + 'total': total, + 'updateCount': updateCount + }; + $.post(ajaxurl, data, function (response) { + if ('failed' !== response) { + const res = JSON.parse(response); + res.batch = parseInt(res.batch); + if (res.batch < res.totalBatch) { + let progress = (res.batch * 100) / res.totalBatch; + progress = Math.round(progress); + $('#importProductsProgressBar').css('width', progress + '%').attr('aria-valuenow', progress); + //alert('batch: ' + res.batch + ', totalBatch: ' + res.totalBatch + ', total: ' + res.total); + importProducts(res.batch + 1, res.totalBatch, res.total, res.updateCount); + return false; + } else { + $('#importProductsProgressBar').css('width', 100 + '%').attr('aria-valuenow', 100); + setTimeout(() => { + top.location.replace(res.redirectUrl); + }, 1000); + return false; + } + } else { + alert('خطا در وارد کردن محصولات'); + return false; + } + }); + } +//===================================================================================================================== + $(function () { + // AJAX - Export Products opening quantity + $('#ssbhesabix_export_products_opening_quantity').submit(function () { + // show processing status + $('#ssbhesabix-export-product-opening-quantity-submit').attr('disabled', 'disabled'); + $('#ssbhesabix-export-product-opening-quantity-submit').removeClass('button-primary'); + $('#ssbhesabix-export-product-opening-quantity-submit').html(' استخراج موجودی اول دوره...'); + $('#ssbhesabix-export-product-opening-quantity-submit i.spinner').show(); + + $('#exportProductsOpeningQuantityProgress').show(); + $('#exportProductsOpeningQuantityProgressBar').css('width', 0 + '%').attr('aria-valuenow', 0); + + exportProductsOpeningQuantity(1, 1, 1); + + return false; + }); + }); + + function exportProductsOpeningQuantity(batch, totalBatch, total) { + var data = { + 'action': 'adminExportProductsOpeningQuantity', + 'batch': batch, + 'totalBatch': totalBatch, + 'total': total + }; + $.post(ajaxurl, data, function (response) { + if ('failed' !== response) { + const res = JSON.parse(response); + res.batch = parseInt(res.batch); + if (res.batch < res.totalBatch) { + let progress = (res.batch * 100) / res.totalBatch; + progress = Math.round(progress); + $('#exportProductsOpeningQuantityProgressBar').css('width', progress + '%').attr('aria-valuenow', progress); + exportProductsOpeningQuantity(res.batch + 1, res.totalBatch, res.total); + return false; + } else { + $('#exportProductsOpeningQuantityProgressBar').css('width', 100 + '%').attr('aria-valuenow', 100); + setTimeout(() => { + top.location.replace(res.redirectUrl); + }, 1000); + return false; + } + } else { + alert('خطا در استخراج موجودی اول دوره'); + return false; + } + }); + } +//===================================================================================================================== + $(function () { + // AJAX - Export Customers + $('#ssbhesabix_export_customers').submit(function () { + // show processing status + $('#ssbhesabix-export-customer-submit').attr('disabled', 'disabled'); + $('#ssbhesabix-export-customer-submit').removeClass('button-primary'); + $('#ssbhesabix-export-customer-submit').html(' خروجی مشتریان، لطفاً صبر کنید...'); + $('#ssbhesabix-export-customer-submit i.spinner').show(); + + $('#exportCustomersProgress').show(); + $('#exportCustomersProgressBar').css('width', 0 + '%').attr('aria-valuenow', 0); + + exportCustomers(1, 1, 1, 0); + + return false; + }); + }); + + function exportCustomers(batch, totalBatch, total, updateCount) { + const data = { + 'action': 'adminExportCustomers', + 'batch': batch, + 'totalBatch': totalBatch, + 'total': total, + 'updateCount': updateCount + }; + $.post(ajaxurl, data, function (response) { + if (response !== 'failed') { + const res = JSON.parse(response); + res.batch = parseInt(res.batch); + if (res.batch < res.totalBatch) { + let progress = (res.batch * 100) / res.totalBatch; + progress = Math.round(progress); + $('#exportCustomersProgressBar').css('width', progress + '%').attr('aria-valuenow', progress); + exportCustomers(res.batch + 1, res.totalBatch, res.total, res.updateCount); + return false; + } else { + $('#exportCustomersProgressBar').css('width', 100 + '%').attr('aria-valuenow', 100); + setTimeout(() => { + top.location.replace(res.redirectUrl); + }, 1000); + return false; + } + } else { + alert('خطا در استخراج مشتریان'); + return false; + } + }); + } +//===================================================================================================================== + $(function () { + // AJAX - Sync Changes + $('#ssbhesabix_sync_changes').submit(function () { + // show processing status + $('#ssbhesabix-sync-changes-submit').attr('disabled', 'disabled'); + $('#ssbhesabix-sync-changes-submit').removeClass('button-primary'); + $('#ssbhesabix-sync-changes-submit').html(' همسان سازی تغییرات...'); + $('#ssbhesabix-sync-changes-submit i.spinner').show(); + + var data = { + 'action': 'adminSyncChanges' + }; + + // post it + $.post(ajaxurl, data, function (response) { + if ('failed' !== response) { + var redirectUrl = response; + + /** Debug **/ + // console.log(redirectUrl); + // return false; + + top.location.replace(redirectUrl); + return false; + } else { + alert('خطا در همگام سازی تغییرات'); + return false; + } + }); + /*End Post*/ + return false; + }); + }); +//===================================================================================================================== + $(function () { + // AJAX - Sync Products + $('#ssbhesabix_sync_products').submit(function () { + + // show processing status + $('#ssbhesabix-sync-products-submit').attr('disabled', 'disabled'); + $('#ssbhesabix-sync-products-submit').removeClass('button-primary'); + $('#ssbhesabix-sync-products-submit').html(' همسان سازی محصولات...'); + $('#ssbhesabix-sync-products-submit i.spinner').show(); + + $('#syncProductsProgress').show(); + $('#syncProductsProgressBar').css('width', 0 + '%').attr('aria-valuenow', 0); + + syncProducts(1, 1, 1); + + return false; + }); + }); +//===================================================================================================================== + function syncProducts(batch, totalBatch, total) { + const data = { + 'action': 'adminSyncProducts', + 'batch': batch, + 'totalBatch': totalBatch, + 'total': total + }; + //$.post(URL, DATA, CALLBACK) + $.post(ajaxurl, data, function (response) { + if (response !== 'failed') { + const res = JSON.parse(response); + res.batch = parseInt(res.batch); + if (res.batch < res.totalBatch) { + let progress = (res.batch * 100) / res.totalBatch; + progress = Math.round(progress); + $('#syncProductsProgressBar').css('width', progress + '%').attr('aria-valuenow', progress); + //alert('batch: ' + res.batch + ', totalBatch: ' + res.totalBatch + ', total: ' + res.total); + syncProducts(res.batch + 1, res.totalBatch, res.total); + return false; + } else { + $('#syncProductsProgressBar').css('width', 100 + '%').attr('aria-valuenow', 100); + setTimeout(() => { + top.location.replace(res.redirectUrl); + }, 1000); + return false; + } + } else { + alert('خطا در همگام سازی محصولات'); + return false; + } + }); + } +//===================================================================================================================== + $(function () { + // AJAX - Sync Orders + $('#ssbhesabix_sync_orders').submit(function () { + // show processing status + $('#ssbhesabix-sync-orders-submit').attr('disabled', 'disabled'); + $('#ssbhesabix-sync-orders-submit').removeClass('button-primary'); + $('#ssbhesabix-sync-orders-submit').html(' همسان سازی سفارشات...'); + $('#ssbhesabix-sync-orders-submit i.spinner').show(); + + $('#syncOrdersProgress').show(); + $('#syncOrdersProgressBar').css('width', 0 + '%').attr('aria-valuenow', 0); + + syncOrders(1, 1, 1, 0); + + return false; + }); + }); + + function syncOrders(batch, totalBatch, total, updateCount) { + var date = $('#ssbhesabix_sync_order_date').val(); + var endDate = $('#ssbhesabix_sync_order_end_date').val(); + + const data = { + 'action': 'adminSyncOrders', + 'date': date, + 'endDate': endDate, + 'batch': batch, + 'totalBatch': totalBatch, + 'total': total, + 'updateCount': updateCount, + }; + + $.post(ajaxurl, data, function (response) { + if (response !== 'failed') { + const res = JSON.parse(response); + res.batch = parseInt(res.batch); + if(res.batch) $('#syncOrdersStatistics').html(`
پارت: ${res.batch} از ${res.totalBatch} - تعداد کل: ${res.total}
`); + if (res.batch < res.totalBatch) { + let progress = (res.batch * 100) / res.totalBatch; + progress = Math.round(progress); + $('#syncOrdersProgressBar').css('width', progress + '%').attr('aria-valuenow', progress); + syncOrders(res.batch + 1, res.totalBatch, res.total, res.updateCount); + return false; + } else { + $('#syncOrdersProgressBar').css('width', 100 + '%').attr('aria-valuenow', 100); + setTimeout(() => { + top.location.replace(res.redirectUrl); + }, 1000); + return false; + } + } else { + alert('خطا در همگام سازی سفارشات'); + return false; + } + }); + } +//===================================================================================================================== + $(function () { + // AJAX - Sync Products + $('#ssbhesabix_update_products').submit(function () { + // show processing status + $('#ssbhesabix-update-products-submit').attr('disabled', 'disabled'); + $('#ssbhesabix-update-products-submit').removeClass('button-primary'); + $('#ssbhesabix-update-products-submit').html(' بروزرسانی محصولات...'); + $('#ssbhesabix-update-products-submit i.spinner').show(); + + $('#updateProductsProgress').show(); + $('#updateProductsProgressBar').css('width', 0 + '%').attr('aria-valuenow', 0); + + updateProducts(1, 1, 1); + + return false; + }); + }); +//===================================================================================================================== + function updateProducts(batch, totalBatch, total) { + var data = { + 'action': 'adminUpdateProducts', + 'batch': batch, + 'totalBatch': totalBatch, + 'total': total + }; + $.post(ajaxurl, data, function (response) { + if ('failed' !== response) { + const res = JSON.parse(response); + res.batch = parseInt(res.batch); + if (res.batch < res.totalBatch) { + let progress = (res.batch * 100) / res.totalBatch; + progress = Math.round(progress); + $('#updateProductsProgressBar').css('width', progress + '%').attr('aria-valuenow', progress); + updateProducts(res.batch + 1, res.totalBatch, res.total); + return false; + } else { + $('#updateProductsProgressBar').css('width', 100 + '%').attr('aria-valuenow', 100); + setTimeout(() => { + top.location.replace(res.redirectUrl); + }, 1000); + return false; + } + } else { + alert('خطا در بروزرسانی محصولات'); + return false; + } + }); + } + +//===================================================================================================================== + + // $(function () { + // // AJAX - Sync Products with ID filter + // $('#ssbhesabix_update_products_with_filter').submit(function (e) { + // + // // Show processing status + // var submitButton = $('#ssbhesabix-update-products-with-filter-submit'); + // submitButton.removeClass('button-primary'); + // submitButton.html(' بروزرسانی محصولات...'); + // }); + // }); + + + + $(function () { + // AJAX - Sync Products + $('#ssbhesabix_update_products_with_filter').submit(function () { + let submitButton = $('#ssbhesabix-update-products-with-filter-submit'); + let offset = document.getElementById("ssbhesabix-update-products-offset").value; + let rpp = document.getElementById("ssbhesabix-update-products-rpp").value; + submitButton.removeClass('button-primary'); + submitButton.html(' بروزرسانی محصولات لطفا صبر کنید...'); + $('#ssbhesabix-update-products-with-filter-submit').attr('disabled', 'disabled'); + + updateProductsWithFilter(offset, rpp); + + return false; + }); + }); +//===================================================================================================================== + function updateProductsWithFilter(offset, rpp) { + var data = { + 'action': 'adminUpdateProductsWithFilter', + 'offset': offset, + 'rpp': rpp, + }; + if(offset && rpp) { + $.post(ajaxurl, data, function (response) { + if ('failed' !== response) { + const res = JSON.parse(response); + if(!res.error) { + top.location.replace(res.redirectUrl); + } + } else { + alert('خطا در بروزرسانی محصولات'); + return false; + } + }); + } else { + alert('فیلد ها را به درستی وارد نمایید'); + submitButton.addClass('button-primary'); + submitButton.html('بروزرسانی محصولات در حسابیکس بر اساس فروشگاه در بازه ID مشخص شده'); + $('#ssbhesabix-update-products-with-filter-submit').removeAttr('disabled'); + return false; + } + } + +//===================================================================================================================== + $(function () { + // AJAX - Clean log + $('#ssbhesabix_clean_log').submit(function (e) { + // show processing status + $('#ssbhesabix-log-clean-submit').attr('disabled', 'disabled'); + $('#ssbhesabix-log-clean-submit').removeClass('button-primary'); + $('#ssbhesabix-log-clean-submit').html(' پاک کردن فایل لاگ، لطفاً صبر کنید...'); + $('#ssbhesabix-log-clean-submit i.spinner').show(); + + var data = { + 'action': 'adminCleanLogFile' + }; + + // post it + $.post(ajaxurl, data, function (response) { + if ('failed' !== response) { + var redirectUrl = response; + + /** Debug **/ + // console.log(redirectUrl); + // return false; + + top.location.replace(redirectUrl); + return false; + } else { + alert('خطا در پاکسازی فایل لاگ'); + return false; + } + }); + /*End Post*/ + return false; + }); + }); +//===================================================================================================================== + $(function () { + // AJAX - Sync Products Manually + $('#ssbhesabix_sync_products_manually').submit(function () { + // show processing status + $('#ssbhesabix_sync_products_manually-submit').attr('disabled', 'disabled'); + $('#ssbhesabix_sync_products_manually-submit').removeClass('button-primary'); + $('#ssbhesabix_sync_products_manually-submit').html(' ذخیره کردن اطلاعات...'); + $('#ssbhesabix_sync_products_manually i.spinner').show(); + + const inputArray = []; + const inputs = $('.code-input'); + console.log(inputs); + for (var n = 0; n < inputs.length; n++) { + var i = inputs[n]; + console.log(i); + const obj = { + id: $(i).attr('id'), + hesabix_id: $(i).val(), + parent_id: $(i).attr('data-parent-id') + } + inputArray.push(obj); + } + + const page = $('#pageNumber').val(); + const rpp = $('#goToPage').attr('data-rpp'); + + var data = { + 'action': 'adminSyncProductsManually', + 'data': JSON.stringify(inputArray), + 'page': page, + 'rpp': rpp + }; + + // post it + $.post(ajaxurl, data, function (response) { + if ('failed' !== response) { + var redirectUrl = response; + + /** Debug **/ + // console.log(redirectUrl); + // return false; + + top.location.replace(redirectUrl); + return false; + } else { + alert('خطا در ذخیره اطلاعات'); + return false; + } + }); + /*End Post*/ + return false; + }); + + $("#goToPage").click(function () { + const page = $('#pageNumber').val(); + const rpp = $('#goToPage').attr('data-rpp'); + window.location.href = "?page=hesabix-sync-products-manually&p=" + page + "&rpp=" + rpp; + }); + + $("#show-tips-btn").click(function () { + $('#tips-alert').removeClass('d-none'); + $('#tips-alert').addClass('d-block'); + }); + + $("#hide-tips-btn").click(function () { + $('#tips-alert').removeClass('d-block'); + $('#tips-alert').addClass('d-none'); + }); + }); + + $(".btn-submit-invoice").on( "click", function() { + var orderId = $(this).attr("data-order-id"); + + var btnEl = $('.btn-submit-invoice[data-order-id=' + orderId + ']'); + + btnEl.attr('aria-disabled', true); + btnEl.addClass('disabled'); + btnEl.html('ثبت فاکتور...'); + //btnEl.show(); + + submitInvoice(orderId); + }); +//===================================================================================================================== + function submitInvoice(orderId) { + var data = { + 'action': 'adminSubmitInvoice', + 'orderId': orderId + }; + $.post(ajaxurl, data, function (response) { + if ('failed' !== response) { + const res = JSON.parse(response); + // refresh page + location.reload(); + } else { + alert('خطا در ثبت فاکتور'); + return false; + } + }); + } + + // change business warning + var oldApiKey = ''; + $("#changeBusinessWarning").hide(); + + $("#ssbhesabix_account_api").focusin( function () { + oldApiKey = $("#ssbhesabix_account_api" ).val(); + }); + $("#ssbhesabix_account_api").focusout( function () { + var newApiKey = $("#ssbhesabix_account_api" ).val(); + if(oldApiKey != '' && oldApiKey != newApiKey) { + $("#changeBusinessWarning").show(); + } + }); +//===================================================================================================================== + $(function () { + // AJAX - clear all plugin data + $('#hesabix-clear-plugin-data').click(function () { + if (confirm('هشدار: با انجام این عملیات کلیه اطلاعات افزونه شامل روابط بین کالاها، مشتریان و فاکتور ها و همینطور تنظیمات افزونه حذف می گردد.' + + 'آیا از انجام این عملیات مطمئن هستید؟')) { + $('#hesabix-clear-plugin-data').addClass('disabled'); + $('#hesabix-clear-plugin-data').html('حذف دیتای افزونه...'); + var data = { + 'action': 'adminClearPluginData' + }; + $.post(ajaxurl, data, function (response) { + $('#hesabix-clear-plugin-data').removeClass('disabled'); + $('#hesabix-clear-plugin-data').html('حذف دیتای افزونه'); + if ('failed' !== response) { + alert('دیتای افزونه با موفقیت حذف شد.'); + return false; + } else { + alert('خطا در هنگام حذف دیتای افزونه.'); + return false; + } + }); + } else { + // Do nothing! + } + return false; + }); + + $('#hesabix-install-plugin-data').click(function () { + if (confirm('با انجام این عملیات جدول افزونه در دیتابیس وردپرس ایجاد' + + ' و تنظیمات پیش فرض افزونه تنظیم می گردد.' + + ' آیا از انجام این عملیات مطمئن هستید؟')) { + $('#hesabix-install-plugin-data').addClass('disabled'); + $('#hesabix-install-plugin-data').html('نصب دیتای افزونه...'); + var data = { + 'action': 'adminInstallPluginData' + }; + $.post(ajaxurl, data, function (response) { + $('#hesabix-install-plugin-data').removeClass('disabled'); + $('#hesabix-install-plugin-data').html('نصب دیتای افزونه'); + if ('failed' !== response) { + alert('دیتای افزونه با موفقیت نصب شد.'); + return false; + } else { + alert('خطا در هنگام نصب دیتای افزونه.'); + return false; + } + }); + } else { + // Do nothing! + } + return false; + }); + }); +//===================================================================================================================== + $(function () { + //SAVE + $(".hesabix-item-save").on('click', function (){ + const productId = $("#panel_product_data_hesabix").data('product-id'); + const attributeId = $(this).data('id'); + const code = $("#hesabix-item-" + attributeId).val(); + var data = { + 'action': 'adminChangeProductCode', + 'productId': productId, + 'attributeId': attributeId, + 'code': code, + }; + $(this).prop('disabled', true); + const _this = this; + $.post(ajaxurl, data, function (response) { + $(_this).prop('disabled', false); + if ('failed' !== response) { + const res = JSON.parse(response); + alert(res.error ? res.message : 'کد کالای متصل با موفقیت تغییر کرد.'); + if(productId === attributeId) + $("#ssbhesabix_hesabix_item_code_0").val(code); + else + $("#ssbhesabix_hesabix_item_code_" + attributeId).val(code); + return false; + } else { + alert('خطا در هنگام تغییر کد کالای متصل.'); + return false; + } + }); + }); + //DELETE LINK + $(".hesabix-item-delete-link").on('click', function (){ + const productId = $("#panel_product_data_hesabix").data('product-id'); + const attributeId = $(this).data('id'); + var data = { + 'action': 'adminDeleteProductLink', + 'productId': productId, + 'attributeId': attributeId + }; + $(this).prop('disabled', true); + const _this = this; + $.post(ajaxurl, data, function (response) { + $(_this).prop('disabled', false); + if ('failed' !== response) { + const res = JSON.parse(response); + $("#hesabix-item-" + attributeId).val(''); + if(productId === attributeId) + $("#ssbhesabix_hesabix_item_code_0").val(''); + else + $("#ssbhesabix_hesabix_item_code_" + attributeId).val(''); + setTimeout(function (){ + alert(res.error ? res.message : 'ارتباط محصول با موفقیت حذف شد'); + }, 100); + return false; + } else { + alert('خطا در هنگام حذف ارتباط'); + return false; + } + }); + }); + //UPDATE + $(".hesabix-item-update").on('click', function (){ + const productId = $("#panel_product_data_hesabix").data('product-id'); + const attributeId = $(this).data('id'); + var data = { + 'action': 'adminUpdateProduct', + 'productId': productId, + 'attributeId': attributeId + }; + $(this).prop('disabled', true); + const _this = this; + $.post(ajaxurl, data, function (response) { + $(_this).prop('disabled', false); + if ('failed' !== response) { + const res = JSON.parse(response); + if(res.newPrice != null) + $("#hesabix-item-price-" + attributeId).text(res.newPrice); + if(res.newQuantity != null) + $("#hesabix-item-quantity-" + attributeId).text(res.newQuantity); + if(res.error) + alert(res.message); + return false; + } else { + alert('خطا در هنگام بروزرسانی محصول'); + return false; + } + }); + }); + //SAVE ALL + $("#hesabix-item-save-all").on('click', function (){ + const productId = $("#panel_product_data_hesabix").data('product-id'); + const itemsCode = $(".hesabix-item-code"); + const itemsData = []; + for (let i = 0; i < itemsCode.length; i++) { + const item = itemsCode[i]; + const attributeId = $(item).data('id'); + const code = $(item).val(); + itemsData.push({attributeId: attributeId, code: code}); + } + + var data = { + 'action': 'adminChangeProductsCode', + 'productId': productId, + 'itemsData': itemsData + }; + $(this).prop('disabled', true); + const _this = this; + $.post(ajaxurl, data, function (response) { + $(_this).prop('disabled', false); + if ('failed' !== response) { + const res = JSON.parse(response); + alert(res.error ? res.message : 'کد کالاهای متصل با موفقیت تغییر کرد.'); + location.reload(); + return false; + } else { + alert('خطا در هنگام تغییر کد کالاهای متصل'); + return false; + } + }); + }); + //DELETE + $("#hesabix-item-delete-link-all").on('click', function (){ + const productId = $("#panel_product_data_hesabix").data('product-id'); + var data = { + 'action': 'adminDeleteProductsLink', + 'productId': productId + }; + $(this).prop('disabled', true); + const _this = this; + $.post(ajaxurl, data, function (response) { + $(_this).prop('disabled', false); + if ('failed' !== response) { + const res = JSON.parse(response); + const itemsCode = $(".hesabix-item-code"); + for (let i = 0; i < itemsCode.length; i++) { + const item = itemsCode[i]; + $(item).val(''); + } + $('[id^="ssbhesabix_hesabix_item_code_"]').val(''); + setTimeout(function (){ + alert(res.error ? res.message : 'ارتباط محصولات با موفقیت حذف شد.'); + }, 100); + return false; + } else { + alert('خطا در هنگام حذف ارتباط'); + return false; + } + }); + }); + //UPDATE ALL + $("#hesabix-item-update-all").on('click', function (){ + const productId = $("#panel_product_data_hesabix").data('product-id'); + var data = { + 'action': 'adminUpdateProductAndVariations', + 'productId': productId + }; + $(this).prop('disabled', true); + const _this = this; + $.post(ajaxurl, data, function (response) { + $(_this).prop('disabled', false); + if ('failed' !== response) { + const res = JSON.parse(response); + if(res.error) + { + alert(res.message); + return false; + } + for (let i = 0; i < res.newData.length; i++) { + if(res.newData[i].newPrice != null) + $("#hesabix-item-price-" + res.newData[i].attributeId).text(res.newData[i].newPrice); + if(res.newData[i].newQuantity != null) + $("#hesabix-item-quantity-" + res.newData[i].attributeId).text(res.newData[i].newQuantity); + } + return false; + } else { + alert('خطا در هنگام بروزرسانی محصول'); + return false; + } + }); + }); + }); +//===================================================================================================================== + $(function (){ + let radio = $('input:radio[name="addFieldsRadio"]'); + let radioChecked = $('input:radio[name="addFieldsRadio"]:checked'); + let textInput = $('.contact_text_input'); + + if(radioChecked.val() === '2'){ + textInput.prop( "disabled", false ); + }else { + textInput.prop( "disabled", true ); + } + $(radio).on('click',function (){ + if($(this).val() === '2'){ + textInput.prop( "disabled", false ); + }else { + textInput.prop( "disabled", true ); + } + }); + + }); +}); +//===================================================================================================================== +function hesabixTutorialJumpTo(time) { + let vidEl = document.getElementById('hesabix-tutorial-video'); + vidEl.play(); + vidEl.pause(); + vidEl.currentTime = time; + vidEl.play(); +} diff --git a/admin/partials/ssbhesabix-admin-display.php b/admin/partials/ssbhesabix-admin-display.php index c0e6e9c..7a9233d 100644 --- a/admin/partials/ssbhesabix-admin-display.php +++ b/admin/partials/ssbhesabix-admin-display.php @@ -1,345 +1,397 @@ - - * @author HamidReza Gharahzadeh - * @author Babak Alizadeh - * @author Sepehr Najafi - */ - -class Ssbhesabix_Admin_Display -{ - /** - * Ssbhesabix_Admin_Display constructor. - */ - public function __construct() - { - add_action('admin_menu', array(__CLASS__, 'hesabix_add_menu')); - } - - /** - * Hook in methods - * @since 1.0.0 - * @access static - */ - - /** - * @since 1.0.0 - * @access public - */ - - static function hesabix_add_menu() - { - $iconUrl = plugins_url('/hesabix-accounting/admin/img/menu-icon.png'); - add_menu_page("حسابیکس", "حسابیکس", "manage_options", "ssbhesabix-option", array(__CLASS__, 'hesabix_plugin_page'), $iconUrl, null); - add_submenu_page("ssbhesabix-option", "تنظیمات حسابیکس", "تنظیمات حسابیکس", "manage_options", 'ssbhesabix-option', array(__CLASS__, 'hesabix_plugin_page')); - } - - function hesabix_plugin_sync_products_manually() - { - $page = $_GET["p"]; - $rpp = $_GET["rpp"]; - if (isset($_GET['data'])) { - $data = $_GET["data"]; - $codesNotFoundInHesabix = explode(",", $data); - } - //set default values to page and rpp - if (!$page) $page = 1; - if (!$rpp) $rpp = 10; - - $result = self::getProductsAndRelations($page, $rpp); - $pageCount = ceil($result["totalCount"] / $rpp); - $i = ($page - 1) * $rpp; - $rpp_options = [10, 15, 20, 30, 50]; - - $showTips = true; - if (!isset($_COOKIE['syncProductsManuallyHelp'])) { - setcookie('syncProductsManuallyHelp', 'ture'); - } else { - $showTips = false; - } - - self::hesabix_plugin_header(); - ?> -
-

-

- همسان سازی دستی کالاهای فروشگاه با حسابیکس - مشاهده نکات مهم -
- - - - - -

-
- - - - - - - - - - - - - - - - - - - - - - -
#IDنام کالاشناسه محصولکد حسابیکس
ID; ?>post_title; ?>sku; ?> - -
- - | - | - - - برو - - - < صفحه قبل - صفحه بعد > - -
- -
-
-
- get_results("SELECT id_hesabix FROM " . $wpdb->prefix . "ssbhesabix WHERE obj_type = 'product' GROUP BY id_hesabix HAVING COUNT(id_hesabix) > 1;"); - $ids = array(); - - foreach ($rows as $row) - $ids[] = $row->id_hesabix; - - $idsStr = implode(',', $ids); - $rows = $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "ssbhesabix WHERE obj_type = 'product' AND id_hesabix IN ($idsStr) ORDER BY id_hesabix"); - $i = 0; - - self::hesabix_plugin_header(); - ?> -
-
- کد محصولات تکراری -
- - - - - - - - - - - - - - - - - - - -
#کد حسابیکسشناسه محصولشناسه متغیر
id_hesabix; ?>id_ps; ?>id_ps_attribute; ?>
-
- -
-
- ابزارهای افزونه حسابیکس -
- - حذف دیتای افزونه -
- نصب دیتای افزونه -
- get_results("SELECT post.ID,post.post_title,post.post_parent,post_excerpt,wc.sku FROM `" . $wpdb->prefix . "posts` as post - LEFT OUTER JOIN `" . $wpdb->prefix . "wc_product_meta_lookup` as wc - ON post.id = wc.product_id - WHERE post.post_type IN('product','product_variation') AND post.post_status IN('publish','private') - ORDER BY post.post_title ASC LIMIT $offset,$rpp"); - - $totalCount = $wpdb->get_var("SELECT COUNT(*) FROM `" . $wpdb->prefix . "posts` as post - LEFT OUTER JOIN `" . $wpdb->prefix . "wc_product_meta_lookup` as wc - ON post.id = wc.product_id - WHERE post.post_type IN('product','product_variation') AND post.post_status IN('publish','private')"); - - $links = $wpdb->get_results("SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` - WHERE obj_type ='product'"); - - foreach ($rows as $r) { - if ($r->post_excerpt) - $r->post_title = $r->post_title . ' [' . $r->post_excerpt . ']'; - } - - foreach ($links as $link) { - foreach ($rows as $r) { - if ($r->ID == $link->id_ps && $link->id_ps_attribute == 0) { - $r->id_hesabix = $link->id_hesabix; - } else if ($r->ID == $link->id_ps_attribute) { - $r->id_hesabix = $link->id_hesabix; - } - } - } - - return array("data" => $rows, "totalCount" => $totalCount); - } -//======================================================================================================================================== - /** - * @since 1.0.0 - * @access public - */ - public static function hesabix_plugin_page() - { - $iconsArray = ['home', 'cog', 'box-open', 'users', 'file-invoice-dollar', 'money-check-alt', 'file-export', 'sync-alt', 'file-alt', 'cog']; - if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) { - $setting_tabs = apply_filters('ssbhesabix_setting_tab', array( - 'home' => __('Home', 'ssbhesabix'), - 'api' => __('API', 'ssbhesabix'), - 'catalog' => __('Catalog', 'ssbhesabix'), - 'customers' => __('Customers', 'ssbhesabix'), - 'invoice' => __('Invoice', 'ssbhesabix'), - 'payment' => __('Payment Methods', 'ssbhesabix'), - 'export' => __('Import and export data', 'ssbhesabix'), - 'sync' => __('Sync', 'ssbhesabix'), - 'log' => __('Log', 'ssbhesabix'), - 'extra' => __('Extra Settings', 'ssbhesabix') - )); - $current_tab = (isset($_GET['tab'])) ? wc_clean($_GET['tab']) : 'home'; - self::hesabix_plugin_header(); - ?> - - $setting_tabvalue) { - switch ($setting_tabkey) { - case $current_tab: - do_action('ssbhesabix_' . $setting_tabkey . '_setting_save_field'); - do_action('ssbhesabix_' . $setting_tabkey . '_setting'); - break; - } - } - } else { - echo '
' . __('Hesabix Plugin requires the WooCommerce to work!, Please install/activate woocommerce and try again', 'ssbhesabix') . '
'; - } - } -//======================================================================================================================================== - public static function hesabix_plugin_header() - { - $logoUrl = plugins_url('/hesabix-accounting/admin/img/hesabix-logo.fa.png'); - ?> - - + * @author HamidReza Gharahzadeh + * @author Sepehr Najafi + */ + +class Ssbhesabix_Admin_Display +{ + /** + * Ssbhesabix_Admin_Display constructor. + */ + public function __construct() + { + add_action('admin_menu', array(__CLASS__, 'hesabix_add_menu')); + } + + /** + * Hook in methods + * @since 1.0.0 + * @access static + */ + + /** + * @since 1.0.0 + * @access public + */ + + static function hesabix_add_menu() + { + $iconUrl = plugins_url('/hesabix-accounting/admin/img/menu-icon.png'); + add_menu_page("حسابیکس", "حسابیکس", "manage_options", "ssbhesabix-option", array(__CLASS__, 'hesabix_plugin_page'), $iconUrl, null); + add_submenu_page("ssbhesabix-option", "تنظیمات حسابیکس", "تنظیمات حسابیکس", "manage_options", 'ssbhesabix-option', array(__CLASS__, 'hesabix_plugin_page')); + } + + function hesabix_plugin_sync_products_manually() + { + $page = $_GET["p"]; + $rpp = $_GET["rpp"]; + if (isset($_GET['data'])) { + $data = $_GET["data"]; + $codesNotFoundInHesabix = explode(",", $data); + } + //set default values to page and rpp + if (!$page) $page = 1; + if (!$rpp) $rpp = 10; + + $result = self::getProductsAndRelations($page, $rpp); + $pageCount = ceil($result["totalCount"] / $rpp); + $i = ($page - 1) * $rpp; + $rpp_options = [10, 15, 20, 30, 50]; + + $showTips = true; + if (!isset($_COOKIE['syncProductsManuallyHelp'])) { + setcookie('syncProductsManuallyHelp', 'ture'); + } else { + $showTips = false; + } + + self::hesabix_plugin_header(); + ?> +
+

+

+ همسان سازی دستی کالاهای فروشگاه با حسابیکس + مشاهده نکات مهم +
+ + + + + +

+
+ + + + + + + + + + + + + + + + + + + + + + +
#IDنام کالاشناسه محصولکد حسابیکس
ID; ?>post_title; ?>sku; ?> + +
+ + | + | + + + برو + + + < صفحه قبل + صفحه بعد > + +
+ +
+
+
+ get_results("SELECT id_hesabix FROM " . $wpdb->prefix . "ssbhesabix WHERE obj_type = 'product' GROUP BY id_hesabix HAVING COUNT(id_hesabix) > 1;"); + + $rows = $wpdb->get_results( + "SELECT id_hesabix + FROM {$wpdb->prefix}ssbhesabix + WHERE obj_type = 'product' + GROUP BY id_hesabix + HAVING COUNT(id_hesabix) > 1" + ); + + $ids = array(); + + foreach ($rows as $row) + $ids[] = $row->id_hesabix; + + $idsStr = implode(',', $ids); + //$rows = $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "ssbhesabix WHERE obj_type = 'product' AND id_hesabix IN ($idsStr) ORDER BY id_hesabix"); + + $rows = $wpdb->get_results( + $wpdb->prepare( + "SELECT * + FROM {$wpdb->prefix}ssbhesabix + WHERE obj_type = 'product' + AND id_hesabix IN ($idsStr) + ORDER BY id_hesabix" + ) + ); + + $i = 0; + + self::hesabix_plugin_header(); + ?> +
+
+ کد محصولات تکراری +
+ + + + + + + + + + + + + + + + + + + +
#کد حسابیکسشناسه محصولشناسه متغیر
id_hesabix; ?>id_ps; ?>id_ps_attribute; ?>
+
+ +
+
+ ابزارهای افزونه حسابیکس +
+ + حذف دیتای افزونه +
+ نصب دیتای افزونه +
+ get_results("SELECT post.ID,post.post_title,post.post_parent,post_excerpt,wc.sku FROM `" . $wpdb->prefix . "posts` as post +// LEFT OUTER JOIN `" . $wpdb->prefix . "wc_product_meta_lookup` as wc +// ON post.id = wc.product_id +// WHERE post.post_type IN('product','product_variation') AND post.post_status IN('publish','private') +// ORDER BY post.post_title ASC LIMIT $offset,$rpp"); + + $rows = $wpdb->get_results( + $wpdb->prepare( + "SELECT post.ID, post.post_title, post.post_parent, post.post_excerpt, wc.sku + FROM {$wpdb->posts} AS post + LEFT OUTER JOIN {$wpdb->prefix}wc_product_meta_lookup AS wc + ON post.ID = wc.product_id + WHERE post.post_type IN ('product', 'product_variation') + AND post.post_status IN ('publish', 'private') + ORDER BY post.post_title ASC + LIMIT %d, %d", + $offset, + $rpp + ) + ); + + + +// $totalCount = $wpdb->get_var("SELECT COUNT(*) FROM `" . $wpdb->prefix . "posts` as post +// LEFT OUTER JOIN `" . $wpdb->prefix . "wc_product_meta_lookup` as wc +// ON post.id = wc.product_id +// WHERE post.post_type IN('product','product_variation') AND post.post_status IN('publish','private')"); + + $totalCount = $wpdb->get_var( + "SELECT COUNT(*) + FROM {$wpdb->posts} AS post + LEFT OUTER JOIN {$wpdb->prefix}wc_product_meta_lookup AS wc + ON post.ID = wc.product_id + WHERE post.post_type IN ('product', 'product_variation') + AND post.post_status IN ('publish', 'private')" + ); + + +// $links = $wpdb->get_results("SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` +// WHERE obj_type ='product'"); + + $links = $wpdb->get_results( + "SELECT * + FROM {$wpdb->prefix}ssbhesabix + WHERE obj_type = 'product'" + ); + + foreach ($rows as $r) { + if ($r->post_excerpt) + $r->post_title = $r->post_title . ' [' . $r->post_excerpt . ']'; + } + + foreach ($links as $link) { + foreach ($rows as $r) { + if ($r->ID == $link->id_ps && $link->id_ps_attribute == 0) { + $r->id_hesabix = $link->id_hesabix; + } else if ($r->ID == $link->id_ps_attribute) { + $r->id_hesabix = $link->id_hesabix; + } + } + } + + return array("data" => $rows, "totalCount" => $totalCount); + } +//======================================================================================================================================== + /** + * @since 1.0.0 + * @access public + */ + public static function hesabix_plugin_page() + { + $iconsArray = ['home', 'cog', 'box-open', 'users', 'file-invoice-dollar', 'money-check-alt', 'file-export', 'sync-alt', 'file-alt', 'cog']; + if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) { + $setting_tabs = apply_filters('ssbhesabix_setting_tab', array( + 'home' => __('Home', 'ssbhesabix'), + 'api' => __('API', 'ssbhesabix'), + 'catalog' => __('Catalog', 'ssbhesabix'), + 'customers' => __('Customers', 'ssbhesabix'), + 'invoice' => __('Invoice', 'ssbhesabix'), + 'payment' => __('Payment Methods', 'ssbhesabix'), + 'export' => __('Import and export data', 'ssbhesabix'), + 'sync' => __('Sync', 'ssbhesabix'), + 'log' => __('Log', 'ssbhesabix'), + 'extra' => __('Extra Settings', 'ssbhesabix') + )); + $current_tab = (isset($_GET['tab'])) ? wc_clean($_GET['tab']) : 'home'; + self::hesabix_plugin_header(); + ?> + + $setting_tabvalue) { + switch ($setting_tabkey) { + case $current_tab: + do_action('ssbhesabix_' . $setting_tabkey . '_setting_save_field'); + do_action('ssbhesabix_' . $setting_tabkey . '_setting'); + break; + } + } + } else { + echo '
' . __('Hesabix Plugin requires the WooCommerce to work!, Please install/activate woocommerce and try again', 'ssbhesabix') . '
'; + } + } +//======================================================================================================================================== + public static function hesabix_plugin_header() + { + $logoUrl = plugins_url('/hesabix-accounting/admin/img/hesabix-logo.fa.png'); + ?> + + - * @author HamidReza Gharahzadeh - * @author Sepehr Najafi - * @author Babak Alizadeh - */ -class Ssbhesabix_Admin_Functions -{ - public static function isDateInFiscalYear($date) - { - $hesabixApi = new Ssbhesabix_Api(); - $fiscalYear = $hesabixApi->settingGetFiscalYear(); - - if (is_object($fiscalYear)) { - - if ($fiscalYear->Success) { - $fiscalYearStartTimeStamp = strtotime($fiscalYear->Result->StartDate); - $fiscalYearEndTimeStamp = strtotime($fiscalYear->Result->EndDate); - $dateTimeStamp = strtotime($date); - - if ($dateTimeStamp >= $fiscalYearStartTimeStamp && $dateTimeStamp <= $fiscalYearEndTimeStamp) { - return 1; - } else { - return 0; - } - } else { - HesabixLogService::log(array("Cannot get FiscalDate. Error Code: $fiscalYear->ErrroCode. Error Message: $fiscalYear->ErrorMessage")); - return false; - } - } - HesabixLogService::log(array("Cannot connect to Hesabix for get FiscalDate.")); - return false; - } -//==================================================================================================================== - public function getProductVariations($id_product) - { - if (!isset($id_product)) { - return false; - } - $product = wc_get_product($id_product); - - if (is_bool($product)) return false; - if ($product->is_type('variable')) { - $children = $product->get_children($args = '', $output = OBJECT); - $variations = array(); - foreach ($children as $value) { - $product_variatons = new WC_Product_Variation($value); - if ($product_variatons->exists()) { - $variations[] = $product_variatons; - } - } - return $variations; - } - return false; - } -//======================================================================================================== - public function setItems($id_product_array) - { - if (!isset($id_product_array) || $id_product_array[0] == null) return false; - if (is_array($id_product_array) && empty($id_product_array)) return true; - - $items = array(); - foreach ($id_product_array as $id_product) { - $product = new WC_Product($id_product); - if ($product->get_status() === "draft") continue; - - $items[] = ssbhesabixItemService::mapProduct($product, $id_product, false); - - $variations = $this->getProductVariations($id_product); - if ($variations) - foreach ($variations as $variation) - $items[] = ssbhesabixItemService::mapProductVariation($product, $variation, $id_product, false); - } - - if (count($items) === 0) return false; - if (!$this->saveItems($items)) return false; - return true; - } -//==================================================================================================================== - public function saveItems($items) - { - $hesabix = new Ssbhesabix_Api(); - $wpFaService = new HesabixWpFaService(); - - $response = $hesabix->itemBatchSave($items); - if ($response->Success) { - foreach ($response->Result as $item) - $wpFaService->saveProduct($item); - return true; - } else { - HesabixLogService::log(array("Cannot add/update Hesabix items. Error Code: " . (string)$response->ErrorCode . ". Error Message: $response->ErrorMessage.")); - return false; - } - } -//==================================================================================================================== - public function getContactCodeByCustomerId($id_customer) - { - if (!isset($id_customer)) { - return false; - } - - global $wpdb; - $row = $wpdb->get_row("SELECT `id_hesabix` FROM " . $wpdb->prefix . "ssbhesabix WHERE `id_ps` = $id_customer AND `obj_type` = 'customer'"); - - if (is_object($row)) { - return $row->id_hesabix; - } else { - return null; - } - } -//==================================================================================================================== - public function setContact($id_customer, $type = 'first', $id_order = '') - { - if (!isset($id_customer)) return false; - - $code = $this->getContactCodeByCustomerId($id_customer); - - $hesabixCustomer = ssbhesabixCustomerService::mapCustomer($code, $id_customer, $type, $id_order); - - $hesabix = new Ssbhesabix_Api(); - $response = $hesabix->contactSave($hesabixCustomer); - - if ($response->Success) { - $wpFaService = new HesabixWpFaService(); - $wpFaService->saveCustomer($response->Result); - return $response->Result->Code; - } else { - HesabixLogService::log(array("Cannot add/update customer. Error Code: " . (string)$response->ErrroCode . ". Error Message: " . (string)$response->ErrorMessage . ". Customer ID: $id_customer")); - return false; - } - } -//==================================================================================================================== - public function setGuestCustomer($id_order) - { - if (!isset($id_order)) return false; - - //$order = new WC_Order($id_order); - $order = wc_get_order($id_order); - - $contactCode = $this->getContactCodeByPhoneOrEmail($order->get_billing_phone(), $order->get_billing_email()); - - $hesabixCustomer = ssbhesabixCustomerService::mapGuestCustomer($contactCode, $id_order); - - $hesabix = new Ssbhesabix_Api(); - $response = $hesabix->contactSave($hesabixCustomer); - - if ($response->Success) { - $wpFaService = new HesabixWpFaService(); - $wpFaService->saveCustomer($response->Result); - return (int)$response->Result->Code; - } else { - HesabixLogService::log(array("Cannot add/update contact. Error Code: " . (string)$response->ErrroCode . ". Error Message: " . (string)$response->ErrorMessage . ". Customer ID: Guest Customer")); - return false; - } - } -//==================================================================================================================== - public function getContactCodeByPhoneOrEmail($phone, $email) - { - if (!$email && !$phone) return null; - - $hesabix = new Ssbhesabix_Api(); - $response = $hesabix->contactGetByPhoneOrEmail($phone, $email); - - if (is_object($response)) { - if ($response->Success && $response->Result->TotalCount > 0) { - $contact_obj = $response->Result->List; - - if (!$contact_obj[0]->Code || $contact_obj[0]->Code == '0' || $contact_obj[0]->Code == '000000') return null; - - foreach ($contact_obj as $contact) { - if (($contact->phone == $phone || $contact->mobile = $phone) && $contact->email == $email) - return (int)$contact->Code; - } - foreach ($contact_obj as $contact) { - if ($phone && $contact->phone == $phone || $contact->mobile = $phone) - return (int)$contact->Code; - } - foreach ($contact_obj as $contact) { - if ($email && $contact->email == $email) - return (int)$contact->Code; - } - return null; - } - } else { - HesabixLogService::log(array("Cannot get Contact list. Error Message: (string)$response->ErrorMessage. Error Code: (string)$response->ErrorCode.")); - } - - return null; - } -//==================================================================================================================== - //Invoice - public function setOrder($id_order, $orderType = 0, $reference = null) - { - if (!isset($id_order)) { - return false; - } - - $wpFaService = new HesabixWpFaService(); - - $number = $this->getInvoiceNumberByOrderId($id_order); - if (!$number) { - $number = null; - if ($orderType == 2) //return if saleInvoice not set before - { - return false; - } - } - -// $order = new WC_Order($id_order); - $order = wc_get_order($id_order); - - $dokanOption = get_option("ssbhesabix_invoice_dokan", 0); - - if ($dokanOption && is_plugin_active("dokan-lite/dokan.php")) { - $orderCreated = $order->get_created_via(); - if ($dokanOption == 1 && $orderCreated !== 'checkout') - return false; - else if ($dokanOption == 2 && $orderCreated === 'checkout') - return false; - } - - $id_customer = $order->get_customer_id(); - if ($id_customer !== 0) { - - $contactCode = $this->setContact($id_customer, 'first', $id_order); - - if ($contactCode == null) { - if (!$contactCode) { - return false; - } - } - HesabixLogService::writeLogStr("order ID " . $id_order); - if (get_option('ssbhesabix_contact_address_status') == 2) { - $this->setContact($id_customer, 'billing', $id_order); - } elseif (get_option('ssbhesabix_contact_address_status') == 3) { - $this->setContact($id_customer, 'shipping', $id_order); - } - } else { - $contactCode = $this->setGuestCustomer($id_order); - if (!$contactCode) { - return false; - } - } - - global $notDefinedProductID; - $notDefinedItems = array(); - $products = $order->get_items(); - foreach ($products as $product) { - if ($product['product_id'] == 0) continue; - $itemCode = $wpFaService->getProductCodeByWpId($product['product_id'], $product['variation_id']); - if ($itemCode == null) { - $notDefinedItems[] = $product['product_id']; - } - } - - if (!empty($notDefinedItems)) { - if (!$this->setItems($notDefinedItems)) { - HesabixLogService::writeLogStr("Cannot add/update Invoice. Failed to set products. Order ID: $id_order"); - return false; - } - } - - $invoiceItems = array(); - $i = 0; - $failed = false; - foreach ($products as $key => $product) { - $itemCode = $wpFaService->getProductCodeByWpId($product['product_id'], $product['variation_id']); - - if ($itemCode == null) { - $pId = $product['product_id']; - $vId = $product['variation_id']; - HesabixLogService::writeLogStr("Item not found. productId: $pId, variationId: $vId, Order ID: $id_order"); - - $failed = true; - break; - } - -// $wcProduct = new WC_Product($product['product_id']); - - if($product['variation_id']) { - $wcProduct = wc_get_product($product['variation_id']); - } else { - $wcProduct = wc_get_product($product['product_id']); - } - - global $discount, $price; - if( $wcProduct->is_on_sale() && get_option('ssbhesabix_set_special_sale_as_discount') === 'yes' ) { - $price = $this->getPriceInHesabixDefaultCurrency($wcProduct->get_regular_price()); - $discount = $this->getPriceInHesabixDefaultCurrency($wcProduct->get_regular_price() - $wcProduct->get_sale_price()); - $discount *= $product['quantity']; - } else { - $price = $this->getPriceInHesabixDefaultCurrency($product['subtotal'] / $product['quantity']); - $discount = $this->getPriceInHesabixDefaultCurrency($product['subtotal'] - $product['total']); - } - - $item = array( - 'RowNumber' => $i, - 'ItemCode' => $itemCode, - 'Description' => Ssbhesabix_Validation::invoiceItemDescriptionValidation($product['name']), - 'Quantity' => (int)$product['quantity'], - 'UnitPrice' => (float)$price, - 'Discount' => (float)$discount, - 'Tax' => (float)$this->getPriceInHesabixDefaultCurrency($product['total_tax']), - ); - - $invoiceItems[] = $item; - $i++; - } - - if ($failed) { - HesabixLogService::writeLogStr("Cannot add/update Invoice. Item code is NULL. Check your invoice products and relations with Hesabix. Order ID: $id_order"); - return false; - } - - if (empty($invoiceItems)) { - HesabixLogService::log(array("Cannot add/update Invoice. At least one item required.")); - return false; - } - - $date_obj = $order->get_date_created(); - switch ($orderType) { - case 0: - $date = $date_obj->date('Y-m-d H:i:s'); - break; - case 2: - $date = date('Y-m-d H:i:s'); - break; - default: - $date = $date_obj->date('Y-m-d H:i:s'); - } - - if ($reference === null) - $reference = $id_order; - - $order_shipping_method = ""; - foreach ($order->get_items('shipping') as $item) - $order_shipping_method = $item->get_name(); - - $note = $order->customer_note; - if ($order_shipping_method) - $note .= "\n" . __('Shipping method', 'ssbhesabix') . ": " . $order_shipping_method; - - global $freightOption, $freightItemCode; - $freightOption = get_option("ssbhesabix_invoice_freight"); - - if($freightOption == 1) { - $freightItemCode = get_option('ssbhesabix_invoice_freight_code'); - if(!isset($freightItemCode) || !$freightItemCode) HesabixLogService::writeLogStr("کد هزینه حمل و نقل تعریف نشده است" . "\n" . "Freight service code is not set"); - - $freightItemCode = $this->convertPersianDigitsToEnglish($freightItemCode); - - if($this->getPriceInHesabixDefaultCurrency($order->get_shipping_total()) != 0) { - $invoiceItem = array( - 'RowNumber' => $i, - 'ItemCode' => $freightItemCode, - 'Description' => 'هزینه حمل و نقل', - 'Quantity' => 1, - 'UnitPrice' => (float) $this->getPriceInHesabixDefaultCurrency($order->get_shipping_total()), - 'Discount' => 0, - 'Tax' => (float) $this->getPriceInHesabixDefaultCurrency($order->get_shipping_tax()) - ); - $invoiceItems[] = $invoiceItem; - } - } - - $data = array( - 'Number' => $number, - 'InvoiceType' => $orderType, - 'ContactCode' => $contactCode, - 'Date' => $date, - 'DueDate' => $date, - 'Reference' => $reference, - 'Status' => 2, - 'Tag' => json_encode(array('id_order' => $id_order)), - 'InvoiceItems' => $invoiceItems, - 'Note' => $note, - 'Freight' => '' - ); - - if($freightOption == 0) { - $freight = $this->getPriceInHesabixDefaultCurrency($order->get_shipping_total() + $order->get_shipping_tax()); - $data['Freight'] = $freight; - } - - $invoice_draft_save = get_option('ssbhesabix_invoice_draft_save_in_hesabix', 'no'); - if ($invoice_draft_save != 'no') - $data['Status'] = 0; - - $invoice_project = get_option('ssbhesabix_invoice_project', -1); - $invoice_salesman = get_option('ssbhesabix_invoice_salesman', -1); - $invoice_salesman_percentage = get_option('ssbhesabix_invoice_salesman_percentage', 0); - if ($invoice_project != -1) $data['Project'] = $invoice_project; - if ($invoice_salesman != -1) $data['SalesmanCode'] = $invoice_salesman; - if($invoice_salesman_percentage) if($invoice_salesman_percentage != 0) $data['SalesmanPercent'] = $this->convertPersianDigitsToEnglish($invoice_salesman_percentage); - - $GUID = $this->getGUID($id_order); - $hesabix = new Ssbhesabix_Api(); - $response = $hesabix->invoiceSave($data, $GUID); -// $response = $hesabix->invoiceSave($data, ''); - - if ($response->Success) { - global $wpdb; - - switch ($orderType) { - case 0: - $obj_type = 'order'; - break; - case 2: - $obj_type = 'returnOrder'; - break; - } - - if ($number === null) { - $wpdb->insert($wpdb->prefix . 'ssbhesabix', array( - 'id_hesabix' => (int)$response->Result->Number, - 'obj_type' => $obj_type, - 'id_ps' => $id_order, - )); - HesabixLogService::log(array("Invoice successfully added. Invoice number: " . (string)$response->Result->Number . ". Order ID: $id_order")); - } else { - $wpFaId = $wpFaService->getWpFaId($obj_type, $id_order); - - $wpdb->update($wpdb->prefix . 'ssbhesabix', array( - 'id_hesabix' => (int)$response->Result->Number, - 'obj_type' => $obj_type, - 'id_ps' => $id_order, - ), array('id' => $wpFaId)); - HesabixLogService::log(array("Invoice successfully updated. Invoice number: " . (string)$response->Result->Number . ". Order ID: $id_order")); - } - - $warehouse = get_option('ssbhesabix_item_update_quantity_based_on', "-1"); - if ($warehouse != "-1" && $orderType === 0) - $this->setWarehouseReceipt($invoiceItems, (int)$response->Result->Number, $warehouse, $date, $invoice_project); - - return true; - } else { - foreach ($invoiceItems as $item) { - HesabixLogService::log(array("Cannot add/update Invoice. Error Code: " . (string)$response->ErrorCode . ". Error Message: " . (string)$response->ErrorMessage . ". Order ID: $id_order" . "\n" - . "Hesabix Id:" . $item['ItemCode'] - )); - } - return false; - } - } -//======================================================================================================================== - public function setWarehouseReceipt($items, $invoiceNumber, $warehouseCode, $date, $project) - { - $invoiceOption = get_option('ssbhesabix_invoice_freight'); - if($invoiceOption == 1) { - $invoiceFreightCode = get_option('ssbhesabix_invoice_freight_code'); - for ($i = 0 ; $i < count($items) ; $i++) { - if($items[$i]["ItemCode"] == $invoiceFreightCode) { - unset($items[$i]); - } - } - } - - $data = array( - 'WarehouseCode' => $warehouseCode, - 'InvoiceNumber' => $invoiceNumber, - 'InvoiceType' => 0, - 'Date' => $date, - 'Items' => $items - ); - - if ($project != -1) - $data['Project'] = $project; - - $hesabix = new Ssbhesabix_Api(); - $response = $hesabix->saveWarehouseReceipt($data); - - if ($response->Success) - HesabixLogService::log(array("Warehouse receipt successfully saved/updated. warehouse receipt number: " . (string)$response->Result->Number . ". Invoice number: $invoiceNumber")); - else - HesabixLogService::log(array("Cannot save/update Warehouse receipt. Error Code: " . (string)$response->ErrorCode . ". Error Message: " . (string)$response->ErrorMessage . ". Invoice number: $invoiceNumber")); - } -//======================================================================================================================== - public static function getPriceInHesabixDefaultCurrency($price) - { - if (!isset($price)) return false; - - $woocommerce_currency = get_woocommerce_currency(); - $hesabix_currency = get_option('ssbhesabix_hesabix_default_currency'); - - if (!is_numeric($price)) - $price = intval($price); - - if ($hesabix_currency == 'IRR' && $woocommerce_currency == 'IRT') - $price *= 10; - - if ($hesabix_currency == 'IRT' && $woocommerce_currency == 'IRR') - $price /= 10; - - return $price; - } -//======================================================================================================================== - public static function getPriceInWooCommerceDefaultCurrency($price) - { - if (!isset($price)) return false; - - $woocommerce_currency = get_woocommerce_currency(); - $hesabix_currency = get_option('ssbhesabix_hesabix_default_currency'); - - if (!is_numeric($price)) - $price = intval($price); - - if ($hesabix_currency == 'IRR' && $woocommerce_currency == 'IRT') - $price /= 10; - - if ($hesabix_currency == 'IRT' && $woocommerce_currency == 'IRR') - $price *= 10; - - return $price; - } -//======================================================================================================================== - public function setOrderPayment($id_order) - { - if (!isset($id_order)) { - return false; - } - - $hesabix = new Ssbhesabix_Api(); - $number = $this->getInvoiceCodeByOrderId($id_order); - if (!$number) { - return false; - } - - //$order = new WC_Order($id_order); - $order = wc_get_order($id_order); - - if ($order->get_total() <= 0) { - return true; - } - $bank_code = $this->getBankCodeByPaymentMethod($order->get_payment_method()); - - if ($bank_code == -1) { - return true; - } elseif ($bank_code != false) { - $transaction_id = $order->get_transaction_id(); - //transaction id cannot be null or empty - if ($transaction_id == '') { - $transaction_id = '-'; - } - - $payTempValue = substr($bank_code, 0, 4); - global $financialData; - if(get_option('ssbhesabix_payment_option') == 'no') { - switch($payTempValue) { - case 'bank': - $payTempValue = substr($bank_code, 4); - $financialData = array('bankCode' => $payTempValue);break; - case 'cash': - $payTempValue = substr($bank_code, 4); - $financialData = array('cashCode' => $payTempValue);break; - } - } elseif (get_option('ssbhesabix_payment_option') == 'yes') { - $defaultBankCode = $this->convertPersianDigitsToEnglish(get_option('ssbhesabix_default_payment_method_code')); - $financialData = array('bankCode' => $defaultBankCode); - } - - $date_obj = $order->get_date_paid(); - if ($date_obj == null) { - $date_obj = $order->get_date_modified(); - } - - global $accountPath; - - if(get_option("ssbhesabix_cash_in_transit") == "1" || get_option("ssbhesabix_cash_in_transit") == "yes") { - $func = new Ssbhesabix_Admin_Functions(); - $cashInTransitFullPath = $func->getCashInTransitFullPath(); - if(!$cashInTransitFullPath) { - HesabixLogService::writeLogStr("Cash in Transit is not Defined in Hesabix ---- وجوه در راه در حسابیکس یافت نشد"); - return false; - } else { - $accountPath = array("accountPath" => $cashInTransitFullPath); - } - } - - $response = $hesabix->invoiceGet($number); - if ($response->Success) { - if ($response->Result->Paid > 0) { - // payment submited before - } else { - $response = $hesabix->invoiceSavePayment($number, $financialData, $accountPath, $date_obj->date('Y-m-d H:i:s'), $this->getPriceInHesabixDefaultCurrency($order->get_total()), $transaction_id); - - if ($response->Success) { - HesabixLogService::log(array("Hesabix invoice payment added. Order ID: $id_order")); - return true; - } else { - HesabixLogService::log(array("Cannot add Hesabix Invoice payment. Order ID: $id_order. Error Code: " . (string)$response->ErrorCode . ". Error Message: " . (string)$response->ErrorMessage . ".")); - return false; - } - } - return true; - } else { - HesabixLogService::log(array("Error while trying to get invoice. Invoice Number: $number. Error Code: " . (string)$response->ErrorCode . ". Error Message: " . (string)$response->ErrorMessage . ".")); - return false; - } - } else { - HesabixLogService::log(array("Cannot add Hesabix Invoice payment - Bank Code not defined. Order ID: $id_order")); - return false; - } - } -//======================================================================================================================== - public function getCashInTransitFullPath() { - $api = new Ssbhesabix_Api(); - $accounts = $api->settingGetAccounts(); - foreach ($accounts->Result as $account) { - if($account->Name == "وجوه در راه") { - return $account->FullPath; - } - } - return false; - } -//======================================================================================================================== - public function getInvoiceNumberByOrderId($id_order) - { - if (!isset($id_order)) return false; - - global $wpdb; - $row = $wpdb->get_row("SELECT `id_hesabix` FROM " . $wpdb->prefix . "ssbhesabix WHERE `id_ps` = $id_order AND `obj_type` = 'order'"); - - if (is_object($row)) { - return $row->id_hesabix; - } else { - return false; - } - } -//======================================================================================================================== - public function getBankCodeByPaymentMethod($payment_method) - { - $code = get_option('ssbhesabix_payment_method_' . $payment_method); - - if (isset($code)) - return $code; - else - return false; - } -//======================================================================================================================== - public function getInvoiceCodeByOrderId($id_order) - { - if (!isset($id_order)) return false; - - global $wpdb; - $row = $wpdb->get_row("SELECT `id_hesabix` FROM " . $wpdb->prefix . "ssbhesabix WHERE `id_ps` = $id_order AND `obj_type` = 'order'"); - - if (is_object($row)) { - return $row->id_hesabix; - } else { - return false; - } - } -//======================================================================================================================== - public function exportProducts() - { - HesabixLogService::writeLogStr("Exporting Products"); - try { - $result = array(); - $result["error"] = false; - global $wpdb; - - $total = $wpdb->get_var("SELECT COUNT(*) FROM `" . $wpdb->prefix . "posts` WHERE post_type = 'product' AND post_status IN('publish','private')"); - $products = $wpdb->get_results("SELECT * FROM `" . $wpdb->prefix . "posts` WHERE post_type = 'product' AND post_status IN('publish','private')"); - - $hesabix = new Ssbhesabix_Api(); - $response = $hesabix->settingExportProdects(array('data'=>$products)); - $result["updateCount"] = $total; - return $result; - } catch(Error $error) { - HesabixLogService::writeLogStr("Error in export products: " . $error->getMessage()); - } - } -//======================================================================================================================== - public function importProducts($batch, $totalBatch, $total, $updateCount) - { - HesabixLogService::writeLogStr("Import Products"); - try { - $wpFaService = new HesabixWpFaService(); - $rpp=500; - $result = array(); - $result["error"] = false; - global $wpdb; - $hesabix = new Ssbhesabix_Api(); - $filters = array(array("Property" => "ItemType", "Operator" => "=", "Value" => 0)); - - if ($batch == 1) { - $total = 0; - $response = $hesabix->itemGetItems(array('Take' => 1, 'Filters' => $filters)); - if ($response->Success) { - $total = $response->Result->FilteredCount; - $totalBatch = ceil($total / $rpp); - } else { - HesabixLogService::log(array("Error while trying to get products for import. Error Message: $response->ErrorMessage. Error Code: $response->ErrorCode.")); - $result["error"] = true; - return $result; - }; - } - - $id_product_array = array(); - $offset = ($batch - 1) * $rpp; - - $response = $hesabix->itemGetItems(array('Skip' => $offset, 'Take' => $rpp, 'SortBy' => 'Id', 'Filters' => $filters)); - if ($response->Success) { - $items = $response->Result->List; - $from = $response->Result->From; - $to = $response->Result->To; - - foreach ($items as $item) { - $wpFa = $wpFaService->getWpFaByHesabixId('product', $item->Code); - if ($wpFa) continue; - - $clearedName = preg_replace("/\s+|\/|\\\|\(|\)/", '-', trim($item->Name)); - $clearedName = preg_replace("/\-+/", '-', $clearedName); - $clearedName = trim($clearedName, '-'); - $clearedName = preg_replace(["/۰/", "/۱/", "/۲/", "/۳/", "/۴/", "/۵/", "/۶/", "/۷/", "/۸/", "/۹/"], - ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"], $clearedName); - - // add product to database - $wpdb->insert($wpdb->prefix . 'posts', array( - 'post_author' => get_current_user_id(), - 'post_date' => date("Y-m-d H:i:s"), - 'post_date_gmt' => date("Y-m-d H:i:s"), - 'post_content' => '', - 'post_title' => $item->Name, - 'post_excerpt' => '', - 'post_status' => 'private', - 'comment_status' => 'open', - 'ping_status' => 'closed', - 'post_password' => '', - 'post_name' => $clearedName, - 'to_ping' => '', - 'pinged' => '', - 'post_modified' => date("Y-m-d H:i:s"), - 'post_modified_gmt' => date("Y-m-d H:i:s"), - 'post_content_filtered' => '', - 'post_parent' => 0, - 'guid' => get_site_url() . '/product/' . $clearedName . '/', - 'menu_order' => 0, - 'post_type' => 'product', - 'post_mime_type' => '', - 'comment_count' => 0, - )); - - $postId = $wpdb->insert_id; - $id_product_array[] = $postId; - $price = self::getPriceInWooCommerceDefaultCurrency($item->SellPrice); - - // add product link to hesabix - $wpdb->insert($wpdb->prefix . 'ssbhesabix', array( - 'obj_type' => 'product', - 'id_hesabix' => (int)$item->Code, - 'id_ps' => $postId, - 'id_ps_attribute' => 0, - )); - - update_post_meta($postId, '_manage_stock', 'yes'); - update_post_meta($postId, '_sku', $item->Barcode); - update_post_meta($postId, '_regular_price', $price); - update_post_meta($postId, '_price', $price); - update_post_meta($postId, '_stock', $item->Stock); - - $new_stock_status = ($item->Stock > 0) ? "instock" : "outofstock"; - wc_update_product_stock_status($postId, $new_stock_status); - $updateCount++; - } - - } else { - HesabixLogService::log(array("Error while trying to get products for import. Error Message: (string)$response->ErrorMessage. Error Code: (string)$response->ErrorCode.")); - $result["error"] = true; - return $result; - } - sleep(2); - - $result["batch"] = $batch; - $result["totalBatch"] = $totalBatch; - $result["total"] = $total; - $result["updateCount"] = $updateCount; - return $result; - } catch(Error $error) { - HesabixLogService::writeLogStr("Error in importing products" . $error->getMessage()); - } - } - -//======================================================================================================================== - public function exportCustomers($batch, $totalBatch, $total, $updateCount) - { - HesabixLogService::writeLogStr("Export Customers"); - $result = array(); - $result["error"] = false; - global $wpdb; - $total = $wpdb->get_var("SELECT COUNT(*) FROM `" . $wpdb->prefix . "users`"); - $customers = $wpdb->get_results("SELECT id,user_nicename,user_email FROM " . $wpdb->prefix . "users"); - $data = array(); - foreach($customers as $customer){ - $temp = array(); - $tempresult = $wpdb->get_results("SELECT meta_key,meta_value FROM `" . $wpdb->prefix . "usermeta` WHERE user_id='". $customer->id . "'"); - foreach($tempresult as $tmr){ - if($tmr->meta_key == 'nickname'){ - $temp['nickname'] = $tmr->meta_value; - } - if($tmr->meta_key == 'first_name'){ - $temp['name'] = $tmr->meta_value; - } - if($tmr->meta_key == 'last_name'){ - $temp['name'] .= $tmr->meta_value; - } - } - $temp['email'] .= $customer->user_email; - array_push($data,$temp); - } - $hesabix = new Ssbhesabix_Api(); - $response = $hesabix->personsImport(['data'=>$data]); - if ($response->Success) { - HesabixLogService::log(array("Contact successfully added.")); - } else { - HesabixLogService::log(array("Cannot add bulk contacts. Error Message: $response->ErrorMessage. Error Code: $response->ErrorCode.")); - } - $result["total"] = $total; - - return $result; - } -//======================================================================================================================== - public function syncOrders($from_date, $batch, $totalBatch, $total, $updateCount) - { - - HesabixLogService::writeLogStr("Sync Orders"); - $wpFaService = new HesabixWpFaService(); - - $result = array(); - $result["error"] = false; - $rpp = 10; - global $wpdb; - - if (!isset($from_date) || empty($from_date)) { - $result['error'] = 'inputDateError'; - return $result; - } - - if (!$this->isDateInFiscalYear($from_date)) { - $result['error'] = 'fiscalYearError'; - return $result; - } - - if ($batch == 1) { - $total = $wpdb->get_var("SELECT COUNT(*) FROM `" . $wpdb->prefix . "posts` - WHERE post_type = 'shop_order' AND post_date >= '" . $from_date . "'"); - $totalBatch = ceil($total / $rpp); - } - - $offset = ($batch - 1) * $rpp; - $orders = $wpdb->get_results("SELECT ID FROM `" . $wpdb->prefix . "posts` - WHERE post_type = 'shop_order' AND post_date >= '" . $from_date . "' - ORDER BY ID ASC LIMIT $offset,$rpp"); - HesabixLogService::writeLogStr("Orders count: " . count($orders)); - - $statusesToSubmitInvoice = get_option('ssbhesabix_invoice_status'); - $statusesToSubmitInvoice = implode(',', $statusesToSubmitInvoice); - $statusesToSubmitReturnInvoice = get_option('ssbhesabix_invoice_return_status'); - $statusesToSubmitReturnInvoice = implode(',', $statusesToSubmitReturnInvoice); - $statusesToSubmitPayment = get_option('ssbhesabix_payment_status'); - $statusesToSubmitPayment = implode(',', $statusesToSubmitPayment); - - $id_orders = array(); - foreach ($orders as $order) { - //$order = new WC_Order($order->ID); - $order = wc_get_order($order->ID); - - $id_order = $order->get_id(); - $id_obj = $wpFaService->getWpFaId('order', $id_order); - $current_status = $order->get_status(); - - if (!$id_obj) { - if (strpos($statusesToSubmitInvoice, $current_status) !== false) { - if ($this->setOrder($id_order)) { - array_push($id_orders, $id_order); - $updateCount++; - - if (strpos($statusesToSubmitPayment, $current_status) !== false) - $this->setOrderPayment($id_order); - - // set return invoice - if (strpos($statusesToSubmitReturnInvoice, $current_status) !== false) { - $this->setOrder($id_order, 2, $this->getInvoiceCodeByOrderId($id_order)); - } - } - } - } - - } - - $result["batch"] = $batch; - $result["totalBatch"] = $totalBatch; - $result["total"] = $total; - $result["updateCount"] = $updateCount; - return $result; - } -//======================================================================================================================== - public function syncProducts($batch, $totalBatch, $total) - { - try { - HesabixLogService::writeLogStr("Sync products price and quantity from hesabix to store: part $batch"); - $result = array(); - $result["error"] = false; - $extraSettingRPP = get_option("ssbhesabix_set_rpp_for_sync_products_into_woocommerce"); - - $rpp=200; - if($extraSettingRPP) { - if($extraSettingRPP != '-1' && $extraSettingRPP != '0') { - $rpp=$extraSettingRPP; - } - } - - $hesabix = new Ssbhesabix_Api(); - $filters = array(array("Property" => "ItemType", "Operator" => "=", "Value" => 0)); - - if ($batch == 1) { - $response = $hesabix->itemGetItems(array('Take' => 1, 'Filters' => $filters)); - if ($response->Success) { - $total = $response->Result->FilteredCount; - $totalBatch = ceil($total / $rpp); - } else { - HesabixLogService::log(array("Error while trying to get products for sync. Error Message: $response->ErrorMessage. Error Code: $response->ErrorCode.")); - $result["error"] = true; - return $result; - } - } - - $offset = ($batch - 1) * $rpp; - $response = $hesabix->itemGetItems(array('Skip' => $offset, 'Take' => $rpp, 'SortBy' => 'Id', 'Filters' => $filters)); - - $warehouse = get_option('ssbhesabix_item_update_quantity_based_on', "-1"); - - if ($warehouse != "-1") { - $products = $response->Result->List; - $codes = []; - foreach ($products as $product) - $codes[] = $product->Code; - $response = $hesabix->itemGetQuantity($warehouse, $codes); - } - - if ($response->Success) { - $products = $warehouse == "-1" ? $response->Result->List : $response->Result; - foreach ($products as $product) { - self::setItemChanges($product); - } - } else { - HesabixLogService::log(array("Error while trying to get products for sync. Error Message: $response->ErrorMessage. Error Code: $response->ErrorCode.")); - $result["error"] = true; - return $result; - } - - $result["batch"] = $batch; - $result["totalBatch"] = $totalBatch; - $result["total"] = $total; - return $result; - } catch (Error $error) { - HesabixLogService::writeLogStr("Error in sync products: " . $error->getMessage()); - } - } -//======================================================================================================================== - public function syncProductsManually($data) - { - HesabixLogService::writeLogStr('Sync Products Manually'); - - $hesabix_item_codes = array(); - foreach ($data as $d) { - if ($d["hesabix_id"]) { - $hesabix_item_codes[] = str_pad($d["hesabix_id"], 6, "0", STR_PAD_LEFT); - } - } - - $hesabix = new Ssbhesabix_Api(); - - $filters = array(array("Property" => "Code", "Operator" => "in", "Value" => $hesabix_item_codes)); - $response = $hesabix->itemGetItems(array('Take' => 100, 'Filters' => $filters)); - - if ($response->Success) { - $products = $response->Result->List; - $products_codes = array(); - foreach ($products as $product) - $products_codes[] = $product->Code; - $diff = array_diff($hesabix_item_codes, $products_codes); - if (is_array($diff) && count($diff) > 0) { - return array("result" => false, "data" => $diff); - } - } - - $id_product_array = array(); - global $wpdb; - - foreach ($data as $d) { - $row = $wpdb->get_row("SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id_ps_attribute` = " . $d["id"] . " AND `obj_type` = 'product'"); - - if (!is_object($row)) { - $row = $wpdb->get_row("SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id_ps` = " . $d["id"] . " AND `obj_type` = 'product'"); - } - if (is_object($row)) { - if (!$d["hesabix_id"]) - $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id' => $row->id)); - else - $wpdb->update($wpdb->prefix . 'ssbhesabix', array('id_hesabix' => $d["hesabix_id"]), array('id' => $row->id)); - } else { - if (!$d["hesabix_id"]) - continue; - if ($d["parent_id"]) - $wpdb->insert($wpdb->prefix . 'ssbhesabix', array('obj_type' => 'product', 'id_hesabix' => $d["hesabix_id"], 'id_ps' => $d["parent_id"], 'id_ps_attribute' => $d["id"])); - else - $wpdb->insert($wpdb->prefix . 'ssbhesabix', array('obj_type' => 'product', 'id_hesabix' => $d["hesabix_id"], 'id_ps' => $d["id"], 'id_ps_attribute' => '0')); - } - - if ($d["hesabix_id"]) { - if ($d["parent_id"]) { - if (!in_array($d["parent_id"], $id_product_array)) - $id_product_array[] = $d["parent_id"]; - } else { - if (!in_array($d["id"], $id_product_array)) - $id_product_array[] = $d["id"]; - } - } - } - - $this->setItems($id_product_array); - return array("result" => true, "data" => null); - } -//======================================================================================================================== - public function updateProductsInHesabixBasedOnStore($batch, $totalBatch, $total) - { - HesabixLogService::writeLogStr("Update Products In Hesabix Based On Store"); - $result = array(); - $result["error"] = false; - $extraSettingRPP = get_option('ssbhesabix_set_rpp_for_sync_products_into_hesabix'); - - $rpp=500; - if($extraSettingRPP) { - if($extraSettingRPP != '-1' && $extraSettingRPP != '0') { - $rpp=$extraSettingRPP; - } - } - - global $wpdb; - - if ($batch == 1) { - $total = $wpdb->get_var("SELECT COUNT(*) FROM `" . $wpdb->prefix . "posts` - WHERE post_type = 'product' AND post_status IN('publish','private')"); - $totalBatch = ceil($total / $rpp); - } - - $offset = ($batch - 1) * $rpp; - $products = $wpdb->get_results("SELECT ID FROM `" . $wpdb->prefix . "posts` - WHERE post_type = 'product' AND post_status IN('publish','private') ORDER BY 'ID' ASC LIMIT $offset,$rpp"); - - $products_id_array = array(); - foreach ($products as $product) - $products_id_array[] = $product->ID; - $this->setItems($products_id_array); - sleep(2); - - $result["batch"] = $batch; - $result["totalBatch"] = $totalBatch; - $result["total"] = $total; - return $result; - } -//======================================================================================================================== - public static function updateProductsInHesabixBasedOnStoreWithFilter($offset=0, $rpp=0) - { - HesabixLogService::writeLogStr("Update Products With Filter In Hesabix Based On Store"); - $result = array(); - $result["error"] = false; - - global $wpdb; - if($offset != 0 && $rpp != 0) { - if(abs($rpp - $offset) <= 200) { - if($rpp > $offset) { - $products = $wpdb->get_results("SELECT * FROM `" . $wpdb->prefix . "posts` - WHERE ID BETWEEN $offset AND $rpp AND post_type = 'product' AND post_status IN('publish','private') ORDER BY 'ID' ASC"); - - $products_id_array = array(); - foreach ($products as $product) - $products_id_array[] = $product->ID; - $response = (new Ssbhesabix_Admin_Functions)->setItems($products_id_array); - if(!$response) $result['error'] = true; - } else { - $products = $wpdb->get_results("SELECT * FROM `" . $wpdb->prefix . "posts` - WHERE ID BETWEEN $rpp AND $offset AND post_type = 'product' AND post_status IN('publish','private') ORDER BY 'ID' ASC"); - - $products_id_array = array(); - foreach ($products as $product) - $products_id_array[] = $product->ID; - $response = (new Ssbhesabix_Admin_Functions)->setItems($products_id_array); - if(!$response) $result['error'] = true; - } - } else { - $result['error'] = true; - echo ''; - } - } else { - echo ''; - } - - return $result; - } -//======================================================================================================================== - public function cleanLogFile() - { - HesabixLogService::clearLog(); - return true; - } -//======================================================================================================================== - public static function setItemChanges($item) - { - if (!is_object($item)) return false; - - if ($item->Quantity || !$item->Stock) - $item->Stock = $item->Quantity; - - $wpFaService = new HesabixWpFaService(); - global $wpdb; - - $wpFa = $wpFaService->getWpFaByHesabixId('product', $item->Code); - if (!$wpFa) return false; - - $id_product = $wpFa->idWp; - $id_attribute = $wpFa->idWpAttribute; - - if ($id_product == 0) { - HesabixLogService::log(array("Item with code: $item->Code is not defined in Online store")); - return false; - } - - $found = $wpdb->get_var("SELECT COUNT(*) FROM `" . $wpdb->prefix . "posts` WHERE ID = $id_product"); - - if (!$found) { - HesabixLogService::writeLogStr("product not found in woocommerce.code: $item->Code, product id: $id_product, variation id: $id_attribute"); - return false; - } - - $product = wc_get_product($id_product); - $variation = $id_attribute != 0 ? wc_get_product($id_attribute) : null; - - -// $product = new WC_Product($id_product); -// $variation = $id_attribute != 0 ? new WC_Product($id_attribute) : null; - - $result = array(); - $result["newPrice"] = null; - $result["newQuantity"] = null; - - $p = $variation ? $variation : $product; - - if (get_option('ssbhesabix_item_update_price') == 'yes') - $result = self::setItemNewPrice($p, $item, $id_attribute, $id_product, $result); - - if (get_option('ssbhesabix_item_update_quantity') == 'yes') - $result = self::setItemNewQuantity($p, $item, $id_product, $id_attribute, $result); - - return $result; - } -//======================================================================================================================== - private static function setItemNewPrice($product, $item, $id_attribute, $id_product, array $result) - { - try { - $option_sale_price = get_option('ssbhesabix_item_update_sale_price', 0); - $woocommerce_currency = get_woocommerce_currency(); - $hesabix_currency = get_option('ssbhesabix_hesabix_default_currency'); - - $old_price = $product->get_regular_price() ? $product->get_regular_price() : $product->get_price(); - $old_price = Ssbhesabix_Admin_Functions::getPriceInHesabixDefaultCurrency($old_price); - - $post_id = $id_attribute && $id_attribute > 0 ? $id_attribute : $id_product; - - if ($item->SellPrice != $old_price) { - $new_price = Ssbhesabix_Admin_Functions::getPriceInWooCommerceDefaultCurrency($item->SellPrice); - update_post_meta($post_id, '_regular_price', $new_price); - update_post_meta($post_id, '_price', $new_price); - - - $sale_price = $product->get_sale_price(); - if ($sale_price && is_numeric($sale_price)) { - $sale_price = Ssbhesabix_Admin_Functions::getPriceInHesabixDefaultCurrency($sale_price); - if (+$option_sale_price === 1) { - update_post_meta($post_id, '_sale_price', null); - } elseif (+$option_sale_price === 2) { - update_post_meta($post_id, '_sale_price', round(($sale_price * $new_price) / $old_price)); - update_post_meta($post_id, '_price', round(($sale_price * $new_price) / $old_price)); - } else { - if($woocommerce_currency == 'IRT' && $hesabix_currency == 'IRR') update_post_meta($post_id, '_price', ($sale_price/10)); - elseif($woocommerce_currency == 'IRR' && $hesabix_currency == 'IRT') update_post_meta($post_id, '_price', ($sale_price*10)); - elseif($woocommerce_currency == 'IRR' && $hesabix_currency == 'IRR') update_post_meta($post_id, '_price', $sale_price); - elseif($woocommerce_currency == 'IRT' && $hesabix_currency == 'IRT') update_post_meta($post_id, '_price', $sale_price); - } - } - - HesabixLogService::log(array("product ID $id_product-$id_attribute Price changed. Old Price: $old_price. New Price: $new_price")); - $result["newPrice"] = $new_price; - } - - return $result; - } catch (Error $error) { - HesabixLogService::writeLogStr("Error in Set Item New Price -> $error"); - } - } -//======================================================================================================================== - private static function setItemNewQuantity($product, $item, $id_product, $id_attribute, array $result) - { - try { - $old_quantity = $product->get_stock_quantity(); - if ($item->Stock != $old_quantity) { - $new_quantity = $item->Stock; - if (!$new_quantity) $new_quantity = 0; - - $new_stock_status = ($new_quantity > 0) ? "instock" : "outofstock"; - - $post_id = ($id_attribute && $id_attribute > 0) ? $id_attribute : $id_product; - - update_post_meta($post_id, '_stock', $new_quantity); - wc_update_product_stock_status($post_id, $new_stock_status); - - HesabixLogService::log(array("product ID $id_product-$id_attribute quantity changed. Old quantity: $old_quantity. New quantity: $new_quantity")); - $result["newQuantity"] = $new_quantity; - } - - return $result; - } catch (Error $error) { - HesabixLogService::writeLogStr("Error in Set Item New Price -> $error"); - } - } -//========================================================================================================================= - function CheckNationalCode($NationalCode): void - { - $identicalDigits = ['1111111111', '2222222222', '3333333333', '4444444444', '5555555555', '6666666666', '7777777777', '8888888888', '9999999999']; - - if(strlen($NationalCode) === 10) { - $summation = 0; - $j = 10; - for($i = 0 ; $i < 9 ; $i++) { - $digit = substr($NationalCode, $i, 1); - $temp = $digit * $j; - $j -= 1; - $summation += $temp; - } - $controlDigit = substr($NationalCode, 9, 1); - $retrieve = $summation % 11; - - if(in_array($NationalCode, $identicalDigits) === false) { - if($retrieve < 2) { - if($controlDigit != $retrieve) { - wc_add_notice(__('please enter a valid national code', 'ssbhesabix'), 'error'); - } - } else { - if($controlDigit != (11 - $retrieve)) { - wc_add_notice(__('please enter a valid national code', 'ssbhesabix'), 'error'); - } - } - } - } else { - wc_add_notice(__('please enter a valid national code', 'ssbhesabix'), 'error'); - } - } -//========================================================================================================================= - function CheckWebsite($Website): void - { - if (filter_var($Website, FILTER_VALIDATE_URL)) { - // - } else { - wc_add_notice(__('please enter a valid Website URL', 'ssbhesabix'), 'error'); - } - } -//========================================================================================================================= - public static function enableDebugMode(): void { - update_option('ssbhesabix_debug_mode', 1); - } - - public static function disableDebugMode(): void { - update_option('ssbhesabix_debug_mode', 0); - } -//========================================================================================================================= - public function convertPersianDigitsToEnglish($inputString) : int { - $newNumbers = range(0, 9); - $persianDecimal = array('۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'); - $arabicDecimal = array('٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'); - $arabic = array('٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'); - $persian = array('۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'); - - $string = str_replace($persianDecimal, $newNumbers, $inputString); - $string = str_replace($arabicDecimal, $newNumbers, $string); - $string = str_replace($persian, $newNumbers, $string); - - return str_replace($arabic, $newNumbers, $string); - } -//========================================================================================================================= - function generateGUID() : string { - $characters = '0123456789ABCDEF'; - $guid = ''; - - for ($i = 0; $i < 32; $i++) { - $guid .= $characters[mt_rand(0, 15)]; - if ($i == 7 || $i == 11 || $i == 15 || $i == 19) { - $guid .= '-'; - } - } - - return $guid; - } -//========================================================================================================================= - public function getGUID($id_order): string { - $option = get_option($id_order); - - if ($option === false || $option == 0) { - $GUID = $this->generateGUID(); - $expirationDateTime = new DateTime('now', new DateTimeZone('UTC')); - add_option($id_order, $expirationDateTime->format('Y-m-d H:i:s') . $GUID); - } else { - $expirationDateTime = new DateTime(substr($option, 0, 19), new DateTimeZone('UTC')); - $currentDateTime = new DateTime('now', new DateTimeZone('UTC')); - - $diff = $currentDateTime->diff($expirationDateTime); - - if ($diff->days < 1) { - // GUID is still valid, continue processing - } else { - // GUID expired, reset the option to allow saving a new invoice - $GUID = $this->generateGUID(); - $expirationDateTime = new DateTime('now', new DateTimeZone('UTC')); - update_option($id_order, $expirationDateTime->format('Y-m-d H:i:s') . $GUID); - } - } - - return substr(get_option($id_order), 20); - } -//========================================================================================================================= + + * @author HamidReza Gharahzadeh + * @author Sepehr Najafi + */ +class Ssbhesabix_Admin_Functions +{ + public static function isDateInFiscalYear($date) + { + $hesabixApi = new Ssbhesabix_Api(); + $fiscalYear = $hesabixApi->settingGetFiscalYear(); + if (is_object($fiscalYear)) { + + if ($fiscalYear->Success) { + $fiscalYearStartTimeStamp = strtotime($fiscalYear->Result->StartDate); + $fiscalYearEndTimeStamp = strtotime($fiscalYear->Result->EndDate); + $dateTimeStamp = strtotime($date); + + if ($dateTimeStamp >= $fiscalYearStartTimeStamp && $dateTimeStamp <= $fiscalYearEndTimeStamp) { + return 1; + } else { + return 0; + } + } else { + HesabixLogService::log(array("Cannot get FiscalDate. Error Code: $fiscalYear->ErrroCode. Error Message: $fiscalYear->ErrorMessage")); + return false; + } + } + HesabixLogService::log(array("Cannot connect to Hesabix for get FiscalDate.")); + return false; + } +//==================================================================================================================== + public function getProductVariations($id_product) + { + if (!isset($id_product)) { + return false; + } + $product = wc_get_product($id_product); + + if (is_bool($product)) return false; + if ($product->is_type('variable')) { + $children = $product->get_children($args = '', $output = OBJECT); + $variations = array(); + foreach ($children as $value) { + $product_variatons = new WC_Product_Variation($value); + if ($product_variatons->exists()) { + $variations[] = $product_variatons; + } + } + return $variations; + } + return false; + } +//======================================================================================================== + public function setItems($id_product_array) + { + if (!isset($id_product_array) || $id_product_array[0] == null) return false; + if (is_array($id_product_array) && empty($id_product_array)) return true; + + $items = array(); + foreach ($id_product_array as $id_product) { + $product = new WC_Product($id_product); + if ($product->get_status() === "draft") continue; + + $items[] = ssbhesabixItemService::mapProduct($product, $id_product, false); + + $variations = $this->getProductVariations($id_product); + if ($variations) + foreach ($variations as $variation) + $items[] = ssbhesabixItemService::mapProductVariation($product, $variation, $id_product, false); + } + + if (count($items) === 0) return false; + if (!$this->saveItems($items)) return false; + return true; + } +//==================================================================================================================== + public function saveItems($items) + { + $hesabix = new Ssbhesabix_Api(); + $wpFaService = new HesabixWpFaService(); + + $response = $hesabix->itemBatchSave($items); + if ($response->Success) { + foreach ($response->Result as $item) + $wpFaService->saveProduct($item); + return true; + } else { + HesabixLogService::log(array("Cannot add/update Hesabix items. Error Code: " . (string)$response->ErrorCode . ". Error Message: $response->ErrorMessage.")); + return false; + } + } +//==================================================================================================================== + public function getContactCodeByCustomerId($id_customer) + { + if (!isset($id_customer)) { + return false; + } + + global $wpdb; + //$row = $wpdb->get_row("SELECT `id_hesabix` FROM " . $wpdb->prefix . "ssbhesabix WHERE `id_ps` = $id_customer AND `obj_type` = 'customer'"); + + $row = $wpdb->get_row( + $wpdb->prepare( + "SELECT `id_hesabix` FROM {$wpdb->prefix}ssbhesabix + WHERE `id_ps` = %d AND `obj_type` = 'customer'", + $id_customer + ) + ); + + if (is_object($row)) { + return $row->id_hesabix; + } else { + return null; + } + } +//==================================================================================================================== + public function setContact($id_customer, $type = 'first', $id_order = '') + { + if (!isset($id_customer)) return false; + + $code = $this->getContactCodeByCustomerId($id_customer); + + $hesabixCustomer = ssbhesabixCustomerService::mapCustomer($code, $id_customer, $type, $id_order); + + $hesabix = new Ssbhesabix_Api(); + $response = $hesabix->contactSave($hesabixCustomer); + + if ($response->Success) { + $wpFaService = new HesabixWpFaService(); + $wpFaService->saveCustomer($response->Result); + return $response->Result->Code; + } else { + HesabixLogService::log(array("Cannot add/update customer. Error Code: " . (string)$response->ErrroCode . ". Error Message: " . (string)$response->ErrorMessage . ". Customer ID: $id_customer")); + return false; + } + } +//==================================================================================================================== + public function setGuestCustomer($id_order) + { + if (!isset($id_order)) return false; + + //$order = new WC_Order($id_order); + $order = wc_get_order($id_order); + + $contactCode = $this->getContactCodeByPhoneOrEmail($order->get_billing_phone(), $order->get_billing_email()); + + $hesabixCustomer = ssbhesabixCustomerService::mapGuestCustomer($contactCode, $id_order); + + $hesabix = new Ssbhesabix_Api(); + $response = $hesabix->contactSave($hesabixCustomer); + + if ($response->Success) { + $wpFaService = new HesabixWpFaService(); + $wpFaService->saveCustomer($response->Result); + return (int)$response->Result->Code; + } else { + HesabixLogService::log(array("Cannot add/update contact. Error Code: " . (string)$response->ErrroCode . ". Error Message: " . (string)$response->ErrorMessage . ". Customer ID: Guest Customer")); + return false; + } + } +//==================================================================================================================== + public function getContactCodeByPhoneOrEmail($phone, $email) + { + if (!$email && !$phone) return null; + + $hesabix = new Ssbhesabix_Api(); + $response = $hesabix->contactGetByPhoneOrEmail($phone, $email); + + if (is_object($response)) { + if ($response->Success && $response->Result->TotalCount > 0) { + $contact_obj = $response->Result->List; + + if (!$contact_obj[0]->Code || $contact_obj[0]->Code == '0' || $contact_obj[0]->Code == '000000') return null; + + foreach ($contact_obj as $contact) { + if (($contact->phone == $phone || $contact->mobile = $phone) && $contact->email == $email) + return (int)$contact->Code; + } + foreach ($contact_obj as $contact) { + if ($phone && $contact->phone == $phone || $contact->mobile = $phone) + return (int)$contact->Code; + } + foreach ($contact_obj as $contact) { + if ($email && $contact->email == $email) + return (int)$contact->Code; + } + return null; + } + } else { + HesabixLogService::log(array("Cannot get Contact list. Error Message: (string)$response->ErrorMessage. Error Code: (string)$response->ErrorCode.")); + } + + return null; + } +//==================================================================================================================== + //Invoice + public function setOrder($id_order, $orderType = 0, $reference = null) + { + if (!isset($id_order)) { + return false; + } + + $wpFaService = new HesabixWpFaService(); + + $number = $this->getInvoiceNumberByOrderId($id_order); + if (!$number) { + $number = null; + if ($orderType == 2) //return if saleInvoice not set before + { + return false; + } + } + +// $order = new WC_Order($id_order); + $order = wc_get_order($id_order); + + $dokanOption = get_option("ssbhesabix_invoice_dokan", 0); + + if ($dokanOption && is_plugin_active("dokan-lite/dokan.php")) { + $orderCreated = $order->get_created_via(); + if ($dokanOption == 1 && $orderCreated !== 'checkout') + return false; + else if ($dokanOption == 2 && $orderCreated === 'checkout') + return false; + } + + $id_customer = $order->get_customer_id(); + if ($id_customer !== 0) { + + $contactCode = $this->setContact($id_customer, 'first', $id_order); + + if ($contactCode == null) { + if (!$contactCode) { + return false; + } + } + HesabixLogService::writeLogStr("order ID " . $id_order); + if (get_option('ssbhesabix_contact_address_status') == 2) { + $this->setContact($id_customer, 'billing', $id_order); + } elseif (get_option('ssbhesabix_contact_address_status') == 3) { + $this->setContact($id_customer, 'shipping', $id_order); + } + } else { + $contactCode = $this->setGuestCustomer($id_order); + if (!$contactCode) { + return false; + } + } + + global $notDefinedProductID; + $notDefinedItems = array(); + $products = $order->get_items(); + foreach ($products as $product) { + if ($product['product_id'] == 0) continue; + $itemCode = $wpFaService->getProductCodeByWpId($product['product_id'], $product['variation_id']); + if ($itemCode == null) { + $notDefinedItems[] = $product['product_id']; + } + } + + if (!empty($notDefinedItems)) { + if (!$this->setItems($notDefinedItems)) { + HesabixLogService::writeLogStr("Cannot add/update Invoice. Failed to set products. Order ID: $id_order"); + return false; + } + } + + $invoiceItems = array(); + $i = 0; + $failed = false; + foreach ($products as $key => $product) { + $itemCode = $wpFaService->getProductCodeByWpId($product['product_id'], $product['variation_id']); + + if ($itemCode == null) { + $pId = $product['product_id']; + $vId = $product['variation_id']; + HesabixLogService::writeLogStr("Item not found. productId: $pId, variationId: $vId, Order ID: $id_order"); + + $failed = true; + break; + } + +// $wcProduct = new WC_Product($product['product_id']); + + if($product['variation_id']) { + $wcProduct = wc_get_product($product['variation_id']); + } else { + $wcProduct = wc_get_product($product['product_id']); + } + + global $discount, $price; + if( $wcProduct->is_on_sale() && get_option('ssbhesabix_set_special_sale_as_discount') === 'yes' ) { + $price = $this->getPriceInHesabixDefaultCurrency($wcProduct->get_regular_price()); + $discount = $this->getPriceInHesabixDefaultCurrency($wcProduct->get_regular_price() - $wcProduct->get_sale_price()); + $discount *= $product['quantity']; + } else { + $price = $this->getPriceInHesabixDefaultCurrency($product['subtotal'] / $product['quantity']); + $discount = $this->getPriceInHesabixDefaultCurrency($product['subtotal'] - $product['total']); + } + + $item = array( + 'RowNumber' => $i, + 'ItemCode' => $itemCode, + 'Description' => Ssbhesabix_Validation::invoiceItemDescriptionValidation($product['name']), + 'Quantity' => (int)$product['quantity'], + 'UnitPrice' => (float)$price, + 'Discount' => (float)$discount, + 'Tax' => (float)$this->getPriceInHesabixDefaultCurrency($product['total_tax']), + ); + + $invoiceItems[] = $item; + $i++; + } + + if ($failed) { + HesabixLogService::writeLogStr("Cannot add/update Invoice. Item code is NULL. Check your invoice products and relations with Hesabix. Order ID: $id_order"); + return false; + } + + if (empty($invoiceItems)) { + HesabixLogService::log(array("Cannot add/update Invoice. At least one item required.")); + return false; + } + + $date_obj = $order->get_date_created(); + switch ($orderType) { + case 0: + $date = $date_obj->date('Y-m-d H:i:s'); + break; + case 2: + $date = date('Y-m-d H:i:s'); + break; + default: + $date = $date_obj->date('Y-m-d H:i:s'); + } + + if ($reference === null) + $reference = $id_order; + + $order_shipping_method = ""; + foreach ($order->get_items('shipping') as $item) + $order_shipping_method = $item->get_name(); + + $note = $order->customer_note; + if ($order_shipping_method) + $note .= "\n" . __('Shipping method', 'ssbhesabix') . ": " . $order_shipping_method; + + global $freightOption, $freightItemCode; + $freightOption = get_option("ssbhesabix_invoice_freight"); + + if($freightOption == 1) { + $freightItemCode = get_option('ssbhesabix_invoice_freight_code'); + if(!isset($freightItemCode) || !$freightItemCode) HesabixLogService::writeLogStr("کد هزینه حمل و نقل تعریف نشده است" . "\n" . "Freight service code is not set"); + + $freightItemCode = $this->convertPersianDigitsToEnglish($freightItemCode); + + if($this->getPriceInHesabixDefaultCurrency($order->get_shipping_total()) != 0) { + $invoiceItem = array( + 'RowNumber' => $i, + 'ItemCode' => $freightItemCode, + 'Description' => 'هزینه حمل و نقل', + 'Quantity' => 1, + 'UnitPrice' => (float) $this->getPriceInHesabixDefaultCurrency($order->get_shipping_total()), + 'Discount' => 0, + 'Tax' => (float) $this->getPriceInHesabixDefaultCurrency($order->get_shipping_tax()) + ); + $invoiceItems[] = $invoiceItem; + } + } + + $data = array( + 'Number' => $number, + 'InvoiceType' => $orderType, + 'ContactCode' => $contactCode, + 'Date' => $date, + 'DueDate' => $date, + 'Reference' => $reference, + 'Status' => 2, + 'Tag' => json_encode(array('id_order' => $id_order)), + 'InvoiceItems' => $invoiceItems, + 'Note' => $note, + 'Freight' => '' + ); + + if($freightOption == 0) { + $freight = $this->getPriceInHesabixDefaultCurrency($order->get_shipping_total() + $order->get_shipping_tax()); + $data['Freight'] = $freight; + } + + $invoice_draft_save = get_option('ssbhesabix_invoice_draft_save_in_hesabix', 'no'); + if ($invoice_draft_save != 'no') + $data['Status'] = 0; + + $invoice_project = get_option('ssbhesabix_invoice_project', -1); + $invoice_salesman = get_option('ssbhesabix_invoice_salesman', -1); + $invoice_salesman_percentage = get_option('ssbhesabix_invoice_salesman_percentage', 0); + if ($invoice_project != -1) $data['Project'] = $invoice_project; + if ($invoice_salesman != -1) $data['SalesmanCode'] = $invoice_salesman; + if($invoice_salesman_percentage) if($invoice_salesman_percentage != 0) $data['SalesmanPercent'] = $this->convertPersianDigitsToEnglish($invoice_salesman_percentage); + + $GUID = $this->getGUID($id_order); + $hesabix = new Ssbhesabix_Api(); + $response = $hesabix->invoiceSave($data, $GUID); +// $response = $hesabix->invoiceSave($data, ''); + + if ($response->Success) { + global $wpdb; + + switch ($orderType) { + case 0: + $obj_type = 'order'; + break; + case 2: + $obj_type = 'returnOrder'; + break; + } + + if ($number === null) { + $wpdb->insert($wpdb->prefix . 'ssbhesabix', array( + 'id_hesabix' => (int)$response->Result->Number, + 'obj_type' => $obj_type, + 'id_ps' => $id_order, + )); + HesabixLogService::log(array("Invoice successfully added. Invoice number: " . (string)$response->Result->Number . ". Order ID: $id_order")); + } else { + $wpFaId = $wpFaService->getWpFaId($obj_type, $id_order); + + $wpdb->update($wpdb->prefix . 'ssbhesabix', array( + 'id_hesabix' => (int)$response->Result->Number, + 'obj_type' => $obj_type, + 'id_ps' => $id_order, + ), array('id' => $wpFaId)); + HesabixLogService::log(array("Invoice successfully updated. Invoice number: " . (string)$response->Result->Number . ". Order ID: $id_order")); + } + + $warehouse = get_option('ssbhesabix_item_update_quantity_based_on', "-1"); + if ($warehouse != "-1" && $orderType === 0) + $this->setWarehouseReceipt($invoiceItems, (int)$response->Result->Number, $warehouse, $date, $invoice_project); + + return true; + } else { + foreach ($invoiceItems as $item) { + HesabixLogService::log(array("Cannot add/update Invoice. Error Code: " . (string)$response->ErrorCode . ". Error Message: " . (string)$response->ErrorMessage . ". Order ID: $id_order" . "\n" + . "Hesabix Id:" . $item['ItemCode'] + )); + } + return false; + } + } +//======================================================================================================================== + public function setWarehouseReceipt($items, $invoiceNumber, $warehouseCode, $date, $project) + { + $invoiceOption = get_option('ssbhesabix_invoice_freight'); + if($invoiceOption == 1) { + $invoiceFreightCode = get_option('ssbhesabix_invoice_freight_code'); + for ($i = 0 ; $i < count($items) ; $i++) { + if($items[$i]["ItemCode"] == $invoiceFreightCode) { + unset($items[$i]); + } + } + } + + $data = array( + 'WarehouseCode' => $warehouseCode, + 'InvoiceNumber' => $invoiceNumber, + 'InvoiceType' => 0, + 'Date' => $date, + 'Items' => $items + ); + + if ($project != -1) + $data['Project'] = $project; + + $hesabix = new Ssbhesabix_Api(); + $response = $hesabix->saveWarehouseReceipt($data); + + if ($response->Success) + HesabixLogService::log(array("Warehouse receipt successfully saved/updated. warehouse receipt number: " . (string)$response->Result->Number . ". Invoice number: $invoiceNumber")); + else + HesabixLogService::log(array("Cannot save/update Warehouse receipt. Error Code: " . (string)$response->ErrorCode . ". Error Message: " . (string)$response->ErrorMessage . ". Invoice number: $invoiceNumber")); + } +//======================================================================================================================== + public static function getPriceInHesabixDefaultCurrency($price) + { + if (!isset($price)) return false; + + $woocommerce_currency = get_woocommerce_currency(); + $hesabix_currency = get_option('ssbhesabix_hesabix_default_currency'); + + if (!is_numeric($price)) + $price = intval($price); + + if ($hesabix_currency == 'IRR' && $woocommerce_currency == 'IRT') + $price *= 10; + + if ($hesabix_currency == 'IRT' && $woocommerce_currency == 'IRR') + $price /= 10; + + return $price; + } +//======================================================================================================================== + public static function getPriceInWooCommerceDefaultCurrency($price) + { + if (!isset($price)) return false; + + $woocommerce_currency = get_woocommerce_currency(); + $hesabix_currency = get_option('ssbhesabix_hesabix_default_currency'); + + if (!is_numeric($price)) + $price = intval($price); + + if ($hesabix_currency == 'IRR' && $woocommerce_currency == 'IRT') + $price /= 10; + + if ($hesabix_currency == 'IRT' && $woocommerce_currency == 'IRR') + $price *= 10; + + return $price; + } +//======================================================================================================================== + public function setOrderPayment($id_order) + { + if (!isset($id_order)) { + return false; + } + + $hesabix = new Ssbhesabix_Api(); + $number = $this->getInvoiceCodeByOrderId($id_order); + if (!$number) { + return false; + } + + //$order = new WC_Order($id_order); + $order = wc_get_order($id_order); + + if ($order->get_total() <= 0) { + return true; + } + + + $transaction_id = $order->get_transaction_id(); + //transaction id cannot be null or empty + if ($transaction_id == '') { + $transaction_id = '-'; + } + + global $financialData; + if(get_option('ssbhesabix_payment_option') == 'no') { + $bank_code = $this->getBankCodeByPaymentMethod($order->get_payment_method()); + if ($bank_code != false) { + $payTempValue = substr($bank_code, 0, 4); + + switch($payTempValue) { + case 'bank': + $payTempValue = substr($bank_code, 4); + $financialData = array('bankCode' => $payTempValue);break; + case 'cash': + $payTempValue = substr($bank_code, 4); + $financialData = array('cashCode' => $payTempValue);break; + } + } else { + HesabixLogService::log(array("Cannot add Hesabix Invoice payment - Bank Code not defined. Order ID: $id_order")); + return false; + } + } elseif (get_option('ssbhesabix_payment_option') == 'yes') { + $defaultBankCode = $this->convertPersianDigitsToEnglish(get_option('ssbhesabix_default_payment_method_code')); + if($defaultBankCode != false) { + $financialData = array('bankCode' => $defaultBankCode); + } else { + HesabixLogService::writeLogStr("Default Bank Code is not Defined"); + return false; + } + } + + $date_obj = $order->get_date_paid(); + if ($date_obj == null) { + $date_obj = $order->get_date_modified(); + } + + global $accountPath; + + if(get_option("ssbhesabix_cash_in_transit") == "1" || get_option("ssbhesabix_cash_in_transit") == "yes") { + $func = new Ssbhesabix_Admin_Functions(); + $cashInTransitFullPath = $func->getCashInTransitFullPath(); + if(!$cashInTransitFullPath) { + HesabixLogService::writeLogStr("Cash in Transit is not Defined in Hesabix ---- وجوه در راه در حسابیکس یافت نشد"); + return false; + } else { + $accountPath = array("accountPath" => $cashInTransitFullPath); + } + } + + $response = $hesabix->invoiceGet($number); + if ($response->Success) { + if ($response->Result->Paid > 0) { + // payment submited before + } else { + $paymentMethod = $order->get_payment_method(); + $transactionFee = 0; + if(isset($paymentMethod)) { + if(get_option("ssbhesabix_payment_transaction_fee_$paymentMethod") > 0) $transactionFee = $this->formatTransactionFee(get_option("ssbhesabix_payment_transaction_fee_$paymentMethod"), $this->getPriceInHesabixDefaultCurrency($order->get_total())); + else $transactionFee = $this->formatTransactionFee(get_option("ssbhesabix_invoice_transaction_fee"), $this->getPriceInHesabixDefaultCurrency($order->get_total())); + } + + if(isset($transactionFee) && $transactionFee != null) $response = $hesabix->invoiceSavePayment($number, $financialData, $accountPath, $date_obj->date('Y-m-d H:i:s'), $this->getPriceInHesabixDefaultCurrency($order->get_total()), $transaction_id,'', $transactionFee); + else $response = $hesabix->invoiceSavePayment($number, $financialData, $accountPath, $date_obj->date('Y-m-d H:i:s'), $this->getPriceInHesabixDefaultCurrency($order->get_total()), $transaction_id,'', 0); + + if ($response->Success) { + HesabixLogService::log(array("Hesabix invoice payment added. Order ID: $id_order")); + return true; + } else { + HesabixLogService::log(array("Cannot add Hesabix Invoice payment. Order ID: $id_order. Error Code: " . (string)$response->ErrorCode . ". Error Message: " . (string)$response->ErrorMessage . ".")); + return false; + } + } + return true; + } else { + HesabixLogService::log(array("Error while trying to get invoice. Invoice Number: $number. Error Code: " . (string)$response->ErrorCode . ". Error Message: " . (string)$response->ErrorMessage . ".")); + return false; + } + } +//======================================================================================================================== + public function getCashInTransitFullPath() { + $api = new Ssbhesabix_Api(); + $accounts = $api->settingGetAccounts(); + foreach ($accounts->Result as $account) { + if($account->Name == "وجوه در راه") { + return $account->FullPath; + } + } + return false; + } +//======================================================================================================================== + public function getInvoiceNumberByOrderId($id_order) + { + if (!isset($id_order)) return false; + + global $wpdb; + $row = $wpdb->get_row("SELECT `id_hesabix` FROM " . $wpdb->prefix . "ssbhesabix WHERE `id_ps` = $id_order AND `obj_type` = 'order'"); + + if (is_object($row)) { + return $row->id_hesabix; + } else { + return false; + } + } +//======================================================================================================================== + public function getBankCodeByPaymentMethod($payment_method) + { + $code = get_option('ssbhesabix_payment_method_' . $payment_method); + + if (isset($code)) + return $code; + else + return false; + } +//======================================================================================================================== + public function getInvoiceCodeByOrderId($id_order) + { + if (!isset($id_order)) return false; + + global $wpdb; + $row = $wpdb->get_row("SELECT `id_hesabix` FROM " . $wpdb->prefix . "ssbhesabix WHERE `id_ps` = $id_order AND `obj_type` = 'order'"); + + if (is_object($row)) { + return $row->id_hesabix; + } else { + return false; + } + } +//======================================================================================================================== + public function exportProducts($batch, $totalBatch, $total, $updateCount) + { + HesabixLogService::writeLogStr("Exporting Products"); + try { + $wpFaService = new HesabixWpFaService(); + $extraSettingRPP = get_option("ssbhesabix_set_rpp_for_export_products"); + $rpp=500; + if($extraSettingRPP) { + if($extraSettingRPP != '-1' && $extraSettingRPP != '0') { + $rpp=$extraSettingRPP; + } + } + $result = array(); + $result["error"] = false; + global $wpdb; + + if ($batch == 1) { +// $total = $wpdb->get_var("SELECT COUNT(*) FROM `" . $wpdb->prefix . "posts` +// WHERE post_type = 'product' AND post_status IN('publish','private')"); + + $total = $wpdb->get_var( + $wpdb->prepare( + "SELECT COUNT(*) FROM {$wpdb->posts} + WHERE post_type = 'product' AND post_status IN ('publish', 'private')" + ) + ); + + $totalBatch = ceil($total / $rpp); + } + + $offset = ($batch - 1) * $rpp; +// $products = $wpdb->get_results("SELECT ID FROM `" . $wpdb->prefix . "posts` +// WHERE post_type = 'product' AND post_status IN('publish','private') ORDER BY 'ID' ASC LIMIT $offset,$rpp"); + + $products = $wpdb->get_results( + $wpdb->prepare( + "SELECT ID FROM {$wpdb->posts} + WHERE post_type = 'product' AND post_status IN ('publish', 'private') + ORDER BY ID ASC + LIMIT %d, %d", + $offset, + $rpp + ) + ); + + $items = array(); + + foreach ($products as $item) { + $id_product = $item->ID; + $product = new WC_Product($id_product); + + $id_obj = $wpFaService->getWpFaId('product', $id_product, 0); + + if (!$id_obj) { + $hesabixItem = ssbhesabixItemService::mapProduct($product, $id_product); + array_push($items, $hesabixItem); + $updateCount++; + } + + $variations = $this->getProductVariations($id_product); + if ($variations) { + foreach ($variations as $variation) { + $id_attribute = $variation->get_id(); + $id_obj = $wpFaService->getWpFaId('product', $id_product, $id_attribute); + + if (!$id_obj) { + $hesabixItem = ssbhesabixItemService::mapProductVariation($product, $variation, $id_product); + array_push($items, $hesabixItem); + $updateCount++; + } + } + } + } + + if (!empty($items)) { + $count = 0; + $hesabix = new Ssbhesabix_Api(); + $response = $hesabix->itemBatchSave($items); + if ($response->Success) { + foreach ($response->Result as $item) { + $json = json_decode($item->Tag); + + global $wpdb; + $wpdb->insert($wpdb->prefix . 'ssbhesabix', array( + 'id_hesabix' => (int)$item->Code, + 'obj_type' => 'product', + 'id_ps' => (int)$json->id_product, + 'id_ps_attribute' => (int)$json->id_attribute, + )); + HesabixLogService::log(array("Item successfully added. Item Code: " . (string)$item->Code . ". Product ID: $json->id_product - $json->id_attribute")); + } + $count += count($response->Result); + } else { + HesabixLogService::log(array("Cannot add bulk item. Error Message: " . (string)$response->ErrorMessage . ". Error Code: " . (string)$response->ErrorCode . ".")); + } + sleep(2); + } + + $result["batch"] = $batch; + $result["totalBatch"] = $totalBatch; + $result["total"] = $total; + $result["updateCount"] = $updateCount; + return $result; + } catch(Error $error) { + HesabixLogService::writeLogStr("Error in export products: " . $error->getMessage()); + } + } +//======================================================================================================================== + public function importProducts($batch, $totalBatch, $total, $updateCount) + { + HesabixLogService::writeLogStr("Import Products"); + try { + $wpFaService = new HesabixWpFaService(); + $extraSettingRPP = get_option("ssbhesabix_set_rpp_for_import_products"); + + $rpp=100; + if($extraSettingRPP) { + if($extraSettingRPP != '-1' && $extraSettingRPP != '0') { + $rpp=$extraSettingRPP; + } + } + + $result = array(); + $result["error"] = false; + global $wpdb; + $hesabix = new Ssbhesabix_Api(); + $filters = array(array("Property" => "khadamat", "Operator" => "=", "Value" => 0)); + + if ($batch == 1) { + $total = 0; + $response = $hesabix->itemGetItems(array('Take' => 1, 'Filters' => $filters)); + if ($response->Success) { + $total = $response->Result->FilteredCount; + $totalBatch = ceil($total / $rpp); + } else { + HesabixLogService::log(array("Error while trying to get products for import. Error Message: $response->ErrorMessage. Error Code: $response->ErrorCode.")); + $result["error"] = true; + return $result; + }; + } + + $id_product_array = array(); + $offset = ($batch - 1) * $rpp; + + $response = $hesabix->itemGetItems(array('Skip' => $offset, 'Take' => $rpp, 'SortBy' => 'Id', 'Filters' => $filters)); + if ($response->Success) { + $items = $response->Result->List; + $from = $response->Result->From; + $to = $response->Result->To; + + foreach ($items as $item) { + $wpFa = $wpFaService->getWpFaByHesabixId('product', $item->Code); + if ($wpFa) continue; + + $clearedName = preg_replace("/\s+|\/|\\\|\(|\)/", '-', trim($item->Name)); + $clearedName = preg_replace("/\-+/", '-', $clearedName); + $clearedName = trim($clearedName, '-'); + $clearedName = preg_replace(["/۰/", "/۱/", "/۲/", "/۳/", "/۴/", "/۵/", "/۶/", "/۷/", "/۸/", "/۹/"], + ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"], $clearedName); + + // add product to database + $wpdb->insert($wpdb->posts, array( + 'post_author' => get_current_user_id(), + 'post_date' => current_time('mysql'), + 'post_date_gmt' => current_time('mysql', 1), + 'post_content' => '', + 'post_title' => $item->Name, + 'post_excerpt' => '', + 'post_status' => 'private', + 'comment_status' => 'open', + 'ping_status' => 'closed', + 'post_password' => '', + 'post_name' => $clearedName, + 'to_ping' => '', + 'pinged' => '', + 'post_modified' => current_time('mysql'), + 'post_modified_gmt' => current_time('mysql', 1), + 'post_content_filtered' => '', + 'post_parent' => 0, + 'guid' => home_url('/product/' . $clearedName . '/'), + 'menu_order' => 0, + 'post_type' => 'product', + 'post_mime_type' => '', + 'comment_count' => 0, + )); + + $postId = $wpdb->insert_id; + $id_product_array[] = $postId; + $price = self::getPriceInWooCommerceDefaultCurrency($item->SellPrice); + + // add product link to hesabix + $wpdb->insert($wpdb->prefix . 'ssbhesabix', array( + 'obj_type' => 'product', + 'id_hesabix' => (int)$item->Code, + 'id_ps' => $postId, + 'id_ps_attribute' => 0, + )); + + update_post_meta($postId, '_manage_stock', 'yes'); + update_post_meta($postId, '_sku', $item->Barcode); + update_post_meta($postId, '_regular_price', $price); + update_post_meta($postId, '_price', $price); + update_post_meta($postId, '_stock', $item->Stock); + + $new_stock_status = ($item->Stock > 0) ? "instock" : "outofstock"; + wc_update_product_stock_status($postId, $new_stock_status); + $updateCount++; + } + + } else { + HesabixLogService::log(array("Error while trying to get products for import. Error Message: (string)$response->ErrorMessage. Error Code: (string)$response->ErrorCode.")); + $result["error"] = true; + return $result; + } + sleep(2); + + $result["batch"] = $batch; + $result["totalBatch"] = $totalBatch; + $result["total"] = $total; + $result["updateCount"] = $updateCount; + return $result; + } catch(Error $error) { + HesabixLogService::writeLogStr("Error in importing products" . $error->getMessage()); + } + } +//======================================================================================================================== + public function exportOpeningQuantity($batch, $totalBatch, $total) + { + try { + $wpFaService = new HesabixWpFaService(); + + $result = array(); + $result["error"] = false; + $extraSettingRPP = get_option("ssbhesabix_set_rpp_for_export_opening_products"); + + $rpp=500; + if($extraSettingRPP) { + if($extraSettingRPP != '-1' && $extraSettingRPP != '0') { + $rpp=$extraSettingRPP; + } + } + + global $wpdb; + + if ($batch == 1) { + $total = $wpdb->get_var( + $wpdb->prepare( + "SELECT COUNT(*) FROM {$wpdb->posts} + WHERE post_type = 'product' AND post_status IN ('publish', 'private')" + ) + ); + $totalBatch = ceil($total / $rpp); + } + + $offset = ($batch - 1) * $rpp; + + $products = $wpdb->get_results( + $wpdb->prepare( + "SELECT ID FROM {$wpdb->posts} + WHERE post_type = 'product' AND post_status IN ('publish', 'private') + ORDER BY ID ASC + LIMIT %d, %d", + $offset, + $rpp + ) + ); + + $items = array(); + + foreach ($products as $item) { + $variations = $this->getProductVariations($item->ID); + if (!$variations) { + $id_obj = $wpFaService->getWpFaId('product', $item->ID, 0); + + if ($id_obj != false) { + $product = new WC_Product($item->ID); + $quantity = $product->get_stock_quantity(); + $price = $product->get_regular_price() ? $product->get_regular_price() : $product->get_price(); + + $row = $wpdb->get_row("SELECT `id_hesabix` FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id` = " . $id_obj . " AND `obj_type` = 'product'"); + + if (is_object($product) && is_object($row) && $quantity > 0 && $price > 0) { + array_push($items, array( + 'Code' => $row->id_hesabix, + 'Quantity' => $quantity, + 'UnitPrice' => $this->getPriceInHesabixDefaultCurrency($price), + )); + } + } + } else { + foreach ($variations as $variation) { + $id_attribute = $variation->get_id(); + $id_obj = $wpFaService->getWpFaId('product', $item->ID, $id_attribute); + if ($id_obj != false) { + $quantity = $variation->get_stock_quantity(); + $price = $variation->get_regular_price() ? $variation->get_regular_price() : $variation->get_price(); + + $row = $wpdb->get_row("SELECT `id_hesabix` FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id` = " . $id_obj . " AND `obj_type` = 'product'"); + + if (is_object($variation) && is_object($row) && $quantity > 0 && $price > 0) { + array_push($items, array( + 'Code' => $row->id_hesabix, + 'Quantity' => $quantity, + 'UnitPrice' => $this->getPriceInHesabixDefaultCurrency($price), + )); + } + } + } + } + } + + if (!empty($items)) { + $hesabix = new Ssbhesabix_Api(); + $response = $hesabix->itemUpdateOpeningQuantity($items); + if ($response->Success) { + // continue batch loop + } else { + HesabixLogService::log(array("ssbhesabix - Cannot set Opening quantity. Error Code: ' . $response->ErrorCode . '. Error Message: ' . $response->ErrorMessage")); + $result['error'] = true; + if ($response->ErrorCode = 199 && $response->ErrorMessage == 'No-Shareholders-Exist') { + $result['errorType'] = 'shareholderError'; + return $result; + } + return $result; + } + } + sleep(2); + $result["batch"] = $batch; + $result["totalBatch"] = $totalBatch; + $result["total"] = $total; + $result["done"] = $batch == $totalBatch; + return $result; + } catch(Error $error) { + HesabixLogService::writeLogStr("Error in Exporting Opening Quantity" . $error->getMessage()); + } + } +//======================================================================================================================== + public function exportCustomers($batch, $totalBatch, $total, $updateCount) + { + HesabixLogService::writeLogStr("Export Customers"); + $wpFaService = new HesabixWpFaService(); + + $result = array(); + $result["error"] = false; + $rpp = 500; + global $wpdb; + + if ($batch == 1) { + $total = $wpdb->get_var("SELECT COUNT(*) FROM `" . $wpdb->prefix . "users`"); + $totalBatch = ceil($total / $rpp); + } + + $offset = ($batch - 1) * $rpp; + $customers = $wpdb->get_results("SELECT ID FROM `" . $wpdb->prefix . "users` ORDER BY ID ASC LIMIT $offset,$rpp"); + + $items = array(); + foreach ($customers as $item) { + $id_customer = $item->ID; + $id_obj = $wpFaService->getWpFaId('customer', $id_customer); + if (!$id_obj) { + $hesabixCustomer = ssbhesabixCustomerService::mapCustomer(null, $id_customer); + array_push($items, $hesabixCustomer); + $updateCount++; + } + } + + if (!empty($items)) { + $hesabix = new Ssbhesabix_Api(); + $response = $hesabix->contactBatchSave($items); + if ($response->Success) { + foreach ($response->Result as $item) { + $json = json_decode($item->Tag); + + $wpdb->insert($wpdb->prefix . 'ssbhesabix', array( + 'id_hesabix' => (int)$item->Code, + 'obj_type' => 'customer', + 'id_ps' => (int)$json->id_customer, + )); + + HesabixLogService::log(array("Contact successfully added. Contact Code: " . $item->Code . ". Customer ID: " . (int)$json->id_customer)); + } + } else { + HesabixLogService::log(array("Cannot add bulk contacts. Error Message: $response->ErrorMessage. Error Code: $response->ErrorCode.")); + } + } + + $result["batch"] = $batch; + $result["totalBatch"] = $totalBatch; + $result["total"] = $total; + $result["updateCount"] = $updateCount; + + return $result; + } +//======================================================================================================================== + public function syncOrders($from_date, $end_date, $batch, $totalBatch, $total, $updateCount) + { + HesabixLogService::writeLogStr("Sync Orders"); + $wpFaService = new HesabixWpFaService(); + + $result = array(); + $result["error"] = false; + $rpp = 10; + global $wpdb; + + if (!isset($from_date) || empty($from_date)) { + $result['error'] = 'inputDateError'; + return $result; + } + + if (!isset($end_date) || empty($end_date)) { + $result['error'] = 'inputDateError'; + return $result; + } + + if (!$this->isDateInFiscalYear($from_date)) { + $result['error'] = 'fiscalYearError'; + return $result; + } + + if (!$this->isDateInFiscalYear($end_date)) { + $result['error'] = 'fiscalYearError'; + return $result; + } + + if ($batch == 1) { + if (get_option('woocommerce_custom_orders_table_enabled') === 'yes') { + $total = $wpdb->get_var("SELECT COUNT(*) FROM `" . $wpdb->prefix . "wc_orders` + WHERE type = 'shop_order' AND date_created_gmt >= '" . $from_date . "' AND date_created_gmt <= '". $end_date ."'"); + } else { + $total = $wpdb->get_var("SELECT COUNT(*) FROM `" . $wpdb->prefix . "posts` + WHERE post_type = 'shop_order' AND post_date >= '" . $from_date . "' AND post_date <= '". $end_date ."'"); + } + $totalBatch = ceil($total / $rpp); + } + + $offset = ($batch - 1) * $rpp; + + if (get_option('woocommerce_custom_orders_table_enabled') === 'yes') { + $orders = $wpdb->get_results("SELECT ID FROM `" . $wpdb->prefix . "wc_orders` + WHERE type = 'shop_order' AND date_created_gmt >= '" . $from_date . "' + AND date_created_gmt <= '". $end_date ."' + ORDER BY ID ASC LIMIT $offset,$rpp"); + } else { + $orders = $wpdb->get_results("SELECT ID FROM `" . $wpdb->prefix . "posts` + WHERE post_type = 'shop_order' AND post_date >= '" . $from_date . "' + AND post_date <= '". $end_date ."' + ORDER BY ID ASC LIMIT $offset,$rpp"); + } + + HesabixLogService::writeLogStr("Orders count: " . count($orders)); + + $statusesToSubmitInvoice = get_option('ssbhesabix_invoice_status'); + $statusesToSubmitInvoice = implode(',', $statusesToSubmitInvoice); + $statusesToSubmitReturnInvoice = get_option('ssbhesabix_invoice_return_status'); + $statusesToSubmitReturnInvoice = implode(',', $statusesToSubmitReturnInvoice); + $statusesToSubmitPayment = get_option('ssbhesabix_payment_status'); + $statusesToSubmitPayment = implode(',', $statusesToSubmitPayment); + + $id_orders = array(); + foreach ($orders as $order) { + //$order = new WC_Order($order->ID); + $order = wc_get_order($order->ID); + + $id_order = $order->get_id(); + $id_obj = $wpFaService->getWpFaId('order', $id_order); + $current_status = $order->get_status(); + + if (!$id_obj) { + if (strpos($statusesToSubmitInvoice, $current_status) !== false) { + if ($this->setOrder($id_order)) { + array_push($id_orders, $id_order); + $updateCount++; + + if (strpos($statusesToSubmitPayment, $current_status) !== false) + $this->setOrderPayment($id_order); + + // set return invoice + if (strpos($statusesToSubmitReturnInvoice, $current_status) !== false) { + $this->setOrder($id_order, 2, $this->getInvoiceCodeByOrderId($id_order)); + } + } + } + } else { + if (strpos($statusesToSubmitPayment, $current_status) !== false) + $this->setOrderPayment($id_order); + } + } + + $result["batch"] = $batch; + $result["totalBatch"] = $totalBatch; + $result["total"] = $total; + $result["updateCount"] = $updateCount; + return $result; + } +//======================================================================================================================== + public function syncProducts($batch, $totalBatch, $total) + { + try { + HesabixLogService::writeLogStr("Sync products price and quantity from hesabix to store: part $batch"); + $result = array(); + $result["error"] = false; + $extraSettingRPP = get_option("ssbhesabix_set_rpp_for_sync_products_into_woocommerce"); + + $rpp=200; + if($extraSettingRPP) { + if($extraSettingRPP != '-1' && $extraSettingRPP != '0') { + $rpp=$extraSettingRPP; + } + } + + $hesabix = new Ssbhesabix_Api(); + $filters = array(array("Property" => "khadamat", "Operator" => "=", "Value" => 0)); + + if ($batch == 1) { + $response = $hesabix->itemGetItems(array('Take' => 1, 'Filters' => $filters)); + if ($response->Success) { + $total = $response->Result->FilteredCount; + $totalBatch = ceil($total / $rpp); + } else { + HesabixLogService::log(array("Error while trying to get products for sync. Error Message: $response->ErrorMessage. Error Code: $response->ErrorCode.")); + $result["error"] = true; + return $result; + } + } + + $offset = ($batch - 1) * $rpp; + $response = $hesabix->itemGetItems(array('Skip' => $offset, 'Take' => $rpp, 'SortBy' => 'Id', 'Filters' => $filters)); + + $warehouse = get_option('ssbhesabix_item_update_quantity_based_on', "-1"); + + if ($warehouse != "-1") { + $products = $response->Result->List; + $codes = []; + foreach ($products as $product) + $codes[] = $product->Code; + $response = $hesabix->itemGetQuantity($warehouse, $codes); + } + + if ($response->Success) { + $products = $warehouse == "-1" ? $response->Result->List : $response->Result; + foreach ($products as $product) { + self::setItemChanges($product); + } + } else { + HesabixLogService::log(array("Error while trying to get products for sync. Error Message: $response->ErrorMessage. Error Code: $response->ErrorCode.")); + $result["error"] = true; + return $result; + } + + $result["batch"] = $batch; + $result["totalBatch"] = $totalBatch; + $result["total"] = $total; + return $result; + } catch (Error $error) { + HesabixLogService::writeLogStr("Error in sync products: " . $error->getMessage()); + } + } +//======================================================================================================================== + public function syncProductsManually($data) + { + HesabixLogService::writeLogStr('Sync Products Manually'); + + $hesabix_item_codes = array(); + foreach ($data as $d) { + if ($d["hesabix_id"]) { + $hesabix_item_codes[] = str_pad($d["hesabix_id"], 6, "0", STR_PAD_LEFT); + } + } + + $hesabix = new Ssbhesabix_Api(); + + $filters = array(array("Property" => "Code", "Operator" => "in", "Value" => $hesabix_item_codes)); + $response = $hesabix->itemGetItems(array('Take' => 100, 'Filters' => $filters)); + + if ($response->Success) { + $products = $response->Result->List; + $products_codes = array(); + foreach ($products as $product) + $products_codes[] = $product->Code; + $diff = array_diff($hesabix_item_codes, $products_codes); + if (is_array($diff) && count($diff) > 0) { + return array("result" => false, "data" => $diff); + } + } + + $id_product_array = array(); + global $wpdb; + + foreach ($data as $d) { + $row = $wpdb->get_row("SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id_ps_attribute` = " . $d["id"] . " AND `obj_type` = 'product'"); + + if (!is_object($row)) { + $row = $wpdb->get_row("SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id_ps` = " . $d["id"] . " AND `obj_type` = 'product'"); + } + if (is_object($row)) { + if (!$d["hesabix_id"]) + $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id' => $row->id)); + else + $wpdb->update($wpdb->prefix . 'ssbhesabix', array('id_hesabix' => $d["hesabix_id"]), array('id' => $row->id)); + } else { + if (!$d["hesabix_id"]) + continue; + if ($d["parent_id"]) + $wpdb->insert($wpdb->prefix . 'ssbhesabix', array('obj_type' => 'product', 'id_hesabix' => $d["hesabix_id"], 'id_ps' => $d["parent_id"], 'id_ps_attribute' => $d["id"])); + else + $wpdb->insert($wpdb->prefix . 'ssbhesabix', array('obj_type' => 'product', 'id_hesabix' => $d["hesabix_id"], 'id_ps' => $d["id"], 'id_ps_attribute' => '0')); + } + + if ($d["hesabix_id"]) { + if ($d["parent_id"]) { + if (!in_array($d["parent_id"], $id_product_array)) + $id_product_array[] = $d["parent_id"]; + } else { + if (!in_array($d["id"], $id_product_array)) + $id_product_array[] = $d["id"]; + } + } + } + + $this->setItems($id_product_array); + return array("result" => true, "data" => null); + } +//======================================================================================================================== + public function updateProductsInHesabixBasedOnStore($batch, $totalBatch, $total) + { + HesabixLogService::writeLogStr("Update Products In Hesabix Based On Store"); + $result = array(); + $result["error"] = false; + $extraSettingRPP = get_option('ssbhesabix_set_rpp_for_sync_products_into_hesabix'); + + $rpp=500; + if($extraSettingRPP) { + if($extraSettingRPP != '-1' && $extraSettingRPP != '0') { + $rpp=$extraSettingRPP; + } + } + + global $wpdb; + + if ($batch == 1) { + //$total = $wpdb->get_var("SELECT COUNT(*) FROM `" . $wpdb->prefix . "posts` WHERE post_type = 'product' AND post_status IN('publish','private')"); + + $total = $wpdb->get_var( + $wpdb->prepare( + "SELECT COUNT(*) FROM {$wpdb->posts} + WHERE post_type = 'product' AND post_status IN ('publish', 'private')" + ) + ); + $totalBatch = ceil($total / $rpp); + } + + $offset = ($batch - 1) * $rpp; +// $products = $wpdb->get_results("SELECT ID FROM `" . $wpdb->prefix . "posts` +// WHERE post_type = 'product' AND post_status IN('publish','private') ORDER BY 'ID' ASC LIMIT $offset,$rpp"); + + $products = $wpdb->get_results( + $wpdb->prepare( + "SELECT ID FROM {$wpdb->posts} + WHERE post_type = 'product' AND post_status IN ('publish', 'private') + ORDER BY ID ASC + LIMIT %d, %d", + $offset, + $rpp + ) + ); + + $products_id_array = array(); + foreach ($products as $product) + $products_id_array[] = $product->ID; + $this->setItems($products_id_array); + sleep(2); + + $result["batch"] = $batch; + $result["totalBatch"] = $totalBatch; + $result["total"] = $total; + return $result; + } +//======================================================================================================================== + public static function updateProductsInHesabixBasedOnStoreWithFilter($offset=0, $rpp=0) + { + HesabixLogService::writeLogStr("Update Products With Filter In Hesabix Based On Store"); + $result = array(); + $result["error"] = false; + + global $wpdb; + if($offset != 0 && $rpp != 0) { + if(abs($rpp - $offset) <= 200) { + if($rpp > $offset) { +// $products = $wpdb->get_results("SELECT * FROM `" . $wpdb->prefix . "posts` +// WHERE ID BETWEEN $offset AND $rpp AND post_type = 'product' AND post_status IN('publish','private') ORDER BY 'ID' ASC"); + + $products = $wpdb->get_results( + $wpdb->prepare( + "SELECT * FROM {$wpdb->posts} + WHERE ID BETWEEN %d AND %d + AND post_type = 'product' + AND post_status IN ('publish', 'private') + ORDER BY ID ASC", + $offset, + $rpp + ) + ); + + $products_id_array = array(); + foreach ($products as $product) + $products_id_array[] = $product->ID; + $response = (new Ssbhesabix_Admin_Functions)->setItems($products_id_array); + if(!$response) $result['error'] = true; + } else { +// $products = $wpdb->get_results("SELECT * FROM `" . $wpdb->prefix . "posts` +// WHERE ID BETWEEN $rpp AND $offset AND post_type = 'product' AND post_status IN('publish','private') ORDER BY 'ID' ASC"); + + $products = $wpdb->get_results( + $wpdb->prepare( + "SELECT * FROM {$wpdb->posts} + WHERE ID BETWEEN %d AND %d + AND post_type = 'product' + AND post_status IN ('publish', 'private') + ORDER BY ID ASC", + $rpp, + $offset + ) + ); + + $products_id_array = array(); + foreach ($products as $product) + $products_id_array[] = $product->ID; + $response = (new Ssbhesabix_Admin_Functions)->setItems($products_id_array); + if(!$response) $result['error'] = true; + } + } else { + $result['error'] = true; + echo ''; + } + } else { + echo ''; + } + + return $result; + } +//======================================================================================================================== + public function cleanLogFile() + { + HesabixLogService::clearLog(); + return true; + } +//======================================================================================================================== + public static function setItemChanges($item) + { + if (!is_object($item)) return false; + + if ($item->Quantity || !$item->Stock) + $item->Stock = $item->Quantity; + + $wpFaService = new HesabixWpFaService(); + global $wpdb; + + $wpFa = $wpFaService->getWpFaByHesabixId('product', $item->Code); + if (!$wpFa) return false; + + $id_product = $wpFa->idWp; + $id_attribute = $wpFa->idWpAttribute; + + if ($id_product == 0) { + HesabixLogService::log(array("Item with code: $item->Code is not defined in Online store")); + return false; + } + + //$found = $wpdb->get_var("SELECT COUNT(*) FROM `" . $wpdb->prefix . "posts` WHERE ID = $id_product"); + + $found = $wpdb->get_var( + $wpdb->prepare( + "SELECT COUNT(*) FROM {$wpdb->posts} + WHERE ID = %d", + $id_product + ) + ); + + + if (!$found) { + HesabixLogService::writeLogStr("product not found in woocommerce.code: $item->Code, product id: $id_product, variation id: $id_attribute"); + return false; + } + + $product = wc_get_product($id_product); + $variation = $id_attribute != 0 ? wc_get_product($id_attribute) : null; + + +// $product = new WC_Product($id_product); +// $variation = $id_attribute != 0 ? new WC_Product($id_attribute) : null; + + $result = array(); + $result["newPrice"] = null; + $result["newQuantity"] = null; + + $p = $variation ? $variation : $product; + + if (get_option('ssbhesabix_item_update_price') == 'yes') + $result = self::setItemNewPrice($p, $item, $id_attribute, $id_product, $result); + + if (get_option('ssbhesabix_item_update_quantity') == 'yes') + $result = self::setItemNewQuantity($p, $item, $id_product, $id_attribute, $result); + + return $result; + } +//======================================================================================================================== + private static function setItemNewPrice($product, $item, $id_attribute, $id_product, array $result) + { + try { + $option_sale_price = get_option('ssbhesabix_item_update_sale_price', 0); + $woocommerce_currency = get_woocommerce_currency(); + $hesabix_currency = get_option('ssbhesabix_hesabix_default_currency'); + + $old_price = $product->get_regular_price() ? $product->get_regular_price() : $product->get_price(); + $old_price = Ssbhesabix_Admin_Functions::getPriceInHesabixDefaultCurrency($old_price); + + $post_id = $id_attribute && $id_attribute > 0 ? $id_attribute : $id_product; + + if ($item->SellPrice != $old_price) { + $new_price = Ssbhesabix_Admin_Functions::getPriceInWooCommerceDefaultCurrency($item->SellPrice); + update_post_meta($post_id, '_regular_price', $new_price); + update_post_meta($post_id, '_price', $new_price); + + + $sale_price = $product->get_sale_price(); + if ($sale_price && is_numeric($sale_price)) { + $sale_price = Ssbhesabix_Admin_Functions::getPriceInHesabixDefaultCurrency($sale_price); + if (+$option_sale_price === 1) { + update_post_meta($post_id, '_sale_price', null); + } elseif (+$option_sale_price === 2) { + update_post_meta($post_id, '_sale_price', round(($sale_price * $new_price) / $old_price)); + update_post_meta($post_id, '_price', round(($sale_price * $new_price) / $old_price)); + } else { + if($woocommerce_currency == 'IRT' && $hesabix_currency == 'IRR') update_post_meta($post_id, '_price', ($sale_price/10)); + elseif($woocommerce_currency == 'IRR' && $hesabix_currency == 'IRT') update_post_meta($post_id, '_price', ($sale_price*10)); + elseif($woocommerce_currency == 'IRR' && $hesabix_currency == 'IRR') update_post_meta($post_id, '_price', $sale_price); + elseif($woocommerce_currency == 'IRT' && $hesabix_currency == 'IRT') update_post_meta($post_id, '_price', $sale_price); + } + } + + HesabixLogService::log(array("product ID $id_product-$id_attribute Price changed. Old Price: $old_price. New Price: $new_price")); + $result["newPrice"] = $new_price; + } + + return $result; + } catch (Error $error) { + HesabixLogService::writeLogStr("Error in Set Item New Price -> $error"); + } + } +//======================================================================================================================== + private static function setItemNewQuantity($product, $item, $id_product, $id_attribute, array $result) + { + try { + $old_quantity = $product->get_stock_quantity(); + if ($item->Stock != $old_quantity) { + $new_quantity = $item->Stock; + if (!$new_quantity) $new_quantity = 0; + + $new_stock_status = ($new_quantity > 0) ? "instock" : "outofstock"; + + $post_id = ($id_attribute && $id_attribute > 0) ? $id_attribute : $id_product; + +// update_post_meta($post_id, '_stock', $new_quantity); +// wc_update_product_stock_status($post_id, $new_stock_status); + + $product = wc_get_product( $post_id ); + if ( $product ) { + + $product->set_stock_quantity( $new_quantity ); + $product->set_stock_status( $new_stock_status ); + $product->save(); + HesabixLogService::log(array("product ID $id_product-$id_attribute quantity changed. Old quantity: $old_quantity. New quantity: $new_quantity")); + $result["newQuantity"] = $new_quantity; + } + } + + return $result; + } catch (Error $error) { + HesabixLogService::writeLogStr("Error in Set Item New Quantity -> $error"); + } + } +//========================================================================================================================= + public static function syncLastChangeID(): bool { + try { + HesabixLogService::writeLogStr("Sync Last Change ID"); + $hesabixApi = new Ssbhesabix_Api(); + $lastChange = $hesabixApi->getLastChangeId(); + + if ($lastChange && isset($lastChange->LastId)) { + update_option('ssbhesabix_last_log_check_id', $lastChange->LastId - 1); + return true; + } + } catch (Exception $error) { + HesabixLogService::writeLogStr("Error in syncing last change id -> " . $error->getMessage()); + } + + return false; + } +//========================================================================================================================= + public static function SaveProductManuallyToHesabix($woocommerceCode, $attributeId, $hesabixCode): bool { + //check no record exist in hesabix + $isProductExistInHesabix = self::CheckExistenceOfTheProductInHesabix($hesabixCode); + if(!$isProductExistInHesabix) { + $isProductValidInWoocommerce = self::CheckValidityOfTheProductInWoocommerce($woocommerceCode, $attributeId, $hesabixCode); + if($isProductValidInWoocommerce) { + //get product + $product = wc_get_product($woocommerceCode); + if($attributeId != 0) $variation = wc_get_product($attributeId); + + if($attributeId == 0) { + $hesabixItem = ssbhesabixItemService::mapProduct($product, $woocommerceCode); + } else { + $hesabixItem = ssbhesabixItemService::mapProductVariation($product, $variation, $woocommerceCode); + } + + //save product to hesabix and make a new link + $api = new Ssbhesabix_Api(); + $hesabixItem["Code"] = $hesabixCode; + $response = $api->itemSave($hesabixItem); + if($response->Success) { + if($attributeId == 0) $productCode = $woocommerceCode; else $productCode = $attributeId; + HesabixLogService::log(array("Item successfully added to Hesabix. Hesabix code: " . $hesabixCode . " - Product code: " . $productCode)); + + $wpFaService = new HesabixWpFaService(); + $wpFa = $wpFaService->getWpFa('product', $woocommerceCode, $attributeId); + if (!$wpFa) { + $wpFa = new WpFa(); + $wpFa->idHesabix = $hesabixCode; + $wpFa->idWp = $woocommerceCode; + $wpFa->idWpAttribute = $attributeId; + $wpFa->objType = 'product'; + $wpFaService->save($wpFa); + HesabixLogService::log(array("Item successfully added. Hesabix code: " . (string)$hesabixCode . ". Product ID: $woocommerceCode - $attributeId")); + return true; + } + } else { + HesabixLogService::log(array("Error in saving product to hesabix. Hesabix given code: " . $hesabixCode)); + return false; + } + } + } + + return false; + } +//========================================================================================================================= + public static function CheckExistenceOfTheProductInHesabix($hesabixCode): bool { + $api = new Ssbhesabix_Api(); + $response = $api->itemGet($hesabixCode); + if($response->Success) { + HesabixLogService::writeLogStr("کالا با کد(" . $hesabixCode . ") در حسابیکس موجود است."); + return true; + } else if($response->ErrorCode == "112") { + return false; + } else { + HesabixLogService::writeLogStr("Error in getting the existence of the product"); + return true; + } + } +//========================================================================================================================= + public static function CheckValidityOfTheProductInWoocommerce($woocommerceCode, $attributeId, $hesabixCode): bool { + //check not exist in link table + $wpFaService = new HesabixWpFaService(); + $code = $wpFaService->getProductCodeByWpId($woocommerceCode, $attributeId); + if ($code) { + HesabixLogService::writeLogStr("این کد حسابیکسی وارد شده به کالای دیگری متصل است." . $code . " - " . $woocommerceCode . " - " . $attributeId); + return false; + } + + //check woocommerce code exists + global $wpdb; + + if($attributeId != 0) $productId = $attributeId; + else $productId = $woocommerceCode; + + $found = $wpdb->get_var( + $wpdb->prepare( + "SELECT COUNT(*) FROM {$wpdb->posts} + WHERE ID = %d", + $productId + ) + ); + + if($found) { + //product is valid + return true; + } else { + HesabixLogService::writeLogStr("product not found in woocommerce. Given product code: " . $woocommerceCode . "-" . $attributeId ); + return false; + } + } +//========================================================================================================================= + function checkNationalCode($NationalCode): void + { + $identicalDigits = ['1111111111', '2222222222', '3333333333', '4444444444', '5555555555', '6666666666', '7777777777', '8888888888', '9999999999']; + + if(strlen($NationalCode) === 10) { + $summation = 0; + $j = 10; + for($i = 0 ; $i < 9 ; $i++) { + $digit = substr($NationalCode, $i, 1); + $temp = $digit * $j; + $j -= 1; + $summation += $temp; + } + $controlDigit = substr($NationalCode, 9, 1); + $retrieve = $summation % 11; + + if(in_array($NationalCode, $identicalDigits) === false) { + if($retrieve < 2) { + if($controlDigit != $retrieve) { + wc_add_notice(__('please enter a valid national code', 'ssbhesabix'), 'error'); + } + } else { + if($controlDigit != (11 - $retrieve)) { + wc_add_notice(__('please enter a valid national code', 'ssbhesabix'), 'error'); + } + } + } + } else { + wc_add_notice(__('please enter a valid national code', 'ssbhesabix'), 'error'); + } + } +//========================================================================================================================= + public function checkNationalCodeWithPhone($nationalCode, $billingPhone): bool { + $api = new Ssbhesabix_Api(); + + $formattedPhoneNumber = $this->convertPersianPhoneDigitsToEnglish($billingPhone); + $formattedPhoneNumber = $this->formatPhoneNumber($formattedPhoneNumber); + + $response = $api->checkMobileAndNationalCode($nationalCode, $formattedPhoneNumber); + if($response->Success) { + if($response->Result->Status == 1) { + return $response->Result->Data->Matched; + } else { + return false; + } + } else { + HesabixLogService::writeLogStr('Error Occurred in Checking Mobile and NationalCode. ErrorCode: ' . $response->ErrorCode . " - ErrorMessage: " . $response->ErrorMessage); + return false; + } + } +//========================================================================================================================= + function checkWebsite($Website): void + { + if (filter_var($Website, FILTER_VALIDATE_URL)) { + // + } else { + wc_add_notice(__('please enter a valid Website URL', 'ssbhesabix'), 'error'); + } + } +//========================================================================================================================= + public static function enableDebugMode(): void { + update_option('ssbhesabix_debug_mode', 1); + } + + public static function disableDebugMode(): void { + update_option('ssbhesabix_debug_mode', 0); + } +//========================================================================================================================= + function formatPhoneNumber($phoneNumber) { + $phoneNumber = preg_replace('/\D/', '', $phoneNumber); + + if (substr($phoneNumber, 0, 2) == '98') { + $phoneNumber = substr($phoneNumber, 2); + } + + if (substr($phoneNumber, 0, 1) == '9' && strlen($phoneNumber) == 10) { + $phoneNumber = '0' . $phoneNumber; + } + + if (strlen($phoneNumber) == 10 && substr($phoneNumber, 0, 1) == '9') { + $phoneNumber = '0' . $phoneNumber; + } + + return $phoneNumber; + } +//========================================================================================================================= + public function convertPersianPhoneDigitsToEnglish($inputString) : string { + $newNumbers = range(0, 9); + $persianDecimal = array('۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'); + $arabicDecimal = array('٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'); + $arabic = array('٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'); + $persian = array('۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'); + + $string = str_replace($persianDecimal, $newNumbers, $inputString); + $string = str_replace($arabicDecimal, $newNumbers, $string); + $string = str_replace($persian, $newNumbers, $string); + + return str_replace($arabic, $newNumbers, $string); + } +//========================================================================================================================= + public function convertPersianDigitsToEnglish($inputString) : int { + $newNumbers = range(0, 9); + $persianDecimal = array('۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'); + $arabicDecimal = array('٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'); + $arabic = array('٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'); + $persian = array('۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'); + + $string = str_replace($persianDecimal, $newNumbers, $inputString); + $string = str_replace($arabicDecimal, $newNumbers, $string); + $string = str_replace($persian, $newNumbers, $string); + + return str_replace($arabic, $newNumbers, $string); + } +//========================================================================================================================= + function generateGUID() : string { + $characters = '0123456789ABCDEF'; + $guid = ''; + + for ($i = 0; $i < 32; $i++) { + $guid .= $characters[mt_rand(0, 15)]; + if ($i == 7 || $i == 11 || $i == 15 || $i == 19) { + $guid .= '-'; + } + } + + return $guid; + } +//========================================================================================================================= + public function getGUID($id_order): string { + $option = get_option($id_order); + + if ($option === false || $option == 0) { + $GUID = $this->generateGUID(); + $expirationDateTime = new DateTime('now', new DateTimeZone('UTC')); + add_option($id_order, $expirationDateTime->format('Y-m-d H:i:s') . $GUID); + } else { + $expirationDateTime = new DateTime(substr($option, 0, 19), new DateTimeZone('UTC')); + $currentDateTime = new DateTime('now', new DateTimeZone('UTC')); + + $diff = $currentDateTime->diff($expirationDateTime); + + if ($diff->days < 1) { + // GUID is still valid, continue processing + } else { + // GUID expired, reset the option to allow saving a new invoice + $GUID = $this->generateGUID(); + $expirationDateTime = new DateTime('now', new DateTimeZone('UTC')); + update_option($id_order, $expirationDateTime->format('Y-m-d H:i:s') . $GUID); + } + } + + return substr(get_option($id_order), 20); + } +//========================================================================================================================= + public function formatTransactionFee($transactionFee, $amount) { + if($transactionFee && $transactionFee > 0) { + $func = new Ssbhesabix_Admin_Functions(); + $transactionFee = $func->convertPersianDigitsToEnglish($transactionFee); + + if($transactionFee<100 && $transactionFee>0) $transactionFee /= 100; + $transactionFee *= $amount; + if($transactionFee < 1) $transactionFee = 0; + } + return $transactionFee; + } +//========================================================================================================================= + public function convertCityCodeToName($cityCode) { + $citiesArray = [ + 1 => [ + 'title' => 'تهران', + 'cities' => [ + 1 => 'تهران', + 331 => 'اسلام شهر', + 1813 => 'ری', + 3341 => 'لواسان', + 3351 => 'شهریار', + 3371 => 'ورامین', + 3381 => 'پیشوا', + 3391 => 'پاکدشت', + 3751 => 'قدس', + 3761 => 'رباطکریم', + 3971 => 'دماوند', + 3981 => 'فیروزکوه', + 16531 => 'جاجرود (خسروآباد)', + 16551 => 'بومهن', + 16571 => 'شهرصنعتی خرمدشت', + 16581 => 'پردیس', + 18131 => 'باقر شهر', + 18141 => 'جعفرابادباقراف', + 18151 => 'مرقدامام ره', + 18161 => 'کهریزک', + 18171 => 'طورقوزاباد', + 18181 => 'قاسم ابادشوراباد', + 18191 => 'قمصر', + 18331 => 'حسن آباد', + 18341 => 'شمس اباد', + 18351 => 'ابراهیم اباد', + 18361 => 'چرمشهر', + 18371 => 'قلعه محمدعلی خان', + 18381 => 'فرودگاه امام خمینی', + 18391 => 'وهن اباد', + 18441 => 'قلعه نوخالصه', + 18451 => 'گل تپه کبیر', + 18461 => 'محمودابادپیرزاده', + 18471 => 'فرون اباد', + 18631 => 'خاورشهر', + 18641 => 'اسلام اباد', + 18651 => 'لپه زنگ', + 18661 => 'قیامدشت', + 18686 => 'قرچک', + 18791 => 'قوچ حصار', + 18986 => 'خلازیر', + 19338 => 'تجریش', + 31130 => 'نصیرشهر', + 31133 => 'شهرک صنعتی نصیرشهر', + 31136 => 'شهرک قلعه میر', + 31641 => 'صفادشت', + 31686 => 'اندیشه', + 31691 => 'ملارد', + 31694 => 'گرمدره', + 33131 => 'احمدابادمستوفی', + 33141 => 'فیروزبهرام', + 33151 => 'گلدسته', + 33171 => 'صالح آباد', + 33186 => 'شاطره', + 33191 => 'چهاردانگه', + 33361 => 'سعیدآباد', + 33451 => 'فشم', + 33461 => 'لواسان بزرگ', + 33541 => 'باغستان', + 33560 => 'صباشهر', + 33561 => 'شاهدشهر', + 33571 => 'فردوسیه', + 33581 => 'وحیدیه', + 33591 => 'لم اباد', + 33711 => 'قلعه سین', + 33741 => 'عسگرابادعباسی', + 33751 => 'دهماسین', + 33761 => 'باغخواص', + 33771 => 'ایجدان', + 33781 => 'ابباریک', + 33831 => 'جواد آباد', + 33841 => 'خاوه', + 33861 => 'جلیل اباد', + 33871 => 'کریم اباد', + 33881 => 'قلعه خواجه', + 33930 => 'شهرک عباس آباد', + 33931 => 'داوداباد', + 33941 => 'شریف آباد', + 33971 => 'پارچین', + 33981 => 'حصارامیر', + 33991 => 'خاتون اباد', + 37551 => 'نصیرآباد', + 37571 => 'گلستان', + 37581 => 'کلمه', + 37611 => 'پرند', + 37614 => 'شهر صنعتی پرند', + 37631 => 'سلطان اباد', + 37650 => 'حصارک پایین', + 37651 => 'نسیم شهر', + 37652 => 'حصارک بالا', + 37653 => 'سبزدشت', + 37656 => 'احمدآبادجانسپار', + 37661 => 'اسماعیل آباد', + 39720 => 'جابان', + 39731 => 'رودهن', + 39741 => 'آبعلی', + 39751 => 'کیلان', + 39761 => 'آبسرد', + 39771 => 'سربندان', + 39780 => 'مهرآباد', + 39781 => 'مشا', + 39791 => 'مرا', + 39811 => 'هرانده', + 39831 => 'درده', + 39841 => 'حصاربن', + 39851 => 'ارجمند', + 39861 => 'امیریه', + ], + ], + 2 => [ + 'title' => 'گيلان', + 'cities' => [ + 41 => 'رشت', + 431 => 'بندرانزلی', + 441 => 'لاهیجان', + 4331 => 'ابکنار', + 4341 => 'خمام', + 4351 => 'فومن', + 4361 => 'صومعه سرا', + 4371 => 'هشتپر', + 4381 => 'ماسال', + 4391 => 'آستارا', + 4431 => 'سیاهکل', + 4441 => 'آستانه اشرفیه', + 4451 => 'منجیل', + 4461 => 'رودبار', + 4471 => 'لنگرود', + 4481 => 'رودسر', + 4491 => 'کلاچای', + 43331 => 'کپورچال', + 43341 => 'جیرهنده', + 43351 => 'لیچارکی حسن رود', + 43361 => 'سنگر', + 43381 => 'سراوان', + 43391 => 'خشکبیجار', + 43431 => 'لشت نشاء', + 43451 => 'خواچکین', + 43461 => 'کوچصفهان', + 43471 => 'بلسبنه', + 43481 => 'چاپارخانه', + 43491 => 'جیرکویه', + 43513 => 'ماکلوان', + 43531 => 'لولمان', + 43541 => 'شفت', + 43551 => 'ملاسرا', + 43561 => 'چوبر', + 43571 => 'ماسوله', + 43581 => 'گشت', + 43591 => 'احمد سر گوراب', + 43631 => 'مرجقل', + 43641 => 'گوراب زرمیخ', + 43651 => 'طاهرگوراب', + 43661 => 'ضیابر', + 43671 => 'مرکیه', + 43681 => 'هنده خاله', + 43691 => 'نوخاله اکبری', + 43741 => 'شیله وشت', + 43751 => 'جوکندان بزرگ', + 43761 => 'لیسار', + 43771 => 'بازارخطبه سرا', + 43780 => 'چوبر', + 43781 => 'حویق', + 43791 => 'پلاسی', + 43811 => 'بازار جمعه', + 43841 => 'رضوانشهر', + 43861 => 'پره سر', + 43871 => 'پلنگ پاره', + 43891 => 'اسالم', + 43931 => 'شیخ محله', + 43941 => 'ویرمونی', + 43951 => 'سیبلی', + 43961 => 'لوندویل', + 43971 => 'مشند', + 43981 => 'کوته کومه', + 43991 => 'حیران', + 44141 => 'رودبنه', + 44331 => 'پایین محله پاشاکی', + 44341 => 'گرماور', + 44351 => 'لیش', + 44361 => 'بارکوسرا', + 44371 => 'شیرین نسا', + 44381 => 'خرارود', + 44391 => 'دیلمان', + 44431 => 'لسکوکلایه', + 44441 => 'کیسم', + 44451 => 'شیرکوه چهارده', + 44461 => 'دهشال', + 44471 => 'کیاشهر', + 44481 => 'دستک', + 44491 => 'پرگاپشت مهدی خانی', + 44531 => 'لوشان', + 44541 => 'بیورزین', + 44551 => 'جیرنده', + 44561 => 'بره سر', + 44581 => 'ویشان', + 44591 => 'کلیشم', + 44631 => 'علی اباد', + 44641 => 'رستم آباد', + 44651 => 'توتکابن', + 44661 => 'کلشتر', + 44681 => 'اسکولک', + 44691 => 'کوکنه', + 44731 => 'سلوش', + 44741 => 'چاف وچمخاله', + 44751 => 'شلمان', + 44761 => 'کومله', + 44771 => 'دیوشل', + 44781 => 'پروش پایین', + 44791 => 'اطاقور', + 44841 => 'حسن سرا', + 44851 => 'طول لات', + 44861 => 'رانکوه', + 44871 => 'چابکسر', + 44881 => 'جنگ سرا', + 44891 => 'واجارگاه', + 44931 => 'رحیم آباد', + 44941 => 'بلترک', + 44951 => 'املش', + 44971 => 'کجید', + 44981 => 'گرمابدشت', + 44991 => 'شوییل', + 44992 => 'پونل', + ], + ], + 3 => [ + 'title' => 'آذربايجان شرقي', + 'cities' => [ + 51 => 'تبریز', + 531 => 'میانه', + 541 => 'مرند', + 551 => 'مراغه', + 5331 => 'شهرجدیدسهند', + 5351 => 'اسکو', + 5361 => 'سردرود', + 5371 => 'آذر شهر', + 5381 => 'شبستر', + 5391 => 'هریس', + 5431 => 'هادیشهر', + 5441 => 'جلفا', + 5451 => 'اهر', + 5461 => 'کلیبر', + 5471 => 'سراب', + 5491 => 'بستان آباد', + 5541 => 'عجب شیر', + 5551 => 'بناب', + 5561 => 'ملکان', + 5571 => 'هشترود', + 5581 => 'قره آغاج', + 5586 => 'اغچه ریش', + 53331 => 'ترک', + 53351 => 'ترکمانچای', + 53361 => 'خاتون اباد', + 53371 => 'شیخدراباد', + 53381 => 'قره بلاغ', + 53391 => 'آقکند', + 53431 => 'اچاچی', + 53441 => 'گوندوغدی', + 53451 => 'پورسخلو', + 53461 => 'کنگاور', + 53481 => 'قویوجاق', + 53491 => 'ارموداق', + 53531 => 'کهنمو', + 53541 => 'اربط', + 53551 => 'خسرو شهر', + 53561 => 'لاهیجان', + 53571 => 'خاص اباد (خاصبان)', + 53581 => 'ایلخچی', + 53591 => 'سرای (سرای ده)', + 53631 => 'کجوار', + 53641 => 'خلجان', + 53651 => '(ینگی اسپران (سفیدان جد', + 53661 => 'باسمنج', + 53671 => '(شادبادمشایخ (پینه شلوا', + 53681 => 'کندرود', + 53691 => 'مایان سفلی', + 53731 => 'تیمورلو', + 53740 => 'خراجو', + 53741 => 'قدمگاه (بادام یار)', + 53751 => 'ممقان', + 53761 => 'گوگان', + 53771 => 'شیرامین', + 53791 => 'هفت چشمه', + 53811 => 'وایقان', + 53831 => 'امند', + 53840 => 'کوزه کنان', + 53841 => 'خامنه', + 53851 => 'سیس', + 53861 => 'صوفیان', + 53871 => 'شند آباد', + 53881 => 'تسوج', + 53891 => 'شرفخانه', + 53941 => 'مینق', + 53950 => 'کلوانق', + 53951 => 'بخشایش', + 53961 => 'سرند', + 53971 => 'زرنق', + 53981 => 'بیلوردی', + 53991 => 'خواجه', + 54331 => 'گلین قیه', + 54341 => 'هرزندجدید (چای هرزند)', + 54351 => 'بناب جدید', + 54361 => 'زنوز', + 54371 => 'دولت اباد', + 54381 => 'یکان کهریز', + 54391 => 'یامچی', + 54431 => 'شجاع', + 54441 => 'داران', + 54451 => 'سیه رود', + 54461 => 'نوجه مهر', + 54471 => 'کشکسرای', + 54481 => 'خاروانا', + 54491 => 'هوراند', + 54531 => 'چول قشلاقی', + 54541 => 'ورگهان', + 54551 => 'افیل', + 54561 => 'اذغان (ازغان)', + 54571 => 'سیه کلان', + 54581 => 'ورزقان', + 54591 => 'اق براز', + 54631 => 'مولان', + 54641 => 'خمارلو', + 54651 => 'عاشقلو', + 54661 => 'اسکلو (اسگلو)', + 54671 => 'آبش احمد', + 54681 => 'یوزبند', + 54682 => 'شهرک صنعتی کاغذکنان', + 54685 => 'کندوان', + 54686 => 'تیل', + 54691 => 'لاریجان', + 54731 => 'اسبفروشان', + 54741 => 'ابرغان', + 54750 => 'دوزدوزان', + 54751 => 'شربیان', + 54761 => 'مهربان', + 54771 => 'رازلیق', + 54781 => 'اغمیون', + 54791 => 'اردها', + 54931 => 'قره چای حاج علی', + 54941 => 'قره بابا', + 54951 => 'سعیداباد', + 54961 => 'الانق', + 54971 => 'کردکندی', + 54981 => 'تیکمه داش', + 54991 => 'قره چمن', + 55330 => 'ورجوی', + 55341 => 'گل تپه', + 55351 => 'خداجو', + 55361 => 'داش اتان', + 55371 => 'داش بلاغ بازار', + 55381 => 'صومعه', + 55391 => 'علویان', + 55431 => 'شیراز', + 55441 => 'خضرلو', + 55451 => 'ینگجه', + 55461 => 'مهماندار', + 55471 => 'خانیان', + 55481 => 'دانالو', + 55491 => 'رحمانلو', + 55531 => 'زاوشت', + 55541 => 'القو', + 55551 => 'روشت بزرگ', + 55561 => 'خوشه مهر (خواجه امیر)', + 55571 => 'زوارق', + 55581 => '(خانه برق قدیم (شورخانه ب', + 55631 => 'لکلر', + 55641 => 'بایقوت', + 55651 => 'اروق', + 55661 => 'اق منار', + 55671 => 'لیلان', + 55681 => 'طوراغای (طوراغایی)', + 55731 => 'اوشندل', + 55741 => 'علی ابادعلیا', + 55751 => 'ذوالبین', + 55761 => 'نظر کهریزی', + 55771 => 'اتش بیگ', + 55781 => 'سلوک', + 55791 => 'نصیرابادسفلی', + 55831 => 'ارسگنای سفلی', + 55841 => '(سلطان اباد (س انمکزار', + 55851 => 'قلعه حسین اباد', + 55871 => 'ذاکرکندی', + 55881 => 'قوچ احمد', + 55891 => 'اغ زیارت', + ], + ], + 4 => [ + 'title' => 'خوزستان', + 'cities' => [ + 61 => 'اهواز', + 631 => 'آبادان', + 641 => 'خرمشهر', + 6331 => 'اروندکنار', + 6341 => 'ملاثانی', + 6351 => 'بندرماهشهر', + 6361 => 'بهبهان', + 6371 => 'آغاجاری', + 6381 => 'رامهرمز', + 6391 => 'ایذه', + 6431 => 'شادگان', + 6441 => 'سوسنگرد', + 6451 => 'شوشتر', + 6461 => 'دزفول', + 6471 => 'شوش', + 6481 => 'اندیمشک', + 6491 => 'مسجدسلیمان', + 61431 => 'الهائی', + 61481 => 'شیبان', + 61491 => 'ویس', + 63331 => 'فیاضی', + 63341 => 'تنگ یک', + 63351 => 'چوئبده', + 63361 => 'نهرسلیم', + 63381 => 'نهرابطر', + 63431 => 'عین دو', + 63441 => 'حمیدیه', + 63451 => 'ام الطمیر (سیدیوسف)', + 63461 => 'کوت عبدالله', + 63471 => 'قلعه چنعان', + 63481 => 'کریت برومی', + 63491 => 'غیزانیه بزرگ', + 63531 => 'چم کلگه', + 63541 => 'چمران', + 63561 => 'بندرامام خمینی', + 63571 => 'صالح شهر', + 63581 => 'اسیاب', + 63591 => 'هندیجان', + 63640 => 'تشان', + 63641 => 'گروه پدافندهوایی بهبها', + 63651 => 'شاه غالب ده ابراهیم', + 63661 => 'کردستان بزرگ', + 63671 => 'منصوریه', + 63681 => 'سردشت', + 63731 => 'امیدیه', + 63751 => 'میانکوه', + 63771 => 'زهره', + 63831 => 'رودزرد', + 63851 => 'نفت سفید', + 63861 => 'مشراگه', + 63871 => 'رامشیر', + 63881 => 'جایزان', + 63891 => 'دره تونم نمی', + 63931 => 'میداود', + 63941 => 'صیدون', + 63951 => 'باغ ملک', + 63961 => 'قلعه تل', + 63971 => 'چنارستان', + 63981 => 'پشت پیان', + 63991 => 'دهدز', + 64330 => 'خنافره', + 64331 => 'عبودی', + 64341 => 'دارخوین', + 64351 => 'درویشی', + 64361 => 'بوزی سیف', + 64371 => 'مینوشهر', + 64381 => 'حفاری شرقی', + 64431 => 'بروایه یوسف', + 64440 => 'کوت سیدنعیم', + 64441 => 'ابوحمیظه', + 64451 => 'هویزه', + 64461 => 'یزدنو', + 64471 => 'رفیع', + 64481 => 'بستان', + 64491 => 'سیدعباس', + 64510 => 'سرداران', + 64511 => 'شرافت', + 64531 => 'گوریه', + 64541 => 'جنت مکان', + 64551 => 'گتوند', + 64560 => 'ترکالکی', + 64561 => 'سماله', + 64571 => 'شهرک نورمحمدی', + 64581 => 'گاومیش اباد', + 64591 => 'عرب حسن', + 64631 => 'صفی آباد', + 64640 => 'چغامیش', + 64641 => 'حمزه', + 64650 => 'شمس آباد', + 64651 => 'امام', + 64652 => 'سیاه منصور', + 64661 => 'میانرود', + 64681 => 'چلون', + 64691 => 'سالند', + 64730 => 'حر', + 64731 => 'شاوور', + 64741 => 'مزرعه یک', + 64751 => 'خسرجی راضی حمد', + 64761 => 'الوان', + 64771 => 'علمه تیمورابوذرغفاری', + 64781 => 'شهرک بهرام', + 64791 => 'فتح المبین', + 64830 => 'آزادی', + 64831 => 'شهرک انصار', + 64841 => 'خواجوی', + 64850 => 'بیدروبه', + 64851 => 'حسینیه', + 64861 => 'کلگه دره دو', + 64871 => 'تله زنگ پایین', + 64881 => 'چم گلک', + 64931 => 'روستای عنبر', + 64941 => 'لالی', + 64951 => 'دره بوری', + 64961 => 'هفتگل', + 64971 => 'کوشکک', + 64980 => 'آبژدان', + 64981 => 'قلعه خواجه', + 64991 => 'گلگیر', + ], + ], + 5 => [ + 'title' => 'فارس', + 'cities' => [ + 71 => 'شیراز', + 731 => 'کازرون', + 741 => 'جهرم', + 7331 => 'قائمیه', + 7341 => 'زرقان', + 7351 => 'نور آباد', + 7361 => 'اردکان', + 7371 => 'مرودشت', + 7381 => 'اقلید', + 7391 => 'آباده', + 7431 => 'لار', + 7441 => 'گراش', + 7451 => 'استهبان', + 7461 => 'فسا', + 7471 => 'فیروز آباد', + 7481 => 'داراب', + 7491 => 'نی ریز', + 71431 => 'بندامیر', + 71451 => 'خیرابادتوللی', + 71461 => 'داریان', + 71491 => 'کم جان', + 71551 => 'شوریجه', + 71561 => 'مهارلو', + 71571 => 'کوهنجان', + 71581 => 'سلطان آباد', + 71591 => 'تفیهان', + 71641 => 'طسوج', + 71651 => 'اکبراباد', + 71661 => 'مظفری', + 71671 => 'کوشک بیدک', + 71681 => 'فتح اباد', + 71691 => 'ده شیب', + 71741 => 'خانه زنیان', + 71781 => 'پاسگاه چنارراهدار', + 71881 => 'موردراز', + 71991 => 'شهرجدیدصدرا', + 73131 => 'کلاتون', + 73141 => 'کلانی', + 73151 => 'کمارج مرکزی', + 73161 => 'مهبودی علیا', + 73171 => 'وراوی', + 73311 => 'حکیم باشی نصف میان (بالا)', + 73331 => 'کنار تخته', + 73341 => 'خشت', + 73351 => 'انارستان', + 73361 => 'نودان', + 73371 => 'مهرنجان', + 73381 => 'جره', + 73391 => 'بالاده', + 73411 => 'لپوئی', + 73431 => 'کامفیروز', + 73441 => 'خرامه', + 73451 => 'سروستان', + 73461 => 'کوار', + 73471 => 'رامجرد', + 73491 => 'گویم', + 73511 => 'خومه زار', + 73531 => 'بابامنیر', + 73541 => 'اهنگری', + 73551 => 'پرین', + 73560 => 'کوپن', + 73561 => 'حسین ابادرستم', + 73571 => 'مصیری', + 73591 => 'میشان سفلی', + 73611 => 'بهرغان', + 73631 => 'بیضا', + 73641 => 'هماشهر', + 73651 => 'کمهر', + 73661 => 'راشک علیا', + 73671 => 'هرایجان', + 73681 => 'بانش', + 73711 => 'کوشک', + 73731 => 'خانیمن', + 73741 => 'سعادت شهر', + 73751 => 'قادرآباد', + 73761 => 'ارسنجان', + 73771 => 'سیدان', + 73791 => 'کوشکک', + 73810 => 'مزایجان', + 73811 => 'خنجشت', + 73831 => 'امامزاده اسماعیل', + 73840 => 'مادرسلیمان', + 73841 => 'حسن آباد', + 73851 => 'اسپاس', + 73861 => 'سده', + 73881 => 'دژکرد', + 73891 => 'شهرمیان', + 73911 => 'بهمن', + 73931 => 'صغاد', + 73940 => 'حسامی', + 73941 => 'بوانات', + 73942 => 'کره ای', + 73951 => 'صفاشهر', + 73981 => 'سورمق', + 73991 => 'ایزدخواست', + 74110 => 'دوزه', + 74161 => 'بندبست', + 74171 => 'باب انار', + 74311 => 'فیشور', + 74331 => 'اوز', + 74341 => 'لامرد', + 74351 => 'جویم', + 74361 => 'بنارویه', + 74370 => 'خور', + 74371 => 'لطیفی', + 74380 => 'عمادده', + 74381 => 'بیرم', + 74390 => 'اهل', + 74391 => 'اشکنان', + 74410 => 'اسیر', + 74411 => 'کهنه', + 74414 => 'خوزی', + 74431 => 'خنج', + 74441 => 'علامرودشت', + 74450 => 'گله دار', + 74451 => 'مهر', + 74461 => 'رونیز', + 74471 => 'بنوان', + 74481 => 'ایج', + 74491 => 'درب قلعه', + 74541 => 'خاوران', + 74551 => 'قطب آباد', + 74561 => 'دنیان', + 74571 => 'سروو', + 74581 => 'مانیان', + 74591 => 'به جان', + 74611 => 'کوشک قاضی', + 74641 => 'نوبندگان', + 74650 => 'قره بلاغ', + 74651 => 'ششده', + 74661 => 'قاسم ابادسفلی', + 74671 => 'زاهدشهر', + 74681 => 'میانده', + 74691 => 'صحرارود', + 74711 => 'بایگان', + 74714 => 'امام شهر', + 74731 => 'مبارک آباد', + 74741 => 'میمند', + 74751 => 'افزر', + 74760 => 'قیر', + 74761 => 'کارزین', + 74771 => 'فراشبند', + 74780 => 'نوجین', + 74781 => 'دهرم', + 74791 => 'جوکان', + 74811 => 'مادوان', + 74814 => 'دبیران', + 74831 => 'ماه سالاری', + 74841 => 'رستاق', + 74850 => 'شهرپیر', + 74861 => 'حاجی آباد', + 74871 => 'فدامی', + 74880 => 'دوبرجی', + 74881 => 'چمن مروارید', + 74891 => 'جنت شهر', + 74911 => 'لای حنا', + 74931 => 'آباده طشک', + 74941 => 'قطاربنه', + 74971 => 'مشکان', + 74981 => 'قطرویه', + 74991 => 'هرگان', + ], + ], + 6 => [ + 'title' => 'اصفهان', + 'cities' => [ + 81 => 'اصفهان', + 831 => 'شاهین شهر', + 841 => 'خمینی شهر', + 851 => 'نجف آباد', + 861 => 'شهرضا', + 871 => 'کاشان', + 8161 => 'منطقه صنعتی محموداباد', + 8331 => 'مورچه خورت', + 8341 => 'دولت آباد', + 8351 => 'میمه', + 8361 => 'خور', + 8371 => 'کوهپایه', + 8381 => 'اردستان', + 8391 => 'نائین', + 8431 => 'درچه پیاز', + 8441 => 'زواره', + 8451 => 'فلاورجان', + 8461 => 'قهدریجان', + 8471 => 'زرین شهر', + 8481 => 'مبارکه', + 8491 => 'فولادشهر', + 8531 => 'تیران', + 8541 => 'دهق', + 8551 => 'علویجه', + 8561 => 'داران', + 8571 => 'چادگان', + 8591 => 'فریدونشهر', + 8641 => 'دهاقان', + 8651 => 'اسفرجان', + 8661 => 'سمیرم', + 8671 => 'حنا', + 8681 => 'مهرگرد', + 8731 => 'جوشقان استرک', + 8741 => 'آران و بیدگل', + 8751 => 'قمصر', + 8761 => 'نطنز', + 8771 => 'گلپایگان', + 8781 => 'گوگد', + 8791 => 'خوانسار', + 81351 => 'تودشک', + 81391 => 'سگزی', + 81431 => 'بهارستان', + 81561 => 'خوراسگان', + 81594 => 'گورت', + 81671 => 'دستجا', + 81681 => 'زیار', + 81751 => 'نصرآباد', + 81789 => 'ابریشم', + 81799 => 'اصفهان (سپاهان شهر)', + 83341 => 'پادگان اموزشی امام ص', + 83351 => 'پالایشگاه اصفهان', + 83361 => 'کلهرود', + 83371 => 'گرگاب', + 83431 => 'دستگرد', + 83441 => 'گز برخوار', + 83451 => 'خورزوق', + 83461 => 'حبیب آباد', + 83531 => 'موته', + 83541 => 'وزوان', + 83551 => 'لای بید', + 83561 => 'رباطاقاکمال', + 83581 => 'خسرواباد', + 83591 => 'کمشچه', + 83631 => 'جندق', + 83641 => 'فرخی', + 83651 => 'مزیک', + 83661 => 'مهرجان', + 83671 => 'بیاضه', + 83681 => 'چوپانان', + 83691 => 'بلان', + 83731 => 'محمدآباد', + 83741 => 'هرند', + 83751 => 'ورزنه', + 83761 => 'قهجاورستان', + 83771 => 'نیک آباد', + 83781 => 'اژیه', + 83791 => 'حسن اباد', + 83831 => 'کچومثقال', + 83841 => 'ظفرقند', + 83851 => 'نهوج', + 83861 => 'نیسیان', + 83871 => 'ومکان', + 83881 => 'همسار', + 83891 => 'فسخود', + 83931 => 'فوداز', + 83941 => 'اشکستان', + 83951 => 'کجان', + 83961 => 'نیستانک', + 83971 => 'انارک', + 83991 => 'بافران', + 84331 => 'تیرانچی', + 84341 => 'کوشک', + 84371 => 'قلعه امیریه', + 84431 => 'مهاباد', + 84441 => 'درقه', + 84451 => 'شهراب', + 84461 => 'تورزن', + 84471 => 'کریم اباد', + 84481 => 'تلک اباد', + 84491 => 'موغار', + 84531 => 'خوانسارک', + 84541 => 'پیربکران', + 84561 => 'کلیشادوسودرجان', + 84581 => 'کرسگان', + 84591 => 'بهاران شهر', + 84631 => 'سهروفیروزان', + 84651 => 'ایمانشهر', + 84671 => 'زازران', + 84681 => 'شرودان', + 84691 => 'جوجیل', + 84731 => 'ورنامخواست', + 84741 => 'سده لنجان', + 84751 => 'چرمهین', + 84761 => 'باغ بهادران', + 84771 => 'نوگوران', + 84781 => 'چمگردان', + 84791 => 'کرچگان', + 84831 => 'دیزیچه', + 84841 => 'زیباشهر', + 84851 => 'باغ ملک', + 84861 => 'دهسرخ', + 84871 => 'پلی اکریل', + 84881 => 'فولادمبارکه', + 84891 => 'کرکوند', + 84931 => 'زاینده رود', + 84951 => 'چم نور', + 84961 => 'کچوییه', + 84971 => 'اشیان', + 84981 => 'طالخونچه', + 84991 => 'تاسیسات سدنکواباد', + 85331 => 'رضوانشهر', + 85341 => 'ورپشت', + 85351 => 'عسگران', + 85371 => 'عزیزاباد', + 85381 => 'میراباد', + 85391 => 'حاجی اباد', + 85441 => 'خیراباد', + 85451 => 'اشن', + 85471 => 'خونداب', + 85531 => 'حسین اباد', + 85631 => 'غرغن', + 85641 => 'دامنه', + 85651 => 'بوئین و میاندشت', + 85661 => 'زرنه', + 85671 => 'بلطاق', + 85681 => 'کرچ', + 85691 => 'قره بلطاق', + 85711 => 'افوس', + 85731 => 'سازمان عمران زاینده رود', + 85741 => 'مشهدکاوه', + 85751 => 'اسکندری', + 85761 => 'رزوه', + 85771 => 'نهرخلج', + 85781 => 'چاه غلامرضارحیمی', + 85791 => 'اورگان', + 85831 => 'گلدشت', + 85851 => 'جوزدان', + 85861 => 'کهریزسنگ', + 85931 => 'نهضت اباد', + 85941 => 'قلعه سرخ', + 85961 => 'اسلام ابادموگویی', + 85971 => 'مصیر', + 85991 => 'برف انبار', + 86331 => 'قمشلو', + 86341 => 'پوده', + 86351 => 'مهیار', + 86361 => 'پرزان', + 86371 => 'منوچهراباد', + 86391 => 'شهرک صنایع شیمیایی ر', + 86431 => 'همگین', + 86451 => 'گلشن', + 86461 => 'کهرویه', + 86471 => 'قصرچم', + 86531 => 'امین اباد', + 86541 => 'مقصودبیک', + 86551 => 'سولار', + 86561 => 'منظریه', + 86631 => 'گرموک', + 86651 => 'هست', + 86671 => 'ونک', + 86751 => 'کهنگان', + 86771 => 'کمه', + 86781 => 'مورک', + 86791 => 'چهارراه', + 86831 => 'ده نسا سفلی', + 86841 => 'اغداش', + 86851 => 'چشمه رحمان', + 86861 => 'ورق', + 86881 => 'سعادت اباد', + 86891 => 'فتح اباد', + 87181 => 'نیاسر', + 87331 => 'سن سن', + 87351 => 'ده زیره', + 87361 => 'رحق', + 87371 => 'اب شیرین', + 87381 => 'نشلج', + 87391 => 'مشکات', + 87431 => 'سفیدشهر', + 87441 => 'مزرعه صدر', + 87461 => 'نوش آباد', + 87481 => 'ابوزیدآباد', + 87491 => 'کاغذی', + 87541 => 'قهرود', + 87551 => 'جوشقان و کامو', + 87561 => 'برزک', + 87571 => 'اسحق اباد', + 87581 => 'وادقان', + 87591 => 'اذان', + 87631 => 'طرق رود', + 87641 => 'اریسمان', + 87651 => 'ابیانه', + 87661 => 'بادرود', + 87671 => 'خالدآ باد', + 87681 => 'اوره', + 87731 => 'ملازجان', + 87741 => 'سعیداباد', + 87751 => 'مرغ', + 87771 => 'قرغن', + 87781 => 'کوچری', + 87831 => 'کلوچان', + 87841 => 'گلشهر', + 87861 => 'زرنجان', + 87871 => 'وانشان', + 87881 => 'تیکن', + 87931 => 'سنگ سفید', + 87941 => 'رحمت اباد', + 87951 => 'خم پیچ', + 87961 => 'مهراباد', + 87971 => 'تیدجان', + 87981 => 'خشکرود', + 87991 => 'ویست', + ], + ], + 7 => [ + 'title' => 'خراسان رضوي', + 'cities' => [ + 91 => 'مشهد', + 931 => 'نیشابور', + 951 => 'تربت حیدریه', + 961 => 'سبزوار', + 9331 => 'فیروزه', + 9341 => 'درود', + 9351 => 'طرقبه', + 9361 => 'چناران', + 9371 => 'کلات', + 9381 => 'سرخس', + 9391 => 'فریمان', + 9471 => 'قوچان', + 9491 => 'درگز', + 9531 => 'فیض آباد', + 9541 => 'رشتخوار', + 9551 => 'کدکن', + 9561 => 'خواف', + 9571 => 'تربت جام', + 9581 => 'صالح آباد', + 9591 => 'تایباد', + 9631 => 'داورزن', + 9641 => 'جغتای', + 9651 => 'ششتمد', + 9671 => 'کاشمر', + 9681 => 'بردسکن', + 9691 => 'گناباد', + 91671 => 'رضویه', + 93161 => 'همت آباد', + 93331 => 'شوراب', + 93341 => 'گلبوی پایین', + 93351 => 'مبارکه', + 93361 => 'چکنه', + 93371 => 'برزنون', + 93381 => 'فدیشه', + 93391 => 'بار', + 93431 => 'میراباد', + 93441 => 'فرخک', + 93451 => 'خرو', + 93461 => 'قدمگاه', + 93471 => 'اسحق اباد', + 93481 => 'خوجان', + 93491 => 'عشق آباد', + 93541 => 'ملک آباد', + 93551 => 'کورده', + 93561 => 'شاندیز', + 93571 => 'طوس سفلی', + 93581 => 'قرقی سفلی (شهیدکاوه)', + 93591 => 'کنه بیست', + 93631 => 'رادکان', + 93641 => 'سیداباد', + 93651 => 'گلبهار', + 93661 => 'سلوگرد', + 93671 => 'ارداک', + 93681 => 'بقمج', + 93691 => 'گلمکان', + 93741 => 'میامی', + 93751 => 'چاهک', + 93761 => 'شهرزو', + 93771 => 'گوش', + 93781 => 'نریمانی سفلی', + 93791 => 'تقی اباد', + 93831 => 'کچولی', + 93841 => 'شیرتپه', + 93851 => 'پس کمر', + 93861 => 'مزدآوند', + 93871 => 'بزنگان', + 93881 => 'گنبدلی', + 93891 => 'کندک لی', + 93931 => 'کته شمشیرسفلی', + ], + ], + 8 => [ + 'title' => 'قزوين', + 'cities' => [ + 341 => 'قزوین', + 3431 => 'الوند', + 3441 => 'آبیک', + 3451 => 'بوئین زهرا', + 3461 => 'آوج', + 3481 => 'تاکستان', + 3491 => 'محمدیه', + 34131 => 'محمودآبادنمونه', + 34151 => 'بیدستان', + 34161 => 'شریفیه', + 34171 => 'اقبالیه', + 34313 => 'نصرت آباد', + 34331 => 'الولک', + 34341 => 'کاکوهستان', + 34351 => 'فلار', + 34381 => 'مینودشت', + 34391 => 'زوارک', + 34431 => 'صمغ اباد', + 34441 => 'ناصراباد', + 34461 => 'رشتقون', + 34471 => 'قشلاق', + 34481 => 'خاکعلی', + 34491 => 'شهرک صنعتی لیا (قدیم)', + 34531 => 'سگز آباد', + 34541 => 'عصمت اباد', + 34551 => 'خرم اباد', + 34561 => 'اسفرورین', + 34571 => 'شال', + 34581 => 'دانسفهان', + 34631 => 'کلنجین', + 34641 => 'آبگرم', + 34651 => 'استبلخ', + 34671 => 'ارداق', + 34681 => 'نیارج', + 34691 => 'حصارولیعصر', + 34731 => 'ماهین', + 34741 => 'سیردان', + 34761 => 'سیاهپوش', + 34781 => 'نیارک', + 34791 => 'اقابابا', + 34811 => 'نرجه', + 34831 => 'خرمدشت', + 34851 => 'ضیاءآباد', + 34871 => 'حسین اباد', + 34891 => 'رحیم اباد', + 34913 => 'مهرگان', + 34931 => 'معلم کلایه', + 34941 => 'یحیی اباد', + 34951 => 'نیکویه', + 34961 => 'رازمیان', + 34971 => 'کوهین', + ], + ], + 9 => [ + 'title' => 'سمنان', + 'cities' => [ + 351 => 'سمنان', + 361 => 'شاهرود', + 3531 => 'علا', + 3541 => 'ابخوری', + 3551 => 'سرخه', + 3561 => 'مهدیشهر', + 3571 => 'شهمیرزاد', + 3581 => 'گرمسار', + 3591 => 'ایوانکی', + 3631 => 'میامی', + 3641 => 'بسطام', + 3651 => 'مجن', + 3661 => 'بیارجمند', + 3671 => 'دامغان', + 3681 => 'امیریه', + 35331 => 'خیراباد', + 35341 => 'ایستگاه میان دره', + 35381 => 'اهوان', + 35431 => 'جام', + 35441 => 'دوزهیر', + 35451 => 'معدن نمک', + 35531 => 'نظامی', + 35541 => 'اسداباد', + 35551 => 'لاسجرد', + 35561 => 'سیداباد', + 35571 => 'عبدالله ابادپایین', + 35581 => 'بیابانک', + 35591 => 'مومن اباد', + 35631 => 'درجزین', + 35641 => 'دربند', + 35651 => 'گل رودبار', + 35661 => 'ابگرم', + 35671 => 'افتر', + 35731 => 'فولادمحله', + 35741 => 'ده صوفیان', + 35751 => 'هیکو', + 35761 => 'چاشم', + 35831 => 'کردوان', + 35841 => 'مندولک', + 35851 => 'داوراباد', + 35861 => 'آرادان', + 35881 => 'بن کوه', + 35891 => 'کهن آباد', + 35931 => 'حسین ابادکوروس', + 35941 => 'کرک', + 35951 => 'گلستانک', + 35961 => 'لجران', + 36331 => 'جودانه', + 36341 => 'ابراهیم اباد', + 36351 => 'بکران', + 36361 => 'کرداباد', + 36371 => 'نردین', + 36381 => 'سوداغلان', + 36391 => 'فرومد', + 36431 => 'ابرسیج', + 36441 => 'میغان', + 36451 => 'قلعه نوخرقان', + 36461 => 'چهلدخترپادگان', + 36471 => 'کلاته خیج', + 36531 => 'نگارمن', + 36541 => 'دهملا', + 36551 => 'رویان', + 36561 => 'بدشت', + 36571 => 'سطوه', + 36581 => 'طرود', + 36591 => 'مغان', + 36631 => 'گیور', + 36641 => 'دستجرد', + 36651 => 'مسیح اباد', + 36661 => 'احمداباد', + 36671 => 'زمان اباد', + 36681 => 'سلمرود', + 36731 => 'جزن', + 36741 => 'برم', + 36751 => 'محمداباد', + 36761 => 'معصوم اباد', + 36771 => 'فرات', + 36781 => 'علیان', + 36791 => 'عمروان', + 36831 => 'قوشه', + 36841 => 'دروار', + 36851 => 'استانه', + 36861 => 'دیباج', + 36871 => 'طرزه', + 36881 => 'مهماندوست', + 36891 => 'کلاته ملا', + 36931 => 'قدرت اباد', + ], + ], + 10 => [ + 'title' => 'قم', + 'cities' => [ + 371 => 'قم', + 3731 => 'قنوات', + 3741 => 'دستجرد', + 37331 => 'امیرابادگنجی', + 37341 => 'قمرود', + 37351 => 'کهک', + 37361 => 'قلعه چم', + 37431 => 'قاهان', + 37441 => 'جعفریه', + 37451 => 'جنداب', + 37461 => 'سلفچگان', + ], + ], + 11 => [ + 'title' => 'مركزي', + 'cities' => [ + 381 => 'اراک', + 391 => 'ساوه', + 3771 => 'پرندک', + 3781 => 'محلات', + 3791 => 'دلیجان', + 3831 => 'کرهرود', + 3841 => 'خنداب', + 3851 => 'کمیجان', + 3861 => 'شازند', + 3871 => 'آستانه', + 3881 => 'خمین', + 3891 => 'رباطمراد', + 3931 => 'غرق آباد', + 3941 => 'مامونیه', + 3951 => 'تفرش', + 3961 => 'آشتیان', + 3991 => 'شهرجدیدمهاجران', + 37731 => 'سلطان اباد', + 37741 => 'اصفهانک', + 37751 => 'حسین اباد', + 37761 => 'خشکرود', + 37771 => 'حکیم اباد', + 37781 => 'یحیی اباد', + 37791 => 'صدراباد', + 37841 => 'نیمور', + 37851 => 'نخجیروان', + 37861 => 'باقراباد', + 37871 => 'بزیجان', + 37881 => 'عیسی اباد', + 37891 => 'خورهه', + 37961 => 'نراق', + 38341 => 'ساروق', + 38351 => 'داودآباد', + 38361 => 'کارچان', + 38451 => 'جاورسیان', + 38461 => 'ادشته', + 38471 => 'استوه', + 38481 => 'سنجان', + 38491 => 'اناج', + 38531 => 'وفس', + 38541 => 'خسروبیگ', + 38551 => 'میلاجرد', + 38561 => 'سمقاور', + 38571 => 'هزاوه', + 38631 => 'قدمگاه', + 38641 => 'هفته', + 38651 => 'لنجرود', + 38661 => 'توره', + 38671 => 'کزاز', + 38681 => 'کتیران بالا', + 38691 => 'نهرمیان', + 38731 => 'سرسختی بالا', + 38741 => 'لوزدرعلیا', + 38761 => 'هندودر', + 38771 => 'تواندشت علیا', + 38781 => 'مالمیر', + 38791 => 'چهارچریک', + 38841 => 'چهارچشمه', + 38851 => 'لکان', + 38861 => 'قورچی باشی', + 38871 => 'ورچه', + 38881 => 'فرفهان', + 38891 => 'امامزاده ورچه', + 38931 => 'رباطکفسان', + 38941 => 'ریحان علیا', + 38951 => 'جزنق', + 38961 => 'خوراوند', + 38971 => 'میشیجان علیا', + 38981 => 'گلدشت', + 38991 => 'دهنو', + 39331 => 'نوبران', + 39351 => 'یل اباد', + 39361 => 'رازقان', + 39371 => 'الویر', + 39381 => 'دوزج', + 39391 => 'علیشار', + 39431 => 'بالقلو', + 39441 => 'زاویه', + 39451 => 'چمران', + 39461 => 'قاقان', + 39471 => 'سامان', + 39481 => 'دخان', + 39491 => 'مراغه', + 39531 => 'فرمهین', + 39541 => 'شهراب', + 39551 => 'زاغر', + 39561 => 'کهک', + 39571 => 'فشک', + 39581 => 'اهنگران', + 39631 => 'مزرعه نو', + 39641 => 'صالح اباد', + 39651 => 'سیاوشان', + 39661 => 'اهو', + ], + ], + 12 => [ + 'title' => 'زنجان', + 'cities' => [ + 451 => 'زنجان', + 4531 => 'زرین آباد', + 4541 => 'ماهنشان', + 4551 => 'سلطانیه', + 4561 => 'ابهر', + 4571 => 'خرمدره', + 4581 => 'قیدار', + 4591 => 'آب بر', + 45331 => 'همایون', + 45341 => 'بوغداکندی', + 45351 => 'اژدهاتو', + 45371 => 'اسفجین', + 45381 => 'ارمغانخانه', + 45391 => 'قبله بلاغی', + 45431 => 'پری', + 45441 => 'اندابادعلیا', + 45451 => 'قره گل', + 45461 => 'نیک پی', + 45471 => 'دندی', + 45481 => 'سونتو', + 45491 => 'قلتوق', + 45531 => 'گوزلدره', + 45551 => 'سنبل اباد', + 45641 => 'درسجین', + 45651 => 'دولت اباد', + 45661 => 'کینه ورس', + 45731 => 'هیدج', + 45741 => 'صائین قلعه', + 45781 => 'اقبلاغ سفلی', + 45791 => 'سهرورد', + 45831 => 'کرسف', + 45841 => 'سجاس', + 45851 => 'محموداباد', + 45861 => 'باش قشلاق', + 45871 => 'گرماب', + 45881 => 'زرین رود', + 45891 => 'کهلا', + 45931 => 'گیلوان', + 45941 => 'دستجرده', + 45951 => 'سعیداباد', + 45961 => 'چورزق', + 45971 => 'حلب', + 45981 => 'درام', + ], + ], + 13 => [ + 'title' => 'مازندران', + 'cities' => [ + 461 => 'آمل', + 471 => 'بابل', + 481 => 'ساری', + 4631 => 'محمودآباد', + 4641 => 'نور', + 4651 => 'نوشهر', + 4661 => 'چالوس', + 4671 => 'سلمانشهر', + 4681 => 'تنکابن', + 4691 => 'رامسر', + 4731 => 'امیرکلا', + 4741 => 'بابلسر', + 4751 => 'فریدونکنار', + 4761 => 'قائم شهر', + 4771 => 'جویبار', + 4781 => 'زیر آب', + 4791 => 'پل سفید', + 4831 => 'کیاسر', + 4841 => 'نکا', + 4851 => 'بهشهر', + 4861 => 'گلوگاه', + 46181 => 'دابودشت', + 46331 => 'معلم کلا', + 46341 => 'سرخرود', + 46351 => 'وسطی کلا', + 46361 => 'رینه', + 46371 => 'سوا', + 46381 => 'باییجان', + 46391 => 'گزنک', + 46411 => 'ایزدشهر', + 46431 => 'چمستان', + 46441 => 'بنفشه ده', + 46451 => 'رییس کلا', + 46461 => 'اوز', + 46471 => 'بلده', + 46481 => 'تاکر', + 46491 => 'گلندرود', + 46531 => 'چلندر', + 46541 => 'صلاح الدین کلا', + 46551 => 'نارنج بن', + 46561 => 'رویان', + 46571 => 'کجور', + 46581 => 'پول', + 46591 => 'لشکنار', + 46631 => 'هیچرود', + 46641 => 'مرزن آباد', + 46651 => 'کردیچال', + 46661 => 'کلاردشت', + 46671 => 'کلنو', + 46681 => 'دلیر', + 46691 => 'سیاه بیشه', + 46731 => 'کلارآباد', + 46741 => 'عباس آباد', + 46751 => 'سرلنگا', + 46761 => 'کترا', + 46771 => 'گلعلی اباد', + 46781 => 'میان کوه سادات', + 46791 => 'مران سه هزار', + 46831 => 'نشتارود', + 46841 => 'قلعه گردن', + 46851 => 'خرم آباد', + 46861 => 'شیرود', + 46871 => 'سلیمان اباد', + 46881 => 'کشکو', + 46891 => 'لاک تراشان', + 46931 => 'سادات محله', + 46941 => 'کتالم وسادات شهر', + 46961 => 'اغوزکتی', + 46971 => 'جواهرده', + 46981 => 'جنت رودبار', + 46991 => 'تمل', + 47331 => 'خوشرودپی', + 47341 => 'اهنگرکلا', + 47351 => 'گاوانکلا', + 47381 => 'شورکش', + 47391 => 'اینج دان', + 47431 => 'عرب خیل', + 47441 => 'بهنمیر', + 47451 => 'کاسگرمحله', + 47461 => 'کله بست', + 47471 => 'بیشه سر', + 47491 => 'گتاب', + 47541 => 'درازکش', + 47551 => 'گردرودبار', + 47561 => 'مرزی کلا', + 47571 => 'شهیداباد', + 47581 => 'زرگرمحله', + 47631 => 'بالاجنیدلاک پل', + 47641 => 'خطیرکلا', + 47651 => 'حاجی کلاصنم', + 47661 => 'واسکس', + 47681 => 'ریکنده', + 47691 => 'ارطه', + 47731 => 'کیاکلا', + 47741 => 'بالادسته رکن کنار', + 47751 => 'بیزکی', + 47761 => 'کوهی خیل', + 47781 => 'سنگتاب', + 47791 => 'رکابدارکلا', + 47831 => 'شیرکلا', + 47841 => 'آلاشت', + 47851 => 'لفور (لفورک)', + 47861 => 'اتو', + 47871 => 'شیرگاه', + 47881 => 'پالند', + 47891 => 'چرات', + 47931 => 'ده میان', + 47941 => 'خشک دره', + 47951 => 'امافت', + 47961 => 'بالادواب', + 47971 => 'ورسک', + 47981 => 'کتی لته', + 48331 => 'اروست', + 48341 => 'فریم', + 48351 => 'سنگده', + 48361 => 'قادیکلا', + 48371 => 'تاکام', + 48390 => 'پایین هولار', + 48391 => 'بالاهولار', + 48431 => 'اسبوکلا', + 48441 => 'سورک', + 48451 => 'اسلام اباد', + 48461 => 'شهرک صنعتی گهرباران', + 48471 => 'فرح اباد (خزراباد)', + 48481 => 'دارابکلا', + 48491 => 'ماچک پشت', + 48531 => 'خورشید (امامیه)', + 48541 => 'زاغمرز', + 48551 => 'چلمردی', + 48561 => 'رستم کلا', + 48571 => 'پایین زرندین', + 48591 => 'بادابسر', + 48631 => 'تیرتاش', + 48641 => 'خلیل شهر', + 48661 => 'دامداری حسن ابوطالبی', + 48671 => 'بیشه بنه', + 48681 => 'سفیدچاه', + 48691 => 'دامداری حاج عزیزمجریان', + 48841 => 'میان دره', + 48872 => 'بندپی', + ], + ], + 14 => [ + 'title' => 'گلستان', + 'cities' => [ + 491 => 'گرگان', + 4871 => 'بندر گز', + 4881 => 'کردکوی', + 4891 => 'بندرترکمن', + 4931 => 'آق قلا', + 4941 => 'علی آباد', + 4951 => 'رامیان', + 4961 => 'آزاد شهر', + 4971 => 'گنبد کاووس', + 4981 => 'مینو دشت', + 4991 => 'کلاله', + 48731 => 'نوکنده', + 48733 => 'مراوه تپه', + 48961 => 'گمیش تپه', + 48971 => 'سیمین شهر', + 49351 => 'جلین', + 49361 => 'سرخنکلاته', + 49371 => 'تقی اباد', + 49391 => 'انبار آلوم', + 49431 => 'فاضل آباد', + 49471 => 'حاجیکلاته', + 49531 => 'خان ببین', + 49541 => 'دلند', + 49631 => 'نگین شهر', + 49641 => 'نوده خاندوز', + 49680 => 'تاتارعلیا', + 49751 => 'اینچه برون', + 49791 => 'کرند', + 49831 => 'گالیکش', + 49981 => 'عزیزاباد', + ], + ], + 15 => [ + 'title' => 'اردبيل', + 'cities' => [ + 561 => 'اردبیل', + 5631 => 'نمین', + 5641 => 'نیر', + 5651 => 'گرمی', + 5661 => 'مشگین شهر', + 5671 => 'بیله سوار', + 5681 => 'خلخال', + 5691 => 'پارس آباد', + 56331 => 'آبی بیگلو', + 56341 => 'ننه کران', + 56351 => 'عنبران', + 56361 => 'گرده', + 56371 => 'ثمرین', + 56381 => 'اردیموسی', + 56391 => 'سرعین', + 56431 => 'کورائیم', + 56441 => 'اسلام آباد', + 56451 => 'مهماندوست علیا', + 56461 => 'هیر', + 56471 => 'بقراباد', + 56481 => 'بودالالو', + 56491 => 'اراللوی بزرگ', + 56531 => 'دیزج', + 56541 => 'حمزه خانلو', + 56551 => 'زهرا', + 56561 => 'انی علیا', + 56571 => 'قاسم کندی', + 56581 => 'تازه کندانگوت', + 56591 => 'قره اغاج پایین', + 56631 => 'پریخان', + 56641 => 'قصابه', + 56651 => 'فخرآباد', + 56653 => 'لاهرود', + 56661 => 'رضی', + 56671 => 'قوشه سفلی', + 56681 => 'مرادلو', + 56691 => 'گنجوبه', + 56731 => 'گوگ تپه', + 56741 => 'انجیرلو', + 56751 => 'جعفر آباد', + 56761 => 'قشلاق اغداش کلام', + 56771 => 'خورخورسفلی', + 56781 => 'شورگل', + 56791 => 'نظرعلی بلاغی', + 56831 => 'لنبر', + 56841 => 'فیروزاباد', + 56851 => 'گیوی', + 56861 => 'خلفلو', + 56871 => 'هشتجین', + 56881 => 'برندق', + 56891 => 'کلور', + 56931 => 'تازه کندجدید', + 56941 => 'گوشلو', + 56961 => 'اق قباق علیا', + 56971 => 'شهرک غفاری', + 56981 => 'اصلاندوز', + 56991 => 'بران علیا', + ], + ], + 16 => [ + 'title' => 'آذربايجان غربي', + 'cities' => [ + 571 => 'ارومیه', + 573 => 'سیلوه', + 581 => 'خوی', + 591 => 'مهاباد', + 5751 => 'قوشچی', + 5761 => 'نقده', + 5771 => 'اشنویه', + 5781 => 'پیرانشهر', + 5791 => 'جلدیان', + 5831 => 'ایواوغلی', + 5837 => 'دیزج دیز', + 5841 => 'فیرورق', + 5861 => 'ماکو', + 5881 => 'سلماس', + 5891 => 'تازه شهر', + 5931 => 'گوگ تپه', + 5951 => 'بوکان', + 5961 => 'سردشت', + 5971 => 'میاندوآب', + 5981 => 'شاهیندژ', + 5991 => 'تکاب', + 57331 => 'باراندوز', + 57341 => 'دیزج دول', + 57351 => 'میاوق', + 57361 => 'ایبلو', + 57371 => 'دستجرد', + 57381 => 'نوشین', + 57391 => 'طلاتپه', + 57411 => 'سیلوانه', + 57431 => 'راژان', + 57441 => 'هاشم اباد', + 57451 => 'دیزج', + 57461 => 'زیوه', + 57471 => 'تویی', + 57481 => 'موانا', + 57531 => 'قره باغ', + 57541 => 'بهله', + 57551 => 'امام کندی', + 57561 => 'نازلو', + 57571 => 'سرو', + 57581 => 'کانسپی', + 57591 => 'ممکان', + 57641 => 'حسنلو', + 57651 => 'کهریزعجم', + 57661 => 'محمدیار', + 57671 => 'شیخ احمد', + 57681 => 'بیگم قلعه', + 57691 => 'راهدانه', + 57731 => 'شاهوانه', + 57741 => 'نالوس', + 57751 => 'ده شمس بزرگ', + 57761 => 'گلاز', + 57771 => 'لولکان', + 57781 => 'سیاوان', + 57831 => 'کله کین', + 57841 => 'شین اباد', + 57851 => 'چیانه', + 57861 => 'بیکوس', + 57871 => 'هنگ اباد', + 57941 => 'گردکشانه', + 57951 => 'پسوه', + 57961 => 'ریگ اباد', + 57971 => 'احمدغریب', + 58331 => 'سیه باز', + 58341 => 'بیله وار', + 58361 => 'ولدیان', + 58381 => 'قوروق', + 58391 => 'هندوان', + 58431 => 'بدلان', + 58441 => 'بلسورسفلی', + 58450 => 'زرآباد', + 58471 => 'استران', + 58481 => 'قطور', + 58516 => 'قره ضیاءالدین', + 58531 => 'شیرین بلاغ', + 58541 => 'مراکان', + 58551 => 'چورس', + 58561 => 'قورول علیا', + 58571 => 'بسطام', + 58631 => 'قره تپه', + 58641 => 'ریحانلوی علیا', + 58651 => 'زاویه سفلی', + 58661 => 'آواجیق', + 58671 => 'بازرگان', + 58681 => 'قم قشلاق', + 58691 => 'یولاگلدی', + 58716 => 'سیه چشمه', + 58731 => 'قرنقو', + 58751 => 'شوط', + 58761 => 'مرگنلر', + 58771 => 'پلدشت', + 58781 => 'نازک علیا', + 58791 => 'حسن کندی', + 58831 => 'وردان', + 58861 => 'قره قشلاق', + 58871 => 'تمر', + 58881 => 'ابگرم', + 58891 => 'سرنق', + 58931 => 'چهریق علیا', + 58941 => 'داراب', + 58951 => 'دلزی', + 58961 => 'اغ برزه', + 58971 => 'سنجی', + 59341 => 'خاتون باغ', + 59351 => 'حاجی حسن', + 59361 => 'سوگلی تپه', + 59371 => 'گلیجه', + 59381 => 'حاجی کند', + 59431 => 'باغچه', + 59441 => 'خورخوره', + 59450 => 'خلیفان', + 59451 => 'کاولان علیا', + 59461 => 'سیاقول علیا', + 59471 => 'اگریقاش', + 59481 => 'اوزون دره علیا', + 59531 => 'یکشوه', + 59541 => 'جوانمرد', + 59551 => 'اختتر', + 59561 => 'سیمینه', + 59571 => 'رحیم خان', + 59581 => 'گل تپه قورمیش', + 59631 => 'شلماش', + 59641 => 'اسلام اباد', + 59651 => 'بیوران سفلی', + 59671 => 'میرآباد', + 59681 => 'زمزیران', + 59691 => 'ربط', + 59730 => 'کشاورز', + 59731 => 'اقبال', + 59741 => 'ملاشهاب الدین', + 59751 => 'للکلو', + 59761 => 'بگتاش', + 59771 => 'چهار برج', + 59781 => 'گوگ تپه خالصه', + 59791 => 'تک اغاج', + 59831 => 'هاچاسو', + 59841 => 'هولاسو', + 59851 => 'قوزلوی افشار', + 59861 => 'محمودآباد', + 59871 => 'الی چین', + 59881 => 'حیدرباغی', + 59891 => 'حمزه قاسم', + 59931 => 'اوغول بیگ', + 59941 => 'دورباش', + 59951 => 'اقابیگ', + 59961 => 'احمدابادسفلی', + 59981 => 'باروق', + ], + ], + 17 => [ + 'title' => 'همدان', + 'cities' => [ + 651 => 'همدان', + 6531 => 'بهار', + 6541 => 'اسدآباد', + 6551 => 'کبودرآهنگ', + 6561 => 'فامنین', + 6571 => 'ملایر', + 6581 => 'تویسرکان', + 6591 => 'نهاوند', + 65141 => 'مریانج', + 65181 => 'جورقان', + 65331 => 'لالجین', + 65341 => 'دیناراباد', + 65351 => 'همه کسی', + 65361 => 'صالح آباد', + 65371 => 'پرلوک', + 65381 => 'حسین ابادبهارعاشوری', + 65391 => 'مهاجران', + 65431 => 'ویرایی', + 65441 => 'جنت اباد', + 65451 => 'موسی اباد', + 65461 => 'چنارسفلی', + 65471 => 'چنارعلیا', + 65481 => 'آجین', + 65491 => 'طویلان سفلی', + 65531 => 'کوریجان', + 65541 => 'کوهین', + 65551 => 'قهوردسفلی', + 65561 => 'اکنلو', + 65571 => 'شیرین سو', + 65581 => 'گل تپه', + 65591 => 'داق داق اباد', + 65631 => 'قهاوند', + 65641 => 'تجرک', + 65651 => 'کوزره', + 65661 => 'چانگرین', + 65671 => 'دمق', + 65681 => 'رزن', + 65691 => 'قروه درجزین', + 65731 => 'ازناو', + 65741 => 'جوزان', + 65751 => 'زنگنه', + 65761 => 'سامن', + 65771 => 'اورزمان', + 65781 => 'جوکار', + 65791 => 'اسلام اباد', + 65831 => 'جعفریه (قلعه جعفربیک)', + 65841 => 'سرکان', + 65851 => 'میانده', + 65861 => 'فرسفج', + 65871 => 'ولاشجرد', + 65881 => 'اشتران', + 65891 => 'باباپیر', + 65931 => 'جهان اباد', + 65941 => 'باباقاسم', + 65951 => 'بابارستم', + 65960 => 'برزول', + 65961 => 'گیان', + 65971 => 'دهفول', + 65981 => 'فیروزان', + 65991 => 'شهرک صنعتی بوعلی', + 65992 => 'پایگاه نوژه', + 65993 => 'علیصدر', + 65995 => 'ازندریان', + 65998 => 'گنبد', + 66000 => 'پادگان قهرمان', + ], + ], + 18 => [ + 'title' => 'كردستان', + 'cities' => [ + 661 => 'سنندج', + 6631 => 'کامیاران', + 6641 => 'دیواندره', + 6651 => 'بیجار', + 6661 => 'قروه', + 6671 => 'مریوان', + 6681 => 'سقز', + 6691 => 'بانه', + 66171 => 'شویشه', + 66331 => 'شاهینی', + 66341 => 'طای', + 66351 => 'گازرخانی', + 66361 => 'نشورسفلی', + 66371 => 'شیروانه', + 66381 => 'خامسان', + 66391 => 'موچش', + 66431 => 'شریف اباد', + 66441 => 'کوله', + 66451 => 'هزارکانیان', + 66461 => 'زرینه', + 66471 => 'گورباباعلی', + 66481 => 'گاوشله', + 66491 => 'خرکه', + 66531 => 'یاسوکند', + 66541 => 'توپ اغاج', + 66551 => 'اق بلاغ طغامین', + 66561 => 'بابارشانی', + 66571 => 'خسرواباد', + 66591 => 'جعفراباد', + 66631 => 'دلبران', + 66641 => 'دزج', + 66651 => 'کانی گنجی', + 66661 => 'بلبان آباد', + 66671 => 'دهگلان', + 66681 => 'قوریچای', + 66691 => 'سریش آباد', + 66711 => 'کانی دینار', + 66731 => 'نی', + 66741 => 'برده رشه', + 66751 => 'چناره', + 66761 => 'پیرخضران', + 66771 => 'بیساران', + 66781 => 'سروآباد', + 66791 => 'اورامان تخت', + 66831 => 'سرا', + 66841 => 'گل تپه', + 66851 => 'تیلکو', + 66861 => 'صاحب', + 66871 => 'خورخوره', + 66881 => 'کسنزان', + 66891 => 'میرده', + 66931 => 'ننور', + 66941 => 'بوئین سفلی', + 66951 => 'آرمرده', + 66961 => 'بوالحسن', + 66971 => 'کانی سور', + 66981 => 'کوخان', + 66991 => 'شوی', + ], + ], + 19 => [ + 'title' => 'كرمانشاه', + 'cities' => [ + 671 => 'کرمانشاه', + 6731 => 'هرسین', + 6741 => 'کنگاور', + 6751 => 'سنقر', + 6761 => 'اسلام آبادغرب', + 6771 => 'سرپل ذهاب', + 6781 => 'قصرشیرین', + 6791 => 'پاوه', + 67131 => 'رباط', + 67331 => 'هفت اشیان', + 67341 => 'هلشی', + 67351 => 'دوردشت', + 67361 => 'سنقراباد', + 67371 => 'بیستون', + 67381 => 'جعفراباد', + 67391 => 'مرزبانی', + 67431 => 'فش', + 67441 => 'فرامان', + 67451 => 'سلطان اباد', + 67461 => 'صحنه', + 67471 => 'قزوینه', + 67481 => 'دهلقین', + 67491 => 'درکه', + 67531 => 'باوله', + 67541 => 'گردکانه علیا', + 67551 => 'اگاه علیا', + 67561 => 'سطر', + 67571 => 'کیوه نان', + 67580 => 'میان راهان', + 67581 => 'کرکسار', + 67591 => 'کندوله', + 67631 => 'زاوله علیا', + 67641 => 'حمیل', + 67651 => 'ریجاب', + 67661 => 'کرندغرب', + 67671 => 'گهواره', + 67681 => 'کوزران', + 67691 => 'قلعه شیان', + 67731 => 'حسن اباد', + 67741 => 'سراب ذهاب', + 67751 => 'ترک ویس', + 67761 => 'ازگله', + 67771 => 'تازه آباد', + 67781 => 'نساردیره', + 67791 => 'سرمست', + 67831 => 'تپه رش', + 67841 => 'خسروی', + 67861 => 'سومار', + 67871 => 'گیلانغرب', + 67891 => 'قیلان', + 67911 => 'شاهو', + 67931 => 'باینگان', + 67940 => 'بانوره', + 67941 => 'نوسود', + 67951 => 'نودشه', + 67961 => 'روانسر', + 67971 => 'دولت اباد', + 67981 => 'جوانرود', + 67991 => 'میراباد', + ], + ], + 20 => [ + 'title' => 'لرستان', + 'cities' => [ + 681 => 'خرم آباد', + 691 => 'بروجرد', + 6831 => 'نورآباد', + 6841 => 'کوهدشت', + 6851 => 'پلدختر', + 6861 => 'الیگودرز', + 6871 => 'ازنا', + 6881 => 'دورود', + 6891 => 'الشتر', + 68141 => 'ماسور', + 68181 => 'بیرانوند', + 68331 => 'برخوردار', + 68341 => 'فرهاداباد', + 68351 => 'دم باغ', + 68361 => 'کهریزوروشت', + 68371 => 'چشمه کیزاب علیا', + 68381 => 'هفت چشمه', + 68391 => 'تقی اباد', + 68431 => 'خوشناموند', + 68441 => 'اشتره گل گل', + 68451 => 'چقابل', + 68461 => 'سوری', + 68471 => 'کونانی', + 68481 => 'گراب', + 68491 => 'درب گنبد', + 68531 => 'پاعلم (پل تنگ)', + 68541 => 'واشیان نصیرتپه', + 68551 => 'چمشک زیرتنگ', + 68561 => 'افرینه', + 68571 => 'معمولان', + 68580 => 'ویسیان', + 68581 => 'میان تاگان', + 68591 => 'پل شوراب پایین', + 68631 => 'شاهپوراباد', + 68641 => 'چمن سلطان', + 68651 => 'کیزاندره', + 68661 => 'قلعه بزنوید', + 68671 => 'شول آباد', + 68681 => 'حیه', + 68691 => 'مرگ سر', + 68731 => 'مومن آباد', + 68741 => 'رازان', + 68751 => 'سیاه گوشی (پل هرو)', + 68761 => 'زاغه', + 68771 => 'سرابدوره', + 68781 => 'چاه ذوالفقار', + 68791 => 'چم پلک', + 68831 => 'ژان', + 68841 => 'کاغه', + 68851 => 'چالانچولان', + 68861 => 'سپید دشت', + 68871 => 'چم سنگر', + 68881 => 'ایستگاه تنگ هفت', + 68891 => 'مکینه حکومتی', + 68931 => 'سراب سیاهپوش', + 68951 => 'ده رحم', + 68961 => 'فیروز آباد', + 68971 => 'اشترینان', + 68981 => 'بندیزه', + 68991 => 'دره گرگ', + ], + ], + 21 => [ + 'title' => 'بوشهر', + 'cities' => [ + 751 => 'بوشهر', + 7531 => 'بندرگناوه', + 7541 => 'خورموج', + 7551 => 'اهرم', + 7561 => 'برازجان', + 75111 => 'نخل تقی', + 75331 => 'بندر ریگ', + 75341 => 'چهارروستایی', + 75351 => 'شول', + 75361 => 'بندر دیلم', + 75371 => 'امام حسن', + 75381 => 'چغادک', + 75390 => 'سیراف', + 75391 => 'عسلویه', + 75431 => 'بادوله', + 75441 => 'شنبه', + 75451 => 'کاکی', + 75461 => 'خارک', + 75471 => 'دلوار', + 75481 => 'بنه گز', + 75491 => 'اباد', + 75531 => 'بردخون', + 75540 => 'بردستان', + 75541 => 'بندردیر', + 75551 => 'آبدان', + 75560 => 'انارستان', + 75561 => 'ریز', + 75570 => 'بنک', + 75571 => 'بندرکنگان', + 75581 => 'جم', + 75591 => 'ابگرمک', + 75631 => 'دالکی', + 75641 => 'شبانکاره', + 75651 => 'آبپخش', + 75661 => 'سعدآباد', + 75671 => 'وحدتیه', + 75681 => 'تنگ ارم', + 75691 => 'کلمه', + ], + ], + 22 => [ + 'title' => 'كرمان', + 'cities' => [ + 761 => 'کرمان', + 771 => 'رفسنجان', + 781 => 'سیرجان', + 7631 => 'ماهان', + 7641 => 'گلباف', + 7651 => 'راور', + 7661 => 'بم', + 7671 => 'بروات', + 7681 => 'راین', + 7691 => 'محمدآباد', + 7731 => 'سرچشمه', + 7741 => 'انار', + 7751 => 'شهربابک', + 7761 => 'زرند', + 7771 => 'کیانشهر', + 7781 => 'کوهبنان', + 7791 => 'چترود', + 7831 => 'پاریز', + 7841 => 'بردسیر', + 7851 => 'بافت', + 7861 => 'جیرفت', + 7871 => 'عنبرآباد', + 7881 => 'کهنوج', + 7891 => 'منوجان', + 76331 => 'ده بالا', + 76361 => 'جوپار', + 76371 => 'باغین', + 76381 => 'اختیارآباد', + 76391 => 'زنگی آباد', + 76431 => 'جوشان', + 76451 => 'اندوهجرد', + 76461 => 'شهداد', + 76471 => 'کشیت', + 76541 => 'فیض اباد', + 76641 => 'دریجان', + 76731 => 'نرماشیر', + 76741 => 'فهرج', + 76771 => 'برج معاز', + 76791 => 'نظام شهر', + 76831 => 'خانه خاتون', + 76841 => 'ابارق', + 76861 => 'گروه', + 76871 => 'گزک', + 76891 => 'محی آباد', + 76941 => 'تهرود', + 76951 => 'میرابادارجمند', + 77331 => 'داوران', + 77341 => 'خنامان', + 77351 => 'کبوترخان', + 77361 => 'هرمزاباد', + 77371 => 'کشکوئیه', + 77381 => 'گلشن', + 77391 => 'صفائیه', + 77431 => 'امین شهر', + 77461 => 'بهرمان', + 77471 => 'جوادیه الهیه نوق', + 77511 => 'خاتون آباد', + 77541 => 'محمدابادبرفه', + 77551 => 'خورسند', + 77561 => 'خبر', + 77571 => 'کمسرخ', + 77581 => 'جوزم', + 77591 => 'دهج', + 77631 => 'دشت خاک', + 77651 => 'حتکن', + 77661 => 'ریحان', + 77671 => 'جرجافک', + 77691 => 'یزدان شهر', + 77731 => 'شعبجره', + 77751 => 'سیریز', + 77761 => 'خانوک', + 77861 => 'جور', + 77931 => 'هوتک', + 77951 => 'کاظم آباد', + 77961 => 'هجدک', + 77971 => 'حرجند', + 78151 => 'نجف شهر', + 78331 => 'بلورد', + 78341 => 'ملک اباد', + 78361 => 'عماداباد', + 78371 => 'زیدآباد', + 78380 => 'هماشهر', + 78431 => 'نگار', + 78441 => 'گلزار', + 78451 => 'لاله زار', + 78461 => 'قلعه عسکر', + 78471 => 'مومن اباد', + 78481 => 'چناربرین', + 78491 => 'کمال اباد', + 78541 => 'امیراباد', + 78551 => 'بزنجان', + 78561 => 'رابر', + 78571 => 'پتکان', + 78591 => 'ارزوئیه', + 78631 => 'جبالبارز', + 78661 => 'درب بهشت', + 78691 => 'رضی ابادبالا', + 78731 => 'میجان علیا', + 78761 => 'مردهک', + 78771 => 'دوساری', + 78781 => 'حسین ابادجدید', + 78791 => 'بلوک', + 78831 => 'رودبار', + 78841 => 'قلعه گنج', + 78851 => 'نودژ', + 78871 => 'فاریاب', + 78941 => 'سرخ قلعه', + 78971 => 'خیراباد', + ], + ], + 23 => [ + 'title' => 'هرمزگان', + 'cities' => [ + 791 => 'بندرعباس', + 7931 => 'خمیر', + 7941 => 'کیش', + 7951 => 'قشم', + 7961 => 'بستک', + 7971 => 'بندرلنگه', + 7981 => 'میناب', + 7991 => 'دهبارز', + 79331 => 'پشته ایسین', + 79341 => 'پل شرقی', + 79351 => 'فین', + 79361 => 'سیاهو', + 79370 => 'سرگز', + 79371 => 'فارغان', + 79381 => 'باغات', + 79391 => 'حاجی آباد', + 79431 => 'ابگرم خورگو', + 79441 => 'قلعه قاضی', + 79450 => 'تخت', + 79451 => 'حسن لنگی پایین', + 79460 => 'گروک', + 79461 => 'سیریک', + 79471 => 'گونمردی', + 79491 => 'گوهرت', + 79531 => 'درگهان', + 79541 => 'سوزا', + 79551 => 'هرمز', + 79561 => 'جزیره لارک شهری', + 79571 => 'هنگام جدید', + 79581 => 'جزیره سیری', + 79591 => 'ابوموسی', + 79611 => 'جناح', + 79631 => 'پدل', + 79641 => 'کنگ', + 79651 => 'دژگان', + 79661 => 'رویدر', + 79671 => 'دهنگ', + 79691 => 'کمشک', + 79711 => 'کوشکنار', + 79731 => 'گزیر', + 79741 => 'بندرمغویه', + 79751 => 'چارک', + 79761 => 'دشتی', + 79771 => 'پارسیان', + 79781 => 'جزیره لاوان', + 79791 => 'بندرجاسک', + 79831 => 'بندر', + 79841 => 'سندرک', + 79851 => 'درپهن', + 79861 => 'کلورجکدان', + 79871 => 'گوهران', + 79881 => 'سردشت', + 79911 => 'بیکاه', + 79931 => 'جغین', + 79941 => 'زیارت علی', + 79951 => 'ماشنگی', + 79961 => 'گوربند', + 79971 => 'تیاب', + 79981 => 'بندزرک', + 79991 => 'هشتبندی', + ], + ], + 24 => [ + 'title' => 'چهارمحال و بختياري', + 'cities' => [ + 881 => 'شهر کرد', + 8831 => 'فرخ شهر', + 8834 => 'دزک', + 8841 => 'هفشجان', + 8844 => 'هارونی', + 8851 => 'سامان', + 8861 => 'فارسان', + 8871 => 'بروجن', + 8881 => 'اردل', + 8891 => 'لردگان', + 88139 => 'کیان', + 88331 => 'طاقانک', + 88351 => 'خراجی', + 88361 => 'دستناء', + 88371 => 'شلمزار', + 88381 => 'گهرو', + 88431 => 'سورشجان', + 88451 => 'مرغملک', + 88461 => 'سودجان', + 88561 => 'نافچ', + 88571 => 'وردنجان', + 88581 => 'بن', + 88591 => 'پردنجان', + 88631 => 'باباحیدر', + 88651 => 'چلگرد', + 88661 => 'شهریاری', + 88671 => 'جونقان', + 88731 => 'نقنه', + 88741 => 'فرادنبه', + 88751 => 'سفید دشت', + 88761 => 'بلداجی', + 88771 => 'اورگان', + 88781 => 'گندمان', + 88791 => 'امام قیس', + 88831 => 'ناغان', + 88841 => 'گل سفید', + 88861 => 'چوله دان', + 88881 => 'دشتک', + 88941 => 'آلونی', + 88951 => 'مال خلیفه', + 88961 => 'چمن بید', + 88971 => 'سردشت', + 88991 => 'منج', + ], + ], + 25 => [ + 'title' => 'يزد', + 'cities' => [ + 891 => 'یزد', + 8931 => 'ابرکوه', + 8951 => 'اردکان', + 8961 => 'میبد', + 8971 => 'بافق', + 8981 => 'مهریز', + 8991 => 'تفت', + 89331 => 'فراغه', + 89351 => 'مهردشت', + 89361 => 'اسفنداباد', + 89416 => 'اشکذر', + 89418 => 'زارچ', + 89431 => 'شاهدیه', + 89441 => 'فهرج', + 89451 => 'خضر آباد', + 89481 => 'ندوشن', + 89491 => 'حمیدیا', + 89531 => 'احمد آباد', + 89551 => 'عقدا', + 89571 => 'انارستان', + 89581 => 'زرین', + 89631 => 'بفروئیه', + 89731 => 'اسفیج', + 89751 => 'مبارکه', + 89761 => 'بهاباد', + 89771 => 'کوشک', + 89781 => 'بنستان', + 89831 => 'تنگ چنار (چنار)', + 89851 => 'ارنان', + 89861 => 'بهادران', + 89871 => 'مروست', + 89881 => 'هرات', + 89891 => 'فتح اباد', + 89931 => 'ناحیه صنعتی پیشکوه', + 89941 => 'نصراباد', + 89951 => 'علی اباد', + 89961 => 'نیر', + 89981 => 'ناحیه صنعتی گاریزات', + 89991 => 'دهشیر', + ], + ], + 26 => [ + 'title' => 'سيستان و بلوچستان', + 'cities' => [ + 981 => 'زاهدان', + 991 => 'ایرانشهر', + 9831 => 'نصرت آباد', + 9841 => 'میرجاوه', + 9861 => 'زابل', + 9871 => 'زهک', + 9875 => 'خواجه احمد', + 9891 => 'خاش', + 9931 => 'سرباز', + 9941 => 'بمپور', + 9951 => 'سراوان', + 9961 => 'سوران', + 9971 => 'چابهار', + 9981 => 'کنارک', + 9991 => 'نیکشهر', + ], + ], + 27 => [ + 'title' => 'ايلام', + 'cities' => [ + 6931 => 'ایلام', + 6941 => 'ایوان', + 6951 => 'سرآبله', + 6961 => 'دره شهر', + 6971 => 'آبدانان', + 6981 => 'دهلران', + 6991 => 'مهران', + 69331 => 'چنارباشی', + 69341 => 'بیشه دراز', + 69351 => 'چشمه کبود', + 69361 => 'چوار', + 69371 => 'بانویزه', + 69381 => 'چمن سیدمحمد', + 69391 => 'هفت چشمه', + 69441 => 'شورابه ملک', + 69451 => 'کلان', + 69471 => 'زرنه', + 69511 => 'شباب', + 69531 => 'توحید', + 69541 => 'بلاوه تره سفلی', + 69551 => 'لومار', + 69561 => 'آسمان آباد', + 69571 => 'سراب کارزان', + 69581 => 'شهرک سرتنگ', + 69591 => 'علی اباد', + 69631 => 'ماژین', + 69641 => 'ارمو', + 69661 => 'چشمه شیرین', + 69671 => 'بدره', + 69681 => 'شهرک ولیعصر', + 69731 => 'گنداب', + 69741 => 'ژیور', + 69751 => 'سراب باغ', + 69761 => 'مورموری', + 69771 => 'سیاه گل', + 69781 => 'اب انار', + 69831 => 'چم هندی', + 69841 => 'موسیان', + 69851 => 'گولاب', + 69861 => 'میمه', + 69871 => 'پهله', + 69881 => 'عین خوش', + 69891 => 'دشت عباس', + 69931 => 'شهرک اسلامیه', + 69951 => 'صالح آباد', + 69970 => 'دلگشا', + 69971 => 'ارکواز', + 69972 => 'مهر', + 69981 => 'دول کبودخوشادول', + 69991 => 'پاریاب', + ], + ], + 28 => [ + 'title' => 'كهگيلويه و بويراحمد', + 'cities' => [ + 7571 => 'دهدشت', + 7581 => 'دوگنبدان', + 7591 => 'یاسوج', + 75731 => 'سوق', + 75741 => 'لنده', + 75751 => 'لیکک', + 75761 => 'چرام', + 75771 => 'دیشموک', + 75781 => 'قلعه رییسی', + 75791 => 'قلعه دختر', + 75831 => 'باباکلان', + 75841 => 'مظفراباد', + 75851 => 'دیل', + 75861 => 'شاه بهرام', + 75871 => 'چاه تلخاب علیا', + 75881 => 'باشت', + 75891 => 'سربیشه', + 75911 => 'مادوان', + 75941 => 'چیتاب', + 75951 => 'گراب سفلی', + 75961 => 'مارگون', + 75971 => 'میمند', + 75981 => 'پاتاوه', + 75991 => 'سی سخت', + ], + ], + 29 => [ + 'title' => 'خراسان شمالي', + 'cities' => [ + 941 => 'بجنورد', + 9431 => 'گرمه', + 9441 => 'جاجرم', + 9451 => 'آشخانه', + 9461 => 'شیروان', + 9481 => 'فاروج', + 9661 => 'اسفراین', + ], + ], + 30 => [ + 'title' => 'خراسان جنوبي', + 'cities' => [ + 971 => 'بیرجند', + 9741 => 'سربیشه', + 9751 => 'نهبندان', + 9761 => 'قاین', + 9771 => 'فردوس', + 9781 => 'بشرویه', + 9791 => 'طبس', + ], + ], + 31 => [ + 'title' => 'البرز', + 'cities' => [ + 31 => 'کرج', + 3331 => 'نظرآباد', + 3361 => 'هشتگرد', + 31541 => 'ادران', + 31551 => 'آسارا', + 31638 => 'گرمدره', + 31656 => 'فردیس', + 31776 => 'مشکین دشت', + 31778 => 'محمدشهر', + 31836 => 'کرج (مهرشهر)', + 31849 => 'ماهدشت', + 31871 => 'اشتهارد', + 31991 => 'کمالشهر', + 33351 => 'تنکمان', + 33611 => 'گلسار', + 33618 => 'شهر جدید هشتگرد', + 33651 => 'کوهسار', + 33661 => 'چهارباغ', + 33691 => 'طالقان', + ], + ], + ]; + foreach($citiesArray as $province) { + foreach ($province['cities'] as $code => $cityName) { + if ($code == $cityCode) { + return $cityName; + } + } + } + return false; + } +//========================================================================================================================= } \ No newline at end of file diff --git a/admin/partials/ssbhesabix-admin-setting.php b/admin/partials/ssbhesabix-admin-setting.php index f465d0f..6381c3b 100644 --- a/admin/partials/ssbhesabix-admin-setting.php +++ b/admin/partials/ssbhesabix-admin-setting.php @@ -1,1840 +1,2339 @@ - - * @author HamidReza Gharahzadeh - * @author Sepehr Najafi - */ -class Ssbhesabix_Setting { - - /** - * Hook in methods - * @since 1.0.0 - * @access static - */ -//========================================================================================================================== - public static function init() { - add_action( 'ssbhesabix_home_setting', array( __CLASS__, 'ssbhesabix_home_setting' ) ); - - add_action( 'ssbhesabix_catalog_setting', array( __CLASS__, 'ssbhesabix_catalog_setting' ) ); - add_action( 'ssbhesabix_catalog_setting_save_field', array( - __CLASS__, - 'ssbhesabix_catalog_setting_save_field' - ) ); - - add_action( 'ssbhesabix_customers_setting', array( __CLASS__, 'ssbhesabix_customers_setting' ) ); - add_action( 'ssbhesabix_customers_setting_save_field', array( - __CLASS__, - 'ssbhesabix_customers_setting_save_field' - ) ); - - add_action( 'ssbhesabix_invoice_setting', array( __CLASS__, 'ssbhesabix_invoice_setting' ) ); - add_action( 'ssbhesabix_invoice_setting_save_field', array( - __CLASS__, - 'ssbhesabix_invoice_setting_save_field' - ) ); - - add_action( 'ssbhesabix_payment_setting', array( __CLASS__, 'ssbhesabix_payment_setting' ) ); - add_action( 'ssbhesabix_payment_setting_save_field', array( - __CLASS__, - 'ssbhesabix_payment_setting_save_field' - ) ); - - add_action( 'ssbhesabix_api_setting', array( __CLASS__, 'ssbhesabix_api_setting' ) ); - add_action( 'ssbhesabix_api_setting_save_field', array( __CLASS__, 'ssbhesabix_api_setting_save_field' ) ); - - add_action( 'ssbhesabix_export_setting', array( __CLASS__, 'ssbhesabix_export_setting' ) ); - - add_action( 'ssbhesabix_sync_setting', array( __CLASS__, 'ssbhesabix_sync_setting' ) ); - - add_action( 'ssbhesabix_log_setting', array( __CLASS__, 'ssbhesabix_log_setting' ) ); - - add_action( 'ssbhesabix_extra_setting', array( __CLASS__, 'ssbhesabix_extra_setting' ) ); - add_action( 'ssbhesabix_extra_setting_save_field', array( - __CLASS__, - 'ssbhesabix_extra_setting_save_field' - ) ); - } -//========================================================================================================================== - public static function ssbhesabix_home_setting() { - ?> -

-

-

- -
- هشدارها -
-
    -
  • * - افزونه حسابیکس از کد کالاها و مشتریان و از شماره فاکتور جهت شناسایی آنها استفاده می کند، - بنابراین پس از ثبت کالاها و مشتریان در حسابیکس کد آنها را در حسابیکس تغییر ندهید، و همچنین پس از ثبت - فاکتور، - شماره فاکتور را در حسابیکس نباید تغییر دهید. -
  • -
  • - * با حذف افزونه از وردپرس، جدول ارتباط بین افزونه و حسابیکس نیز از دیتابیس وردپرس حذف می شود - و کلیه ارتباطات از بین می رود. -
  • -
-
- - __('Enable or Disable Debug Mode', 'ssbhesabix'), - 'id' => 'ssbhesabix_debug_mode_checkbox', - 'default' => 'no', - 'type' => 'checkbox', - ); - - return $fields; - } -//============================================================================================== - public static function ssbhesabix_extra_setting() { - ?> -
-
    -
  • - این صفحه برای تنظیمات پیشرفته افزونه می باشد -
  • -
-
- -

- - -
- - - - Plugin Version - Server PHP Version - Plugin PHP Version Tested Up To - - - - - ' . $plugin_version . ' - ' . $server_php_version . ' - ' . $plugin_php_version . ' - - - ' - - . ''; - ?> -
- init( $ssbhesabf_setting_fields ); ?> -
-

- -

-
- save_fields( $ssbhesabf_setting_fields ); - } -//============================================================================================== - public static function ssbhesabix_catalog_setting_fields() { - $warehouses = Ssbhesabix_Setting::ssbhesabix_get_warehouses(); - - $fields[] = array( - 'title' => __( 'Catalog Settings', 'ssbhesabix' ), - 'type' => 'title', - 'desc' => '', - 'id' => 'catalog_options' - ); - - $fields[] = array( - 'title' => __( 'Update Price', 'ssbhesabix' ), - 'desc' => __( 'Update Price after change in Hesabix', 'ssbhesabix' ), - 'id' => 'ssbhesabix_item_update_price', - 'default' => 'no', - 'type' => 'checkbox' - ); - - $fields[] = array( - 'title' => __( 'Update Quantity', 'ssbhesabix' ), - 'desc' => __( 'Update Quantity after change in Hesabix', 'ssbhesabix' ), - 'id' => 'ssbhesabix_item_update_quantity', - 'default' => 'no', - 'type' => 'checkbox' - ); - - $fields[] = array( - 'title' => __( "Update product's quantity based on", 'ssbhesabix' ), - 'id' => 'ssbhesabix_item_update_quantity_based_on', - 'type' => 'select', - 'options' => $warehouses, - ); - - $fields[] = array( - 'title' => "", - 'desc' => __( 'Do not submit product in Hesabix automatically by saving product in woocommerce', 'ssbhesabix' ), - 'id' => 'ssbhesabix_do_not_submit_product_automatically', - 'default' => 'no', - 'type' => 'checkbox' - ); - - $fields[] = array( - 'title' => "", - 'desc' => __( 'Do not update product price in Hesabix by editing product in woocommerce', 'ssbhesabix' ), - 'id' => 'ssbhesabix_do_not_update_product_price_in_hesabix', - 'default' => 'no', - 'type' => 'checkbox' - ); - - $fields[] = array( - 'title' => "", - 'desc' => __( 'Do not update product barcode in Hesabix by saving product in woocommerce', 'ssbhesabix' ), - 'id' => 'ssbhesabix_do_not_update_product_barcode_in_hesabix', - 'default' => 'no', - 'type' => 'checkbox' - ); - - $fields[] = array( - 'title' => "", - 'desc' => __( 'Do not update product category in Hesabix by saving product in woocommerce', 'ssbhesabix' ), - 'id' => 'ssbhesabix_do_not_update_product_category_in_hesabix', - 'default' => 'no', - 'type' => 'checkbox' - ); - - $fields[] = array( - 'title' => "", - 'desc' => __( 'Do not update product code in Hesabix by saving product in woocommerce', 'ssbhesabix' ), - 'id' => 'ssbhesabix_do_not_update_product_product_code_in_hesabix', - 'default' => 'no', - 'type' => 'checkbox' - ); - - $fields[] = array( - 'title' => "", - 'desc' => __( 'Show Hesabix ID in Products Page', 'ssbhesabix' ), - 'id' => 'ssbhesabix_show_product_code_in_products_page', - 'default' => 'no', - 'type' => 'checkbox' - ); - - $fields[] = array( - 'title' => "", - 'desc' => __( 'Set Special Sale as Discount in invoice', 'ssbhesabix' ), - 'id' => 'ssbhesabix_set_special_sale_as_discount', - 'default' => 'no', - 'type' => 'checkbox' - ); - - $options_to_update_sale_price = array(); - $options_to_update_sale_price[0] = __( "The Sale price does not change", 'ssbhesabix' ); - $options_to_update_sale_price[1] = __( "The Sale price gets removed", 'ssbhesabix' ); - $options_to_update_sale_price[2] = __( "The sale price get changes in proportion to the regular price", 'ssbhesabix' ); - - $fields[] = array( - 'title' => __( "Update sale price", 'ssbhesabix' ), - 'id' => 'ssbhesabix_item_update_sale_price', - 'type' => 'select', - 'options' => $options_to_update_sale_price, - ); - - $fields[] = array( 'type' => 'sectionend', 'id' => 'catalog_options' ); - - return $fields; - } -//==================================================================================================== - public static function ssbhesabix_catalog_setting() { - $ssbhesabf_setting_fields = self::ssbhesabix_catalog_setting_fields(); - $Html_output = new Ssbhesabix_Html_output(); - ?> -
- init( $ssbhesabf_setting_fields ); ?> -

- -

-
- save_fields( $ssbhesabf_setting_fields ); - } -//============================================================================================= - public static function ssbhesabix_customers_setting_fields() { - - $fields[] = array( - 'title' => __( 'Customers Settings', 'ssbhesabix' ), - 'type' => 'title', - 'desc' => '', - 'id' => 'customer_options' - ); - - $fields[] = array( - 'title' => __( 'Update Customer Address', 'ssbhesabix' ), - 'desc' => __( 'Choose when update Customer address in Hesabix.', 'ssbhesabix' ), - 'id' => 'ssbhesabix_contact_address_status', - 'type' => 'select', - 'options' => array( - '1' => __( 'Use first customer address', 'ssbhesabix' ), - '2' => __( 'update address with Invoice address', 'ssbhesabix' ), - '3' => __( 'update address with Delivery address', 'ssbhesabix' ) - ), - ); - - $fields[] = array( - 'title' => __( 'Customer\'s Group', 'ssbhesabix' ), - 'desc' => __( 'Enter a Customer\'s Group in Hesabix', 'ssbhesabix' ), - 'id' => 'ssbhesabix_contact_node_family', - 'type' => 'text', - 'default' => 'مشتریان فروشگاه آنلاین' - ); - - $fields[] = array( - 'title' => __( 'Save Customer\'s group', 'ssbhesabix' ), - 'desc' => __( 'Automatically save Customer\'s group in hesabix', 'ssbhesabix' ), - 'id' => 'ssbhesabix_contact_automatic_save_node_family', - 'default' => 'yes', - 'type' => 'checkbox' - ); - $fields[] = array( - 'title' => __( 'Customer\'s detail auto save and update', 'ssbhesabix' ), - 'desc' => __( 'Save and update Customer\'s detail automatically in hesabix', 'ssbhesabix' ), - 'id' => 'ssbhesabix_contact_automatically_save_in_hesabix', - 'type' => 'checkbox', - 'default' => 'yes' - ); - - $fields[] = array( 'type' => 'sectionend', 'id' => 'customer_options' ); - - return $fields; - } -//============================================================================================= - public static function ssbhesabix_customers_setting() { - - $ssbhesabf_setting_fields = self::ssbhesabix_customers_setting_fields(); - - $add_fields = get_option( 'ssbhesabix_contact_add_additional_checkout_fields_hesabix', 1 ); - $nationalCodeCheck = get_option( 'ssbhesabix_contact_NationalCode_checkbox_hesabix' ) == 'yes'; - $economicCodeCheck = get_option( 'ssbhesabix_contact_EconomicCode_checkbox_hesabix' ) == 'yes'; - $registrationNumberCheck = get_option( 'ssbhesabix_contact_RegistrationNumber_checkbox_hesabix') == 'yes'; - $websiteCheck = get_option( 'ssbhesabix_contact_Website_checkbox_hesabix') == 'yes'; - - $nationalCodeRequired = get_option( 'ssbhesabix_contact_NationalCode_isRequired_hesabix' ) == 'yes'; - $economicCodeRequired = get_option( 'ssbhesabix_contact_EconomicCode_isRequired_hesabix' ) == 'yes'; - $registrationNumberRequired = get_option( 'ssbhesabix_contact_RegistrationNumber_isRequired_hesabix') == 'yes'; - $websiteRequired = get_option( 'ssbhesabix_contact_Website_isRequired_hesabix') == 'yes'; - - $nationalCodeMetaName = get_option( 'ssbhesabix_contact_NationalCode_text_hesabix', null ) ; - $economicCodeMetaName = get_option( 'ssbhesabix_contact_EconomicCode_text_hesabix', null ) ; - $registrationNumberMetaName = get_option( 'ssbhesabix_contact_RegistrationNumber_text_hesabix', null ); - $websiteMetaName = get_option( 'ssbhesabix_contact_Website_text_hesabix', null ) ; - - $Html_output = new Ssbhesabix_Html_output(); - ?> -
- init( $ssbhesabf_setting_fields ); ?> - -
-
- -
-
-
- > - -
- -
- > - -
-
- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class="form-control" value="yes"> class="form-control" value="yes">
class="form-control" value="yes"> class="form-control" value="yes">
class="form-control" value="yes"> class="form-control" value="yes">
class="form-control" value="yes"> class="form-control" value="yes">
-
-
- -

- -

-
- save_fields( $ssbhesabf_setting_fields ); - // .... - } - -//============================================================================================= - public static function ssbhesabix_invoice_setting_fields() { - $projects = Ssbhesabix_Setting::ssbhesabix_get_projects(); - $salesmen = Ssbhesabix_Setting::ssbhesabix_get_salesmen(); - - $fields[] = array( - 'title' => __( 'Invoice Settings', 'ssbhesabix' ), - 'type' => 'title', - 'desc' => '', - 'id' => 'invoice_options' - ); - - $fields[] = array( - 'title' => __( 'Add invoice in which status', 'ssbhesabix' ), - 'id' => 'ssbhesabix_invoice_status', - 'type' => 'multiselect', - 'options' => array( - 'pending' => __( 'Pending payment', 'ssbhesabix' ), - 'processing' => __( 'Processing', 'ssbhesabix' ), - 'on-hold' => __( 'On hold', 'ssbhesabix' ), - 'completed' => __( 'Completed', 'ssbhesabix' ), - 'cancelled' => __( 'Cancelled', 'ssbhesabix' ), - 'refunded' => __( 'Refunded', 'ssbhesabix' ), - 'failed' => __( 'Failed', 'ssbhesabix' ), - 'checkout-draft' => __( 'Draft', 'ssbhesabix' ), - ), - ); - - $fields[] = array( - 'title' => __( 'Return sale invoice status', 'ssbhesabix' ), - 'id' => 'ssbhesabix_invoice_return_status', - 'type' => 'multiselect', - 'options' => array( - 'pending' => __( 'Pending payment', 'ssbhesabix' ), - 'processing' => __( 'Processing', 'ssbhesabix' ), - 'on-hold' => __( 'On hold', 'ssbhesabix' ), - 'completed' => __( 'Completed', 'ssbhesabix' ), - 'cancelled' => __( 'Cancelled', 'ssbhesabix' ), - 'refunded' => __( 'Refunded', 'ssbhesabix' ), - 'failed' => __( 'Failed', 'ssbhesabix' ), - 'checkout-draft' => __( 'Draft', 'ssbhesabix' ), - ), - ); - - $fields[] = array( - 'title' => __( "Invoice's Project", 'ssbhesabix' ), - 'id' => 'ssbhesabix_invoice_project', - 'type' => 'select', - 'options' => $projects, - ); - - $fields[] = array( - 'title' => __( "Invoice's Salesman", 'ssbhesabix' ), - 'id' => 'ssbhesabix_invoice_salesman', - 'type' => 'select', - 'options' => $salesmen, - ); - - $fields[] = array( - 'title' => __( "Invoice Salesman Percentage", 'ssbhesabix' ), - 'id' => 'ssbhesabix_invoice_salesman_percentage', - 'type' => 'text', - 'placeholder' => __("Invoice Salesman Percentage", 'ssbhesabix'), - ); - - $fields[] = array( - 'title' => '', - 'desc' => __('Save invoice in draft mode in Hesabix', 'ssbhesabix'), - 'id' => 'ssbhesabix_invoice_draft_save_in_hesabix', - 'type' => 'checkbox', - 'default' => 'no' - ); - - $fields[] = array( - 'title' => __('Save Freight', 'ssbhesabix'), - 'id' => 'ssbhesabix_invoice_freight', - 'type' => 'radio', - 'options' => [ - 0 => __("Save as Freight", 'ssbhesabix'), - 1 => __("Save as a Service", 'ssbhesabix') - ], - ); - - $fields[] = array( - 'title' => __('Service Code For Freight', 'ssbhesabix'), - 'id' => 'ssbhesabix_invoice_freight_code', - 'type' => 'text', - 'placeholder' => __('Enter Freight Code', 'ssbhesabix'), - ); - - if(is_plugin_active( 'dokan-lite/dokan.php' )){ - $fields[] = array( - 'title' => __( "Submit invoice base on Dokan orders", 'ssbhesabix' ), - 'id' => 'ssbhesabix_invoice_dokan', - 'type' => 'radio', - 'options' => [0 => __( "Inactive", 'ssbhesabix' ), - 1 => __( "Submit parent order", 'ssbhesabix' ), - 2 => __( "Submit children orders", 'ssbhesabix' )], - 'default' => 0 - ); - } - - $fields[] = array('type' => 'sectionend', 'id' => 'invoice_options'); - - return $fields; - } -//============================================================================================= - public static function ssbhesabix_invoice_setting() { - $ssbhesabf_setting_fields = self::ssbhesabix_invoice_setting_fields(); - $Html_output = new Ssbhesabix_Html_output(); - ?> - -
- توجه
- در اینجا تعیین کنید که فاکتور سفارش در چه مرحله ای در حسابیکس ثبت شود. - و چه زمان برای یک سفارش فاکتور برگشت از فروش ثبت شود. -
- در صورت انتخاب ذخیره هزینه حمل و نقل به عنوان یک خدمت، ابتدا باید یک خدمت در حسابیکس تعریف کنید و کد مربوط به آن را در فیلد کد خدمت حمل و نقل وارد و ذخیره نمایید. -
- فیلد "ذخیره هزینه به عنوان خدمت" برای سامانه مودیان مالیاتی می باشد. -
- توجه کنید که مقدار این فیلد به درستی وارد شده باشد تا در ثبت فاکتور مشکلی ایجاد نشود. -
-
- init( $ssbhesabf_setting_fields ); ?> -

- -

- alert("کد خدمت حمل و نقل تعریف نشده است")'; - } - ?> -
- save_fields( $ssbhesabf_setting_fields ); - } -//============================================================================================= - public static function ssbhesabix_payment_setting_fields() { - $banks = Ssbhesabix_Setting::ssbhesabix_get_banks(); - $cashes = Ssbhesabix_Setting::ssbhesabix_get_cashes(); - $payInputValue = array_merge($banks,$cashes); - - $payment_gateways = new WC_Payment_Gateways; - $available_payment_gateways = $payment_gateways->get_available_payment_gateways(); - - $fields[] = array( - 'title' => __( 'Payment methods Settings', 'ssbhesabix' ), - 'type' => 'title', - 'desc' => '', - 'id' => 'payment_options' - ); - - $fields[] = array( - 'title' => __( 'Add payment in which status', 'ssbhesabix' ), - 'id' => 'ssbhesabix_payment_status', - 'type' => 'multiselect', - 'options' => array( - 'pending' => __( 'Pending payment', 'ssbhesabix' ), - 'processing' => __( 'Processing', 'ssbhesabix' ), - 'on-hold' => __( 'On hold', 'ssbhesabix' ), - 'completed' => __( 'Completed', 'ssbhesabix' ), - 'cancelled' => __( 'Cancelled', 'ssbhesabix' ), - 'refunded' => __( 'Refunded', 'ssbhesabix' ), - 'failed' => __( 'Failed', 'ssbhesabix' ), - 'checkout-draft' => __( 'Draft', 'ssbhesabix' ), - ), - ); - - - foreach ( $available_payment_gateways as $gateway ) { - $fields[] = array( - 'title' => $gateway->title, - 'id' => 'ssbhesabix_payment_method_' . $gateway->id, - 'type' => 'select', - 'options' => $payInputValue - ); - } - - $fields[] = array( - 'title' => __('Default Payment Gateway By Using this Option, all Invoices Will Have this Payment Gateway as Their Payment Gateway', 'ssbhesabix'), - 'id' => 'ssbhesabix_payment_option', - 'type' => 'radio', - 'options' => [ - 'yes' => __("Save Default Bank as the Payment Gateway", "ssbhesabix"), - 'no' => __("Save Other Payment Methods as the Payment Gateway", "ssbhesabix"), - ], - 'default' => 'no' - ); - - $fields[] = array( - 'title' => __( "Invoice Transaction Fee Percentage", 'ssbhesabix' ), - 'id' => 'ssbhesabix_invoice_transaction_fee', - 'type' => 'text', - 'placeholder' => __("Invoice Transaction Fee Percentage", 'ssbhesabix'), - 'default' => '0' - ); - - $fields[] = array( - 'title' => __( "Submit Cash in Transit", 'ssbhesabix' ), - 'id' => 'ssbhesabix_cash_in_transit', - 'desc' => __( "Submit Invoice Receipt Cash in Transit", 'ssbhesabix' ), - 'type' => 'checkbox', - 'default' => 'no' - ); - - $fields[] = array( - 'title' => __('Default Bank Code', 'ssbhesabix'), - 'id' => 'ssbhesabix_default_payment_method_code', - 'type' => 'text', - 'placeholder' => __('Enter Bank Code', 'ssbhesabix') - ); - - $fields[] = array( - 'title' => __('Default Bank Name', 'ssbhesabix'), - 'id' => 'ssbhesabix_default_payment_method_name', - 'type' => 'text', - 'placeholder' => __('Enter Bank Name', 'ssbhesabix') - ); - - $fields[] = array( 'type' => 'sectionend', 'id' => 'payment_options' ); - - return $fields; - } -//============================================================================================= - public static function ssbhesabix_payment_setting() { - $ssbhesabf_setting_fields = self::ssbhesabix_payment_setting_fields(); - $Html_output = new Ssbhesabix_Html_output(); - ?> -
- توجه
- در اینجا تعیین کنید که رسید دریافت وجه فاکتور در چه وضعیتی ثبت شود - و در هر روش پرداخت، رسید در چه بانکی و یا صندوقی ثبت شود. -
- بانک پیش فرض، جهت کاربرانی می باشد که به هر دلیلی روش های پرداخت وکامرس در اینجا نمایش داده نمی شود. در این صورت با انتخاب بانک و ثبت کد آن، تمامی دریافت ها در آن بانک ثبت خواهد شد -
-
- init( $ssbhesabf_setting_fields ); ?> -

- -

- alert("کد بانک پیش فرض تعریف نشده است")'; - } - - if(get_option("ssbhesabix_cash_in_transit") == "yes" || get_option("ssbhesabix_cash_in_transit") == "1") { - $func = new Ssbhesabix_Admin_Functions(); - $cashInTransitFullPath = $func->getCashInTransitFullPath(); - if(!$cashInTransitFullPath) { - HesabixLogService::writeLogStr("Cash in Transit is not Defined in Hesabix ---- وجوه در راه در حسابیکس یافت نشد"); - echo ' - '; - } - } - ?> -
- save_fields( $ssbhesabf_setting_fields ); - } -//============================================================================================= - public static function ssbhesabix_api_setting_fields() { - $fields[] = array( - 'title' => __( 'API Settings', 'ssbhesabix' ), - 'type' => 'title', - 'desc' => '', - 'id' => 'api_options' - ); - - $fields[] = array( - 'title' => __( 'API Key', 'ssbhesabix' ), - 'desc' => __( 'Find API key in Setting->Financial Settings->API Menu', 'ssbhesabix' ), - 'id' => 'ssbhesabix_account_api', - 'type' => 'text', - ); - - $fields[] = array( - 'title' => __( 'API Address', 'ssbhesabix' ), - 'id' => 'ssbhesabix_api_address', - 'type' => 'select', - 'options' => array( - "0" => "hesabix.ir", - "1" => "next.hesabix.ir" - ) - ); - - $fields[] = array( 'type' => 'sectionend', 'id' => 'api_options' ); - - return $fields; - } -//============================================================================================= - public static function ssbhesabix_api_setting() { - $businessInfo = self::getSubscriptionInfo(); - $isBusinessInfo = false; - if ( $businessInfo["expireDate"] != '' && $businessInfo["expireDate"] != null ) { - $isBusinessInfo = true; - $expireDate = strtotime( $businessInfo["expireDate"] ); - $expireDateStr = date( "Y/m/d", $expireDate ); - } - - $ssbhesabf_setting_fields = self::ssbhesabix_api_setting_fields(); - $Html_output = new Ssbhesabix_Html_output(); - ?> -
- توجه
-
    -
  • - برای اتصال به API حسابیکس و فعال شدن این افزونه باید در اینجا - کلید API و توکن ورود به کسب و کار خود را وارد کنید. -
  • -
  • - برای پیدا کردن توکن ورود و کلید API، در حسابیکس به قسمت تنظیمات، تنظیمات API مراجعه کنید. -
  • -
  • - اگر می خواهید کسب و کار دیگری را به افزونه متصل کنید، ابتدا باید یک بار افزونه را - حذف و مجدد نصب کنید تا جدول ارتباطات کسب و کار قبلی با افزونه حذف گردد. -
  • -
-
-
- اطلاعات کسب و کار -
-
نام کسب و کار:
-
-
طرح:
-
-
-
-
اعتبار سند:
-
-
تاریخ انقضا:
-
-
-
- -
- هشدار
- برای اتصال یک کسب و کار دیگر به افزونه، ابتدا باید یک بار افزونه را حذف و مجدد - نصب کنید تا جدول ارتباطات افزونه با کسب و کار قبل حذف گردد. -
- -
- init( $ssbhesabf_setting_fields ); ?> -

- -

-
- save_fields( $ssbhesabf_setting_fields ); - - Ssbhesabix_Setting::ssbhesabix_set_webhook(); - } -//============================================================================================= - public static function ssbhesabix_export_setting() { - // Export - Bulk product export offers - $productExportResult = ( isset( $_GET['productExportResult'] ) ) ? wc_clean( $_GET['productExportResult'] ) : null; - $productImportResult = ( isset( $_GET['productImportResult'] ) ) ? wc_clean( $_GET['productImportResult'] ) : null; - $error = ( isset( $_GET['error'] ) ) ? wc_clean( $_GET['error'] ) : null; - - if ( ! is_null( $productExportResult ) && $productExportResult === 'true' ) { - $processed = ( isset( $_GET['processed'] ) ) ? wc_clean( $_GET['processed'] ) : null; - if ( $processed == 0 ) { - echo '
'; - echo '

' . __( 'No products were exported, All products were exported or there are no product', 'ssbhesabix' ); - echo '

'; - } else { - echo '
'; - echo '

' . sprintf( __( 'Export products completed. %s products added/updated.', 'ssbhesabix' ), $processed ); - echo '

'; - } - } elseif ( $productExportResult === 'false' ) { - if ( ! is_null( $error ) && $error === '-1' ) { - echo '
'; - echo '

' . __( 'Export products fail. Hesabix has already contained products.', 'ssbhesabix' ); - echo '

'; - } else { - echo '
'; - echo '

' . __( 'Export products fail. Please check the log file.', 'ssbhesabix' ); - echo '

'; - } - } - - if ( ! is_null( $productImportResult ) && $productImportResult === 'true' ) { - $processed = ( isset( $_GET['processed'] ) ) ? wc_clean( $_GET['processed'] ) : null; - if ( $processed == 0 ) { - echo '
'; - echo '

' . __( 'No products were imported, All products were imported or there are no product', 'ssbhesabix' ); - echo '

'; - } else { - echo '
'; - echo '

' . sprintf( __( 'Import products completed. %s products added/updated.', 'ssbhesabix' ), $processed ); - echo '

'; - } - } elseif ( $productImportResult === 'false' ) { - echo '
'; - echo '

' . __( 'Import products fail. Please check the log file.', 'ssbhesabix' ); - echo '

'; - } - - // Export - Product opening quantity export offers - $productOpeningQuantityExportResult = ( isset( $_GET['productOpeningQuantityExportResult'] ) ) ? wc_clean( $_GET['productOpeningQuantityExportResult'] ) : null; - if ( ! is_null( $productOpeningQuantityExportResult ) && $productOpeningQuantityExportResult === 'true' ) { - echo '
'; - echo '

' . __( 'Export product opening quantity completed.', 'ssbhesabix' ); - echo '

'; - } elseif ( ! is_null( $productOpeningQuantityExportResult ) && $productOpeningQuantityExportResult === 'false' ) { - $shareholderError = ( isset( $_GET['shareholderError'] ) ) ? wc_clean( $_GET['shareholderError'] ) : null; - $noProduct = ( isset( $_GET['noProduct'] ) ) ? wc_clean( $_GET['noProduct'] ) : null; - if ( $shareholderError == 'true' ) { - echo '
'; - echo '

' . __( 'Export product opening quantity fail. No Shareholder exists, Please define Shareholder in Hesabix', 'ssbhesabix' ); - echo '

'; - } elseif ( $noProduct == 'true' ) { - echo '
'; - echo '

' . __( 'No product available for Export product opening quantity.', 'ssbhesabix' ); - echo '

'; - } else { - echo '
'; - echo '

' . __( 'Export product opening quantity fail. Please check the log file.', 'ssbhesabix' ); - echo '

'; - } - } - - // Export - Bulk customer export offers - $customerExportResult = ( isset( $_GET['customerExportResult'] ) ) ? wc_clean( $_GET['customerExportResult'] ) : null; - - if ( ! is_null( $customerExportResult ) && $customerExportResult === 'true' ) { - $processed = ( isset( $_GET['processed'] ) ) ? wc_clean( $_GET['processed'] ) : null; - if ( $processed == 0 ) { - echo '
'; - echo '

' . __( 'No customers were exported, All customers were exported or there are no customer', 'ssbhesabix' ); - echo '

'; - } else { - echo '
'; - echo '

' . sprintf( __( 'Export customers completed. %s customers added.', 'ssbhesabix' ), $processed ); - echo '

'; - } - } elseif ( ! is_null( $customerExportResult ) && $customerExportResult === 'false' ) { - if ( ! is_null( $error ) && $error === '-1' ) { - echo '
'; - echo '

' . __( 'Export customers fail. Hesabix has already contained customers.', 'ssbhesabix' ); - echo '

'; - } else { - echo '
'; - echo '

' . __( 'Export customers fail. Please check the log file.', 'ssbhesabix' ); - echo '

'; - } - } - - ?> -
-

-
-
-
-
-
- -
- -
-
-

-
-
-
-
- -
    -
  • با انجام این عملیات محصولات لینک نشده از فروشگاه وارد حسابیکس می شوند.
  • -
  • با انجام این عملیات موجودی محصولات وارد حسابیکس نمی شود و برای وارد کردن موجودی محصولات - فروشگاه - در حسابیکس، باید از گزینه استخراج موجودی اول دوره استفاده کنید. -
  • -
-
-
-
- -
-
-
- -
- -
-
-

-
-
-
-
- -
    -
  • با انجام این عملیات مشتریان لینک نشده از فروشگاه وارد حسابیکس می شوند.
  • -
  • - اگر یک مشتری بیش از یک بار وارد حسابیکس شده است می توانید از گزینه ادغام تراکنش ها در حسابیکس - استفاده کنید. -
  • -
-
-
-
- -
-
-
- -
- -
-
-

- -

-
-
-
-
- -
    -
  • با انجام این عملیات محصولات لینک نشده از حسابیکس وارد فروشگاه می شوند.
  • -
  • اگر محصولات از قبل هم در فروشگاه تعریف شده اند و هم در حسابیکس و به هم لینک نشده اند باید از - گزینه - همسان سازی دستی محصولات استفاده کنید. -
  • -
  • محصولات در وضعیت خصوصی وارد فروشگاه می شوند و سپس هر زمان مایل بودید می توانید وضعیت را به - منتشر شده تغییر دهید. -
  • -
  • تمامی محصولات بعنوان محصول ساده (و نه متغیر) وارد فروشگاه می شوند.
  • -
-
-
-
- '; - echo '

' . __( 'Sync completed, All hesabix changes synced successfully.', 'ssbhesabix' ); - echo ''; - } - - // Sync - Bulk product sync offers - $productSyncResult = ( isset( $_GET['productSyncResult'] ) ) ? wc_clean( $_GET['productSyncResult'] ) : null; - if ( ! is_null( $productSyncResult ) && $productSyncResult == 'true' ) { - echo '

'; - echo '

' . __( 'Sync completed, All products price/quantity synced successfully.', 'ssbhesabix' ); - echo '

'; - } elseif ( ! is_null( $productSyncResult ) && ! $productSyncResult == 'false' ) { - echo '
'; - echo '

' . __( 'Sync products fail. Please check the log file.', 'ssbhesabix' ); - echo '

'; - } - - // Sync - Bulk invoice sync offers - $orderSyncResult = ( isset( $_GET['orderSyncResult'] ) ) ? wc_clean( $_GET['orderSyncResult'] ) : null; - - if ( ! is_null( $orderSyncResult ) && $orderSyncResult === 'true' ) { - $processed = ( isset( $_GET['processed'] ) ) ? wc_clean( $_GET['processed'] ) : null; - echo '
'; - echo '

' . sprintf( __( 'Order sync completed. %s order added.', 'ssbhesabix' ), $processed ); - echo '

'; - } elseif ( ! is_null( $orderSyncResult ) && $orderSyncResult === 'false' ) { - $fiscal = ( isset( $_GET['fiscal'] ) ) ? wc_clean( $_GET['fiscal'] ) : false; - - if ( $fiscal === 'true' ) { - echo '
'; - echo '

' . __( 'The date entered is not within the fiscal year.', 'ssbhesabix' ); - echo '

'; - } else { - echo '
'; - echo '

' . __( 'Cannot sync orders. Please enter valid Date format.', 'ssbhesabix' ); - echo '

'; - } - } - - // Sync - Bulk product update - $productUpdateResult = ( isset( $_GET['$productUpdateResult'] ) ) ? wc_clean( $_GET['$productUpdateResult'] ) : null; - if ( ! is_null( $productUpdateResult ) && $productUpdateResult == 'true' ) { - echo '
'; - echo '

' . __( 'Update completed successfully.', 'ssbhesabix' ); - echo '

'; - } elseif ( ! is_null( $productUpdateResult ) && ! $productUpdateResult == 'false' ) { - echo '
'; - echo '

' . __( 'Update failed. Please check the log file.', 'ssbhesabix' ); - echo '

'; - } - - // Sync - Bulk product with filter update in Hesabix - $productUpdateWithFilterResult = ( isset( $_GET['$productUpdateWithFilterResult'] ) ) ? wc_clean( $_GET['$productUpdateWithFilterResult'] ) : null; - if ( ! is_null( $productUpdateWithFilterResult ) && $productUpdateWithFilterResult == 'true' ) { - echo '
'; - echo '

' . __( 'Update completed successfully.', 'ssbhesabix' ); - echo '

'; - } elseif ( ! is_null( $productUpdateWithFilterResult ) && ! $productUpdateWithFilterResult == 'false' ) { - echo '
'; - echo '

' . __( 'Update failed. Please check the log file.', 'ssbhesabix' ); - echo '

'; - } - ?> - -
-

' . $storeProductsCount . '' ?>

-

' . $hesabixProductsCount . '' ?>

-

' . $linkedProductsCount . '' ?>

-
- -
-

-
- -
-
-
-
- -
- -
-
-

-
- -
    -
  • با انجام این عملیات کالاها، مشتریان و سفارشاتی که تا کنون در حسابیکس ثبت نشده اند در حسابیکس - ثبت می شوند. -
  • -
  • توجه کنید که بصورت نرمال با فعالسازی افزونه و تکمیل تنظیمات API - این همسان سازی بصورت خودکار انجام می شود و این گزینه صرفاْ برای مواقعی است که به دلایل فنی - مثل قطع اتصال فروشگاه با حسابیکس و یا خطا و باگ این همسان سازی صورت نگرفته است. -
  • -
-
-
-
- -
-
-
- -
- - - - - -
-
-

-
-
-
-
- -
    -
  • با انجام این عملیات موجودی و قیمت محصولات در فروشگاه، بر اساس قیمت و موجودی آنها در حسابیکس - تنظیم می شود. -
  • -
  • این عملیات بر اساس تنظیمات صورت گرفته در تب محصولات انجام می شود.
  • -
-
-
-
- -
-
-
- -
- - -
-
-

-
-
-
-
- -
    -
  • با انجام این عملیات سفارشات فروشگاه که در حسابیکس ثبت نشده اند از تاریخ انتخاب شده بررسی و در - حسابیکس ثبت می شوند. -
  • -
  • توجه کنید که بصورت نرمال با فعالسازی افزونه و تکمیل تنظیمات API - این همسان سازی بصورت خودکار انجام می شود و این گزینه صرفاْ برای مواقعی است که به دلایل فنی - مثل قطع اتصال فروشگاه با حسابیکس و یا خطا و باگ این همسان سازی صورت نگرفته است. -
  • -
-
-
-
- -
-
-
- -
- -
-
-

-
-
-
-
- -
    -
  • با انجام این عملیات ویژگی محصولات مثل نام و قیمت در حسابیکس، بر اساس فروشگاه بروزرسانی می - شود. -
  • -
  • در این عملیات موجودی کالا در حسابیکس تغییری نمی کند و بروز رسانی نمی شود.
  • -
-
-
-
- -
-
-
- -
- -

- -

- -
-
-

-
- -
    -
  • با انجام این عملیات ویژگی محصولات مثل نام و قیمت در حسابیکس، بر اساس فروشگاه در بازه ID مشخص شده بروزرسانی می - شود. -
  • -
  • در این عملیات موجودی کالا در حسابیکس تغییری نمی کند و بروز رسانی نمی شود.
  • -
  • بازه ID نباید بیشتر از 200 عدد باشد.
  • -
-
-
-
- - $storeProductsCount, - "hesabixProductsCount" => $hesabixProductsCount, - "linkedProductsCount" => $linkedProductsCount - ); - } -//============================================================================================= - public static function getProductCountsInHesabix() { - $hesabix = new Ssbhesabix_Api(); - - $filters = array( array( "Property" => "ItemType", "Operator" => "=", "Value" => 0 ) ); - - $response = $hesabix->itemGetItems( array( 'Take' => 1, 'Filters' => $filters ) ); - if ( $response->Success ) { - return $response->Result->FilteredCount; - } else { - return 0; - } - } -//============================================================================================= - public static function getLinkedProductsCount() { - global $wpdb; - - return $wpdb->get_var( "SELECT COUNT(*) FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `obj_type` = 'product'" ); - } -//============================================================================================= - public static function getProductCountsInStore() { - global $wpdb; - - return $wpdb->get_var( "SELECT COUNT(*) FROM `" . $wpdb->prefix . "posts` WHERE `post_type` IN ('product','product_variation') AND `post_status` IN ('publish', 'private', 'draft') " ); - } -//============================================================================================= - public static function getSubscriptionInfo() { - $businessName = ''; - $hesabix = new Ssbhesabix_Api(); - $response = $hesabix->settingGetSubscriptionInfo(); - if ( $response->Success ) { - $businessName = $response->Result->name; - } - return array( - "businessName" => $businessName, - ); - } -//============================================================================================= - public static function ssbhesabix_set_webhook() { - $url = get_site_url() . '/index.php?ssbhesabix_webhook=1&token=' . substr( wp_hash( AUTH_KEY . 'ssbhesabix/webhook' ), 0, 10 ); - - $hookPassword = get_option( 'ssbhesabix_webhook_password' ); - - $ssbhesabix_api = new Ssbhesabix_Api(); - $response = $ssbhesabix_api->settingSetChangeHook( $url, $hookPassword ); - - if ( is_object( $response ) ) { - if ( $response->Success ) { - update_option( 'ssbhesabix_live_mode', 1 ); - update_option( 'ssbhesabix_account_bid', $response->bid ); - update_option( 'ssbhesabix_account_year', $response->year ); - //set the last log ID if is not set - $lastChanges = get_option( 'ssbhesabix_last_log_check_id' ); - if ( ! $lastChanges ) { - $lastChanges = 0; - } - $changes = $ssbhesabix_api->settingGetChanges( $lastChanges ); - if ( $changes->Success ) { - if ( get_option( 'ssbhesabix_last_log_check_id' ) == 0 ) { - $lastChange = end( $changes->Result ); - update_option( 'ssbhesabix_last_log_check_id', $lastChange->Id ); - } - } else { - echo '
'; - echo '

' . __( 'Cannot check the last change ID. Error Message: ', 'ssbhesabix' ) . $changes->ErrorMessage . '

'; - echo '
'; - - HesabixLogService::log( array("Cannot check the last change ID. Error Message: $changes->ErrorMessage. Error Code: $changes->ErrorCode") ); - } - - - //check if date in fiscalYear - if ( Ssbhesabix_Admin_Functions::isDateInFiscalYear( date( 'Y-m-d H:i:s' ) ) === 0 ) { - echo '
'; - echo '

' . __( 'The fiscal year has passed or not arrived. Please check the fiscal year settings in Hesabix.', 'ssbhesabix' ) . '

'; - echo '
'; - - update_option( 'ssbhesabix_live_mode', 0 ); - } - - //check the Hesabix default currency - $default_currency = $ssbhesabix_api->settingGetCurrency(); - if ( $default_currency->Success ) { - $woocommerce_currency = get_woocommerce_currency(); - $hesabix_currency = $default_currency->Result->moneyName; - if ( $hesabix_currency == $woocommerce_currency || ( $hesabix_currency == 'IRR' && $woocommerce_currency == 'IRT' ) || ( $hesabix_currency == 'IRT' && $woocommerce_currency == 'IRR' ) ) { - update_option( 'ssbhesabix_hesabix_default_currency', $hesabix_currency ); - } else { - update_option( 'ssbhesabix_hesabix_default_currency', 0 ); - update_option( 'ssbhesabix_live_mode', 0 ); - - echo '
'; - echo '

' . __( 'Hesabix and WooCommerce default currency must be same.', 'ssbhesabix' ); - echo '

'; - } - } else { - echo '
'; - echo '

' . __( 'Cannot check the Hesabix default currency. Error Message: ', 'ssbhesabix' ) . $default_currency->ErrorMessage . '

'; - echo '
'; - - HesabixLogService::log( array( "Cannot check the Hesabix default currency. Error Message: $default_currency->ErrorMessage. Error Code: $default_currency->ErrorCode" ) ); - } - - if ( get_option( 'ssbhesabix_live_mode' ) ) { - echo '
'; - echo '

' . __( 'API Setting updated. Test Successfully', 'ssbhesabix' ) . '

'; - echo '
'; - } - } else { - update_option( 'ssbhesabix_live_mode', 0 ); - echo '
'; - echo '

' . __( 'Cannot set Hesabix webHook. Error Message:', 'ssbhesabix' ) . $response->ErrorMessage . '

'; - echo '
'; - HesabixLogService::log( array("Cannot set Hesabix webHook. Error Message: $response->ErrorMessage. Error Code: $response->ErrorCode") ); - } - } else { - update_option( 'ssbhesabix_live_mode', 0 ); - echo '
'; - echo '

' . __( 'Cannot connect to Hesabix servers. Please check your Internet connection', 'ssbhesabix' ) . '

'; - echo '
'; - - HesabixLogService::log( array("Cannot connect to hesabix servers. Check your internet connection" ) ); - } - - return $response; - } -//============================================================================================= - public static function ssbhesabix_get_banks() { - $ssbhesabix_api = new Ssbhesabix_Api(); - $banks = $ssbhesabix_api->settingGetBanks(); - - if ( is_object( $banks ) && $banks->Success ) { - $available_banks = array(); - $available_banks[ - 1 ] = __( 'Choose', 'ssbhesabix' ); - foreach ( $banks->Result as $bank ) { - if ( $bank->Currency == get_woocommerce_currency() || ( get_woocommerce_currency() == 'IRT' && $bank->Currency == 'IRR' ) || ( get_woocommerce_currency() == 'IRR' && $bank->Currency == 'IRT' ) ) { - $available_banks[ 'bank'.$bank->Code ] = $bank->Name . ' - ' . $bank->Branch . ' - ' . $bank->AccountNumber; - } - } - - if ( empty( $available_banks ) ) { - $available_banks[0] = __( 'Define at least one bank in Hesabix', 'ssbhesabix' ); - } - - return $available_banks; - } else { - update_option( 'ssbhesabix_live_mode', 0 ); - - echo '
'; - echo '

' . __( 'Cannot get Banks detail.', 'ssbhesabix' ) . '

'; - echo '
'; - - HesabixLogService::log( array("Cannot get banking information. Error Code: $banks->ErrorCode. Error Message: $banks->ErrorMessage." ) ); - - return array( '0' => __( 'Cannot get Banks detail.', 'ssbhesabix' ) ); - } - } -//============================================================================================= - public static function ssbhesabix_get_cashes() { - $ssbhesabix_api = new Ssbhesabix_Api(); - $cashes = $ssbhesabix_api->settingGetCashes(); - - if ( is_object( $cashes ) && $cashes->Success ) { - $available_cashes = array(); - foreach ( $cashes->Result as $cash ) { - if ( $cash->Currency == get_woocommerce_currency() || ( get_woocommerce_currency() == 'IRT' && $cash->Currency == 'IRR' ) || ( get_woocommerce_currency() == 'IRR' && $cash->Currency == 'IRT' ) ) { - $available_cashes[ 'cash'.$cash->Code ] = $cash->Name; - } - } - return $available_cashes; - } - } - -//============================================================================================= - public static function ssbhesabix_get_salesmen() { - $ssbhesabix_api = new Ssbhesabix_Api(); - $salesmen = $ssbhesabix_api->settingGetSalesmen(); - - if ( is_object( $salesmen ) && $salesmen->Success ) { - $available_salesmen = array(); - $available_salesmen[ - 1 ] = __( 'Choose', 'ssbhesabix' ); - foreach ( $salesmen->Result as $salesman ) { - if ( $salesman->Active ) { - $available_salesmen[ $salesman->Code ] = $salesman->Name; - } - } - - return $available_salesmen; - } else { - update_option( 'ssbhesabix_live_mode', 0 ); - echo '
'; - echo '

' . __( 'Cannot get Salesmen detail.', 'ssbhesabix' ) . '

'; - echo '
'; - HesabixLogService::log( array("Cannot get salesmen information. Error Code: $salesmen->ErrorCode Error Message: .$salesmen->ErrorMessage.") ); - - return array( '0' => __( 'Cannot get salesmen detail.', 'ssbhesabix' ) ); - } - } -//============================================================================================= - public static function ssbhesabix_log_setting() { - $cleanLogResult = ( isset( $_GET['cleanLogResult'] ) ) ? wc_clean( $_GET['cleanLogResult'] ) : null; - - if ( ! is_null( $cleanLogResult ) && $cleanLogResult === 'true' ) { - echo '
'; - echo '

' . __( 'The log file was cleared.', 'ssbhesabix' ) . '

'; - echo '
'; - } elseif ( $cleanLogResult === 'false' ) { - echo '
'; - echo '

' . __( 'Log file not found.', 'ssbhesabix' ) . '

'; - echo '
'; - } - - self::ssbhesabix_tab_log_html(); - } -//============================================================================================= - public static function ssbhesabix_tab_log_html() { - ?> -
-
- توجه فرمایید با زدن دکمه پاک کردن کل لاگ ها، تمامی فایل های لاگ ذخیره شده پاک می شوند. -
- در صورت نیاز به پاک کردن فایل لاگ جاری می توانید از دکمه پاک کردن لاگ جاری، زمانی که فایل لاگ مدنظر انتخاب شده است، استفاده کنید. -
- فهرست تاریخچه لاگ ها، لاگ های موجود در سیستم در بازه 10 روز گذشته را نمایش می دهد. -
-

-
-
- -
-
-
- -
-
-
-
-
- -
- "> - - -
-
-
-
- -
-
- "> - -
-
-
-
-
-
-
-
-
-
- -
- - -
-
-
-
-
-
-
-
-
- -
- - - -
-
-
-
-
- 1000 ) { - - $fileSizeInMb = ( ( filesize( WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d") . '.txt' ) / 1000 ) / 1000 ); - $fileSizeInMb = round( $fileSizeInMb, 2 ); - - - $str = __( 'The log file size is large, clean log file.', 'ssbhesabix' ); - - echo '
' . - '

' . $str . ' (' . $fileSizeInMb . 'MB)' . '

' - . '
'; - - } else if ( file_exists( WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d") . '.txt' ) ) { - - $URL = WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d") . '.txt'; - $logFileContent = HesabixLogService::readLog($URL); - } - - echo '
'. - '
-

' . __("Log History", "ssbhesabix") . '

-
-
    '; - for($i = 0 ; $i < 10 ; $i++) { - if( file_exists( WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d", strtotime(-$i."day")) . '.txt' ) ) { - echo '
  • '; - } - } - echo ' -
-
-
'; - echo ''; - echo '
'; -//--------------------------------------- - if(isset($_POST["changeLogFile"])) { - echo - ''; - - $URL = WP_CONTENT_DIR . '/ssbhesabix-' . $_POST["changeLogFile"] . '.txt'; - $logFileContent = HesabixLogService::readLog($URL); - - echo '
'. - '
-

' . __("Log History", "ssbhesabix") . '

-
-
    '; - for($i = 0 ; $i < 10 ; $i++) { - if( file_exists( WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d", strtotime(-$i."day")) . '.txt' ) ) { - echo '
  • '; - } - } - echo ' -
-
-
'; - echo ''; - echo '
'; - } -//--------------------------------------- - if(isset($_POST["deleteLogFiles"])) { - $prefix = WP_CONTENT_DIR . '/ssbhesabix-'; - - $files = glob($prefix . '*'); - if ($files) { - foreach ($files as $file) { - if (is_file($file)) { - if (unlink($file)) { - header("refresh:0"); - } else { - HesabixLogService::writeLogStr("Unable to delete the file"); - } - } - } - } else { - HesabixLogService::writeLogStr("No files found"); - } - } -//--------------------------------------- - if(isset($_POST["ssbhesabix-log-clean-submit"])) { - if($_POST["currentLogFileDate"]) { - $file = WP_CONTENT_DIR . '/ssbhesabix-' . $_POST["currentLogFileDate"] . '.txt'; - } else { - $file = WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d") . '.txt'; - } - if (is_file($file)) { - if (unlink($file)) { - HesabixLogService::writeLogStr("Selected Log File Deleted"); - header("refresh:0"); - } else { - HesabixLogService::writeLogStr("Unable to delete the file"); - } - } - } -//--------------------------------------- - if(isset($_POST["ssbhesabix-delete-logs-between-two-dates"])) { - $startDate = $_POST["ssbhesabix_delete_log_date_from"]; - $endDate = $_POST["ssbhesabix_delete_log_date_to"]; - - $directory = WP_CONTENT_DIR . '/ssbhesabix-'; - $files = glob($directory . '*'); - if($files) { - foreach ($files as $file) { - if(is_file($file)) { - $fileDate = substr($file, strlen($directory), 10); - $dateObj = DateTime::createFromFormat('Y-m-d', $fileDate); - $startObj = DateTime::createFromFormat('Y-m-d', $startDate); - $endObj = DateTime::createFromFormat('Y-m-d', $endDate); - - if ($dateObj >= $startObj && $dateObj <= $endObj) { - HesabixLogService::writeLogStr("Log Files deleted"); - unlink($file); - } - } - } - } - header("refresh:0"); - } -//--------------------------------------- - if(isset($_POST["ssbhesabix-find-log-submit"])) { - echo - ''; - - $URL = WP_CONTENT_DIR . '/ssbhesabix-' . $_POST["ssbhesabix_find_log_date"] . '.txt'; - if ( file_exists( WP_CONTENT_DIR . '/ssbhesabix-' . $_POST["ssbhesabix_find_log_date"] . '.txt' ) && - ( filesize( WP_CONTENT_DIR . '/ssbhesabix-' . $_POST["ssbhesabix_find_log_date"] . '.txt' ) / 1000 ) < 1000 ) { - $logFileContent = HesabixLogService::readLog($URL); - } - - - echo '
'. - '
-

' . __("Log History", "ssbhesabix") . '

-
-
    '; - for($i = 0 ; $i < 10 ; $i++) { - if( file_exists( WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d", strtotime(-$i."day")) . '.txt' ) ) { - echo '
  • '; - } - } - echo ' -
-
-
'; - echo ''; - echo '
'; - } - ?> -
- settingGetWarehouses(); - - if ( is_object( $warehouses ) && $warehouses->ErrorCode == 199 ) { - $available_warehouses = array(); - $available_warehouses[ - 1 ] = __( 'Accounting quantity (Total inventory)', 'ssbhesabix' ); - - return $available_warehouses; - } - - if ( is_object( $warehouses ) && $warehouses->Success ) { - $available_warehouses = array(); - $available_warehouses[ - 1 ] = __( 'Accounting quantity (Total inventory)', 'ssbhesabix' ); - foreach ( $warehouses->Result as $warehouse ) { - $available_warehouses[ $warehouse->Code ] = $warehouse->Name; - } - - return $available_warehouses; - } else { - update_option( 'ssbhesabix_live_mode', 0 ); - echo '
'; - echo '

' . __( 'Cannot get warehouses.', 'ssbhesabix' ) . '

'; - echo '
'; - HesabixLogService::log( array("Cannot get warehouses. Error Code: $warehouses->ErrorCode. Error Message: .$warehouses->ErrorMessage.") ); - - return array( '0' => __( 'Cannot get warehouses.', 'ssbhesabix' ) ); - } - } - -} - -Ssbhesabix_Setting::init(); + + * @author HamidReza Gharahzadeh + * @author Sepehr Najafi + */ +class Ssbhesabix_Setting { + + /** + * Hook in methods + * @since 1.0.0 + * @access static + */ +//========================================================================================================================== + public static function init() { + add_action( 'ssbhesabix_home_setting', array( __CLASS__, 'ssbhesabix_home_setting' ) ); + + add_action( 'ssbhesabix_catalog_setting', array( __CLASS__, 'ssbhesabix_catalog_setting' ) ); + add_action( 'ssbhesabix_catalog_setting_save_field', array( + __CLASS__, + 'ssbhesabix_catalog_setting_save_field' + ) ); + + add_action( 'ssbhesabix_customers_setting', array( __CLASS__, 'ssbhesabix_customers_setting' ) ); + add_action( 'ssbhesabix_customers_setting_save_field', array( + __CLASS__, + 'ssbhesabix_customers_setting_save_field' + ) ); + + add_action( 'ssbhesabix_invoice_setting', array( __CLASS__, 'ssbhesabix_invoice_setting' ) ); + add_action( 'ssbhesabix_invoice_setting_save_field', array( + __CLASS__, + 'ssbhesabix_invoice_setting_save_field' + ) ); + + add_action( 'ssbhesabix_payment_setting', array( __CLASS__, 'ssbhesabix_payment_setting' ) ); + add_action( 'ssbhesabix_payment_setting_save_field', array( + __CLASS__, + 'ssbhesabix_payment_setting_save_field' + ) ); + + add_action( 'ssbhesabix_api_setting', array( __CLASS__, 'ssbhesabix_api_setting' ) ); + add_action( 'ssbhesabix_api_setting_save_field', array( __CLASS__, 'ssbhesabix_api_setting_save_field' ) ); + + add_action( 'ssbhesabix_export_setting', array( __CLASS__, 'ssbhesabix_export_setting' ) ); + + add_action( 'ssbhesabix_sync_setting', array( __CLASS__, 'ssbhesabix_sync_setting' ) ); + + add_action( 'ssbhesabix_log_setting', array( __CLASS__, 'ssbhesabix_log_setting' ) ); + + add_action( 'ssbhesabix_extra_setting', array( __CLASS__, 'ssbhesabix_extra_setting' ) ); + add_action( 'ssbhesabix_extra_setting_save_field', array( + __CLASS__, + 'ssbhesabix_extra_setting_save_field' + ) ); + } +//========================================================================================================================== + public static function ssbhesabix_home_setting() { + ?> +

+

+

+ +
+ هشدارها +
+
    +
  • * + افزونه حسابیکس از کد کالاها و مشتریان و از شماره فاکتور جهت شناسایی آنها استفاده می کند، + بنابراین پس از ثبت کالاها و مشتریان در حسابیکس کد آنها را در حسابیکس تغییر ندهید، و همچنین پس از ثبت + فاکتور، + شماره فاکتور را در حسابیکس نباید تغییر دهید. +
  • +
  • + * با حذف افزونه از وردپرس، جدول ارتباط بین افزونه و حسابیکس نیز از دیتابیس وردپرس حذف می شود + و کلیه ارتباطات از بین می رود. +
  • +
+
+
+ نکات +
+
    +
  • * + پیشنهاد می شود قبل از شروع کار با افزونه، حتما ویدیو خودآموز افزونه را مشاهده نمایید. +
  • +
+
+ +
+
+

+ + +
+
+

+
+ نصب افزونه +
00:00 +
+
+ اتصال افزونه به حسابیکس +
01:15 +
+
+ تنظیمات افزونه +
04:06 +
+
+ تعریف محصول و لینک کردن محصول به حسابیکس +
08:40 +
+
+ خروجی محصولات به حسابیکس +
22:58 +
+
+ خروجی موجودی اول دوره محصولات به حسابیکس +
24:22 +
+
+ خروجی مشتریان +
24:55 +
+
+ ورود محصولات از حسابیکس به فروشگاه +
25:25 +
+
+ همسان سازی قیمت و موجودی محصولات +
26:32 +
+
+ همسان سازی سفارشات +
27:25 +
+
+ بروزرسانی محصولات در حسابیکس بر اساس فروشگاه +
29:18 +
+
+ سفارشات و ثبت فاکتور در حسابیکس +
30:05 +
+
+ پشتیبان گیری از جدول افزونه در دیتابیس +
35:20 +
+
+ لاگ رویدادها و خطاها +
41:42 +
+
+ حذف محصولات +
50:46 +
+
+ محصول پیش نویس +
52:23 +
+
+
+ + __('Enable or Disable Debug Mode', 'ssbhesabix'), + 'id' => 'ssbhesabix_debug_mode_checkbox', + 'default' => 'no', + 'type' => 'checkbox', + ); + + return $fields; + } +//============================================================================================== + public static function ssbhesabix_extra_setting() { + ?> +
+
    +
  • + این صفحه برای تنظیمات پیشرفته افزونه می باشد +
  • +
+
+ +

+ + +
+ + + + Plugin Version + Server PHP Version + Plugin PHP Version Tested Up To + + + + + ' . $plugin_version . ' + ' . $server_php_version . ' + ' . $plugin_php_version . ' + + + ' + + . ''; + ?> +
+ init( $ssbhesabf_setting_fields ); ?> +
+ + + : 500 +
+
+
+ + + : 200 +
+
+
+ + + : 100 +
+
+
+ + + : 500 +
+
+
+ + + : 500 +
+
+

+ +

+
+

بروزرسانی ID آخرین تغییر

+

این گزینه تغییرات را به آخرین ID بروزرسانی می کند.

+ +
+
+
+

افزودن دستی محصول به حسابیکس

+

در فیلد کد ووکامرس، کد محصول بدون لینک را که می خواهید در حسابیکس ذخیره کنید، وارد نمایید.

+

در فیلد کد حسابیکس، کد حسابداری را وارد نمایید به طوری که محصولی با این کد حسابداری وجود نداشته باشد تا محصول ووکامرس انتخابی با این کد در حسابیکس اضافه شود.

+

در صورتی که محصول ساده است به جای کد متغیر عدد صفر را قرار دهید.

+ + + + + + + + + + + +
+
+ syncLastChangeID(); + } + + if(isset($_POST['ssbhesabix_save_product_manually_to_hesabix'])) { + $func = new Ssbhesabix_Admin_Functions(); + if(empty($_POST['attribute_code'])) { + $_POST['attribute_code'] = 0; + } + if (empty($_POST['woocommerce_code'])) { + echo ""; + } else { + if(isset($_POST['hesabix_code']) && isset($_POST['woocommerce_code']) && isset($_POST['attribute_code'])) { + $result = $func->SaveProductManuallyToHesabix($_POST['woocommerce_code'], $_POST['attribute_code'], $_POST['hesabix_code']); + if($result) { + echo ''; + } else { + echo ''; + } + } + } + } + + if(isset($_POST["ssbhesabix_integration"])) { + if(isset($_POST['ssbhesabix_set_rpp_for_sync_products_into_hesabix'])) update_option('ssbhesabix_set_rpp_for_sync_products_into_hesabix', $_POST['ssbhesabix_set_rpp_for_sync_products_into_hesabix']); + if(isset($_POST['ssbhesabix_set_rpp_for_sync_products_into_woocommerce'])) update_option('ssbhesabix_set_rpp_for_sync_products_into_woocommerce', $_POST['ssbhesabix_set_rpp_for_sync_products_into_woocommerce']); + if(isset($_POST['ssbhesabix_set_rpp_for_import_products'])) update_option('ssbhesabix_set_rpp_for_import_products', $_POST['ssbhesabix_set_rpp_for_import_products']); + if(isset($_POST['ssbhesabix_set_rpp_for_export_products'])) update_option('ssbhesabix_set_rpp_for_export_products', $_POST['ssbhesabix_set_rpp_for_export_products']); + if(isset($_POST['ssbhesabix_set_rpp_for_export_opening_products'])) update_option('ssbhesabix_set_rpp_for_export_opening_products', $_POST['ssbhesabix_set_rpp_for_export_opening_products']); + header('refresh:0'); + } + ?> +
+
+

مشاهده آیتم های جدول ارتباط

+ + + + + + + + + + + + +
+ getWpFaSearch($woocommerce_search_code, $woocommerce_attribute_search_code, $hesabix_search_code, $obj_type_search); + + ?> +
+ + + + + + + + + + + + + + + + + + + + + +
IDنوع آیتمکد حسابیکسکد ووکامرسکد متغیر ووکامرس
id;?>objType;?>idHesabix;?>idWp;?>idWpAttribute;?>
+
+ + save_fields( $ssbhesabf_setting_fields ); + } +//============================================================================================== + public static function ssbhesabix_catalog_setting_fields() { + $warehouses = Ssbhesabix_Setting::ssbhesabix_get_warehouses(); + + $fields[] = array( + 'title' => __( 'Catalog Settings', 'ssbhesabix' ), + 'type' => 'title', + 'desc' => '', + 'id' => 'catalog_options' + ); + + $fields[] = array( + 'title' => __( 'Update Price', 'ssbhesabix' ), + 'desc' => __( 'Update Price after change in Hesabix', 'ssbhesabix' ), + 'id' => 'ssbhesabix_item_update_price', + 'default' => 'no', + 'type' => 'checkbox' + ); + + $fields[] = array( + 'title' => __( 'Update Quantity', 'ssbhesabix' ), + 'desc' => __( 'Update Quantity after change in Hesabix', 'ssbhesabix' ), + 'id' => 'ssbhesabix_item_update_quantity', + 'default' => 'no', + 'type' => 'checkbox' + ); + + $fields[] = array( + 'title' => __( "Update product's quantity based on", 'ssbhesabix' ), + 'id' => 'ssbhesabix_item_update_quantity_based_on', + 'type' => 'select', + 'options' => $warehouses, + ); + + $fields[] = array( + 'title' => "", + 'desc' => __( 'Remove The Titles for Attributes When Saving Product To Hesabix', 'ssbhesabix' ), + 'id' => 'ssbhesabix_remove_attributes_titles', + 'default' => 'no', + 'type' => 'checkbox' + ); + + $fields[] = array( + 'title' => "", + 'desc' => __( 'Do not update purchase and sales titles in hesabix', 'ssbhesabix' ), + 'id' => 'ssbhesabix_do_not_update_titles_in_hesabix', + 'default' => 'no', + 'type' => 'checkbox' + ); + + $fields[] = array( + 'title' => "", + 'desc' => __( 'Do not submit product in Hesabix automatically by saving product in woocommerce', 'ssbhesabix' ), + 'id' => 'ssbhesabix_do_not_submit_product_automatically', + 'default' => 'no', + 'type' => 'checkbox' + ); + + $fields[] = array( + 'title' => "", + 'desc' => __( 'Do not update product price in Hesabix by editing product in woocommerce', 'ssbhesabix' ), + 'id' => 'ssbhesabix_do_not_update_product_price_in_hesabix', + 'default' => 'no', + 'type' => 'checkbox' + ); + + $fields[] = array( + 'title' => "", + 'desc' => __( 'Do not update product barcode in Hesabix by saving product in woocommerce', 'ssbhesabix' ), + 'id' => 'ssbhesabix_do_not_update_product_barcode_in_hesabix', + 'default' => 'no', + 'type' => 'checkbox' + ); + + $fields[] = array( + 'title' => "", + 'desc' => __( 'Do not update product category in Hesabix by saving product in woocommerce', 'ssbhesabix' ), + 'id' => 'ssbhesabix_do_not_update_product_category_in_hesabix', + 'default' => 'no', + 'type' => 'checkbox' + ); + + $fields[] = array( + 'title' => "", + 'desc' => __( 'Do not update product code in Hesabix by saving product in woocommerce', 'ssbhesabix' ), + 'id' => 'ssbhesabix_do_not_update_product_product_code_in_hesabix', + 'default' => 'no', + 'type' => 'checkbox' + ); + + $fields[] = array( + 'title' => "", + 'desc' => __( 'Show Hesabix ID in Products Page', 'ssbhesabix' ), + 'id' => 'ssbhesabix_show_product_code_in_products_page', + 'default' => 'no', + 'type' => 'checkbox' + ); + + $fields[] = array( + 'title' => "", + 'desc' => __( 'Show Hesabix Code in Woocommerce Excel Export', 'ssbhesabix' ), + 'id' => 'ssbhesabix_show_hesabix_code_in_excel_export', + 'default' => 'no', + 'type' => 'checkbox' + ); + + $fields[] = array( + 'title' => "", + 'desc' => __( 'Set Special Sale as Discount in invoice', 'ssbhesabix' ), + 'id' => 'ssbhesabix_set_special_sale_as_discount', + 'default' => 'no', + 'type' => 'checkbox' + ); + + $options_to_update_sale_price = array(); + $options_to_update_sale_price[0] = __( "The Sale price does not change", 'ssbhesabix' ); + $options_to_update_sale_price[1] = __( "The Sale price gets removed", 'ssbhesabix' ); + $options_to_update_sale_price[2] = __( "The sale price get changes in proportion to the regular price", 'ssbhesabix' ); + + $fields[] = array( + 'title' => __( "Update sale price", 'ssbhesabix' ), + 'id' => 'ssbhesabix_item_update_sale_price', + 'type' => 'select', + 'options' => $options_to_update_sale_price, + ); + + $fields[] = array( 'type' => 'sectionend', 'id' => 'catalog_options' ); + + return $fields; + } +//==================================================================================================== + public static function ssbhesabix_catalog_setting() { + $ssbhesabf_setting_fields = self::ssbhesabix_catalog_setting_fields(); + $Html_output = new Ssbhesabix_Html_output(); + ?> +
+ init( $ssbhesabf_setting_fields ); ?> +

+ +

+
+ save_fields( $ssbhesabf_setting_fields ); + } +//============================================================================================= + public static function ssbhesabix_customers_setting_fields() { + + $fields[] = array( + 'title' => __( 'Customers Settings', 'ssbhesabix' ), + 'type' => 'title', + 'desc' => '', + 'id' => 'customer_options' + ); + + $fields[] = array( + 'title' => __( 'Update Customer Address', 'ssbhesabix' ), + 'desc' => __( 'Choose when update Customer address in Hesabix.', 'ssbhesabix' ), + 'id' => 'ssbhesabix_contact_address_status', + 'type' => 'select', + 'options' => array( + '1' => __( 'Use first customer address', 'ssbhesabix' ), + '2' => __( 'update address with Invoice address', 'ssbhesabix' ), + '3' => __( 'update address with Delivery address', 'ssbhesabix' ) + ), + ); + + $fields[] = array( + 'title' => __( 'Customer\'s Group', 'ssbhesabix' ), + 'desc' => __( 'Enter a Customer\'s Group in Hesabix', 'ssbhesabix' ), + 'id' => 'ssbhesabix_contact_node_family', + 'type' => 'text', + 'default' => 'مشتریان فروشگاه آنلاین' + ); + + $fields[] = array( + 'title' => __( 'Save Customer\'s group', 'ssbhesabix' ), + 'desc' => __( 'Automatically save Customer\'s group in hesabix', 'ssbhesabix' ), + 'id' => 'ssbhesabix_contact_automatic_save_node_family', + 'default' => 'yes', + 'type' => 'checkbox' + ); + $fields[] = array( + 'title' => __( 'Customer\'s detail auto save and update', 'ssbhesabix' ), + 'desc' => __( 'Save and update Customer\'s detail automatically in hesabix', 'ssbhesabix' ), + 'id' => 'ssbhesabix_contact_automatically_save_in_hesabix', + 'type' => 'checkbox', + 'default' => 'yes' + ); + + $fields[] = array( 'type' => 'sectionend', 'id' => 'customer_options' ); + + return $fields; + } +//============================================================================================= + public static function ssbhesabix_customers_setting() { + + $ssbhesabf_setting_fields = self::ssbhesabix_customers_setting_fields(); + + $add_fields = get_option( 'ssbhesabix_contact_add_additional_checkout_fields_hesabix', 1 ); + $nationalCodeCheck = get_option( 'ssbhesabix_contact_NationalCode_checkbox_hesabix' ) == 'yes'; + $economicCodeCheck = get_option( 'ssbhesabix_contact_EconomicCode_checkbox_hesabix' ) == 'yes'; + $registrationNumberCheck = get_option( 'ssbhesabix_contact_RegistrationNumber_checkbox_hesabix') == 'yes'; + $websiteCheck = get_option( 'ssbhesabix_contact_Website_checkbox_hesabix') == 'yes'; + + $nationalCodeRequired = get_option( 'ssbhesabix_contact_NationalCode_isRequired_hesabix' ) == 'yes'; + $economicCodeRequired = get_option( 'ssbhesabix_contact_EconomicCode_isRequired_hesabix' ) == 'yes'; + $registrationNumberRequired = get_option( 'ssbhesabix_contact_RegistrationNumber_isRequired_hesabix') == 'yes'; + $websiteRequired = get_option( 'ssbhesabix_contact_Website_isRequired_hesabix') == 'yes'; + + $nationalCodeMetaName = get_option( 'ssbhesabix_contact_NationalCode_text_hesabix', null ) ; + $economicCodeMetaName = get_option( 'ssbhesabix_contact_EconomicCode_text_hesabix', null ) ; + $registrationNumberMetaName = get_option( 'ssbhesabix_contact_RegistrationNumber_text_hesabix', null ); + $websiteMetaName = get_option( 'ssbhesabix_contact_Website_text_hesabix', null ) ; + + $Html_output = new Ssbhesabix_Html_output(); + ?> +
+ init( $ssbhesabf_setting_fields ); ?> + +
+
+ +
+
+
+ > + +
+ +
+ > + +
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
class="form-control" value="yes"> class="form-control" value="yes">
class="form-control" value="yes"> class="form-control" value="yes">
class="form-control" value="yes"> class="form-control" value="yes">
class="form-control" value="yes"> class="form-control" value="yes">
+
+
+ +

+ +

+
+ save_fields( $ssbhesabf_setting_fields ); + // .... + } + +//============================================================================================= + public static function ssbhesabix_invoice_setting_fields() { + $projects = Ssbhesabix_Setting::ssbhesabix_get_projects(); + $salesmen = Ssbhesabix_Setting::ssbhesabix_get_salesmen(); + + $fields[] = array( + 'title' => __( 'Invoice Settings', 'ssbhesabix' ), + 'type' => 'title', + 'desc' => '', + 'id' => 'invoice_options' + ); + + $fields[] = array( + 'title' => __( 'Add invoice in which status', 'ssbhesabix' ), + 'id' => 'ssbhesabix_invoice_status', + 'type' => 'multiselect', + 'options' => array( + 'pending' => __( 'Pending payment', 'ssbhesabix' ), + 'processing' => __( 'Processing', 'ssbhesabix' ), + 'on-hold' => __( 'On hold', 'ssbhesabix' ), + 'completed' => __( 'Completed', 'ssbhesabix' ), + 'cancelled' => __( 'Cancelled', 'ssbhesabix' ), + 'refunded' => __( 'Refunded', 'ssbhesabix' ), + 'failed' => __( 'Failed', 'ssbhesabix' ), + 'checkout-draft' => __( 'Draft', 'ssbhesabix' ), + ), + ); + + $fields[] = array( + 'title' => __( 'Return sale invoice status', 'ssbhesabix' ), + 'id' => 'ssbhesabix_invoice_return_status', + 'type' => 'multiselect', + 'options' => array( + 'pending' => __( 'Pending payment', 'ssbhesabix' ), + 'processing' => __( 'Processing', 'ssbhesabix' ), + 'on-hold' => __( 'On hold', 'ssbhesabix' ), + 'completed' => __( 'Completed', 'ssbhesabix' ), + 'cancelled' => __( 'Cancelled', 'ssbhesabix' ), + 'refunded' => __( 'Refunded', 'ssbhesabix' ), + 'failed' => __( 'Failed', 'ssbhesabix' ), + 'checkout-draft' => __( 'Draft', 'ssbhesabix' ), + ), + ); + + $fields[] = array( + 'title' => __( "Invoice's Project", 'ssbhesabix' ), + 'id' => 'ssbhesabix_invoice_project', + 'type' => 'select', + 'options' => $projects, + ); + + $fields[] = array( + 'title' => __( "Invoice's Salesman", 'ssbhesabix' ), + 'id' => 'ssbhesabix_invoice_salesman', + 'type' => 'select', + 'options' => $salesmen, + ); + + $fields[] = array( + 'title' => __( "Invoice Salesman Percentage", 'ssbhesabix' ), + 'id' => 'ssbhesabix_invoice_salesman_percentage', + 'type' => 'text', + 'placeholder' => __("Invoice Salesman Percentage", 'ssbhesabix'), + ); + + $fields[] = array( + 'title' => '', + 'desc' => __('Save invoice in draft mode in Hesabix', 'ssbhesabix'), + 'id' => 'ssbhesabix_invoice_draft_save_in_hesabix', + 'type' => 'checkbox', + 'default' => 'no' + ); + + $fields[] = array( + 'title' => __('Save Freight', 'ssbhesabix'), + 'id' => 'ssbhesabix_invoice_freight', + 'type' => 'radio', + 'options' => [ + 0 => __("Save as Freight", 'ssbhesabix'), + 1 => __("Save as a Service", 'ssbhesabix') + ], + ); + + $fields[] = array( + 'title' => __('Service Code For Freight', 'ssbhesabix'), + 'id' => 'ssbhesabix_invoice_freight_code', + 'type' => 'text', + 'placeholder' => __('Enter Freight Code', 'ssbhesabix'), + ); + + if(is_plugin_active( 'dokan-lite/dokan.php' )){ + $fields[] = array( + 'title' => __( "Submit invoice base on Dokan orders", 'ssbhesabix' ), + 'id' => 'ssbhesabix_invoice_dokan', + 'type' => 'radio', + 'options' => [0 => __( "Inactive", 'ssbhesabix' ), + 1 => __( "Submit parent order", 'ssbhesabix' ), + 2 => __( "Submit children orders", 'ssbhesabix' )], + 'default' => 0 + ); + } + + $fields[] = array('type' => 'sectionend', 'id' => 'invoice_options'); + + return $fields; + } +//============================================================================================= + public static function ssbhesabix_invoice_setting() { + $ssbhesabf_setting_fields = self::ssbhesabix_invoice_setting_fields(); + $Html_output = new Ssbhesabix_Html_output(); + ?> + +
+ توجه
+ در اینجا تعیین کنید که فاکتور سفارش در چه مرحله ای در حسابیکس ثبت شود. + و چه زمان برای یک سفارش فاکتور برگشت از فروش ثبت شود. +
+ در صورت انتخاب ذخیره هزینه حمل و نقل به عنوان یک خدمت، ابتدا باید یک خدمت در حسابیکس تعریف کنید و کد مربوط به آن را در فیلد کد خدمت حمل و نقل وارد و ذخیره نمایید. +
+ فیلد "ذخیره هزینه به عنوان خدمت" برای سامانه مودیان مالیاتی می باشد. +
+ توجه کنید که مقدار این فیلد به درستی وارد شده باشد تا در ثبت فاکتور مشکلی ایجاد نشود. +
+
+ init( $ssbhesabf_setting_fields ); ?> +

+ +

+ alert("کد خدمت حمل و نقل تعریف نشده است")'; + } + ?> +
+ save_fields( $ssbhesabf_setting_fields ); + } +//============================================================================================= + public static function ssbhesabix_payment_setting_fields() { + $banks = Ssbhesabix_Setting::ssbhesabix_get_banks(); + $cashes = Ssbhesabix_Setting::ssbhesabix_get_cashes(); + $payInputValue = array_merge($banks,$cashes); + + $payment_gateways = new WC_Payment_Gateways; + $available_payment_gateways = $payment_gateways->get_available_payment_gateways(); + + $fields[] = array( + 'title' => __( 'Payment methods Settings', 'ssbhesabix' ), + 'type' => 'title', + 'desc' => '', + 'id' => 'payment_options' + ); + + $fields[] = array( + 'title' => __( 'Add payment in which status', 'ssbhesabix' ), + 'id' => 'ssbhesabix_payment_status', + 'type' => 'multiselect', + 'options' => array( + 'pending' => __( 'Pending payment', 'ssbhesabix' ), + 'processing' => __( 'Processing', 'ssbhesabix' ), + 'on-hold' => __( 'On hold', 'ssbhesabix' ), + 'completed' => __( 'Completed', 'ssbhesabix' ), + 'cancelled' => __( 'Cancelled', 'ssbhesabix' ), + 'refunded' => __( 'Refunded', 'ssbhesabix' ), + 'failed' => __( 'Failed', 'ssbhesabix' ), + 'checkout-draft' => __( 'Draft', 'ssbhesabix' ), + ), + ); + + foreach ( $available_payment_gateways as $gateway ) { + $fields[] = array( + 'title' => $gateway->title, + 'id' => 'ssbhesabix_payment_method_' . $gateway->id, + 'type' => 'select', + 'options' => $payInputValue + ); + } + + foreach ( $available_payment_gateways as $gateway ) { + $fields[] = array( + 'title' => 'درصد کارمزد تراکنش برای ' . $gateway->title, + 'id' => 'ssbhesabix_payment_transaction_fee_' . $gateway->id, + 'class' => 'payment-transaction-fee', + 'type' => 'text', + 'placeholder' => 'وارد نمایید', + 'default' => '0', + ); + } + + $plugins = get_plugins(); + foreach ($plugins as $plugin_file => $plugin_info) { + if ($plugin_file === 'snapppay-woocommerce-gateway /index.php') { + if(is_plugin_active('snapppay-woocommerce-gateway /index.php')) { + $fields[] = array( + 'title' => 'پرداخت اسنپ پی', + 'id' => 'ssbhesabix_payment_method_snapppay', + 'type' => 'select', + 'options' => $payInputValue + ); + + $fields[] = array( + 'title' => 'درصد کارمزد تراکنش برای پرداخت اسنپ پی', + 'id' => 'ssbhesabix_payment_transaction_fee_snapppay', + 'type' => 'text', + 'placeholder' => 'وارد نمایید', + 'default' => '0', + ); + } + } + } + + $fields[] = array( + 'title' => __('Default Payment Gateway By Using this Option, all Invoices Will Have this Payment Gateway as Their Payment Gateway', 'ssbhesabix'), + 'id' => 'ssbhesabix_payment_option', + 'type' => 'radio', + 'options' => [ + 'yes' => __("Save Default Bank as the Payment Gateway", "ssbhesabix"), + 'no' => __("Save Other Payment Methods as the Payment Gateway", "ssbhesabix"), + ], + 'default' => 'no' + ); + + $fields[] = array( + 'title' => __( "Default Invoice Transaction Fee Percentage", 'ssbhesabix' ), + 'id' => 'ssbhesabix_invoice_transaction_fee', + 'type' => 'text', + 'class' => 'payment-transaction-fee', + 'placeholder' => __("Default Invoice Transaction Fee Percentage", 'ssbhesabix'), + 'default' => '0' + ); + + $fields[] = array( + 'title' => __( "Submit Cash in Transit", 'ssbhesabix' ), + 'id' => 'ssbhesabix_cash_in_transit', + 'desc' => __( "Submit Invoice Receipt Cash in Transit", 'ssbhesabix' ), + 'type' => 'checkbox', + 'default' => 'no' + ); + + $fields[] = array( + 'title' => __('Default Bank Code', 'ssbhesabix'), + 'id' => 'ssbhesabix_default_payment_method_code', + 'type' => 'text', + 'placeholder' => __('Enter Bank Code', 'ssbhesabix') + ); + + $fields[] = array( + 'title' => __('Default Bank Name', 'ssbhesabix'), + 'id' => 'ssbhesabix_default_payment_method_name', + 'type' => 'text', + 'placeholder' => __('Enter Bank Name', 'ssbhesabix') + ); + + $fields[] = array( 'type' => 'sectionend', 'id' => 'payment_options' ); + + return $fields; + } +//============================================================================================= + public static function ssbhesabix_payment_setting() { + $ssbhesabf_setting_fields = self::ssbhesabix_payment_setting_fields(); + $Html_output = new Ssbhesabix_Html_output(); + ?> + +
+ توجه
+ در اینجا تعیین کنید که رسید دریافت وجه فاکتور در چه وضعیتی ثبت شود + و در هر روش پرداخت، رسید در چه بانکی و یا صندوقی ثبت شود. +
+ بانک پیش فرض، جهت کاربرانی می باشد که به هر دلیلی روش های پرداخت وکامرس در اینجا نمایش داده نمی شود. در این صورت با انتخاب بانک و ثبت کد آن، تمامی دریافت ها در آن بانک ثبت خواهد شد +
+ درصد کارمزد تراکنش برای هر روش پرداخت می تواند تعریف شود(بین 1 تا 100). +
+ درصد کارمزد تراکنش پیش فرض زمانی اعمال می شود که درصد یک روش پرداخت یا تعریف نشده باشد و یا صفر باشد. +
+
+ init( $ssbhesabf_setting_fields ); ?> +

+ +

+ alert("کد بانک پیش فرض تعریف نشده است")'; + } + + if(get_option("ssbhesabix_cash_in_transit") == "yes" || get_option("ssbhesabix_cash_in_transit") == "1") { + $func = new Ssbhesabix_Admin_Functions(); + $cashInTransitFullPath = $func->getCashInTransitFullPath(); + if(!$cashInTransitFullPath) { + HesabixLogService::writeLogStr("Cash in Transit is not Defined in Hesabix ---- وجوه در راه در حسابیکس یافت نشد"); + echo ' + '; + } + } + ?> +
+ save_fields( $ssbhesabf_setting_fields ); + } +//============================================================================================= + public static function ssbhesabix_api_setting_fields() { + $fields[] = array( + 'title' => __( 'API Settings', 'ssbhesabix' ), + 'type' => 'title', + 'desc' => '', + 'id' => 'api_options' + ); + + $fields[] = array( + 'title' => __( 'API Key', 'ssbhesabix' ), + 'desc' => __( 'Find API key in Setting->Financial Settings->API Menu', 'ssbhesabix' ), + 'id' => 'ssbhesabix_account_api', + 'type' => 'text', + ); + + $fields[] = array( + 'title' => __( 'API Address', 'ssbhesabix' ), + 'id' => 'ssbhesabix_api_address', + 'type' => 'select', + 'options' => array( + "0" => "hesabix.ir", + "1" => "next.hesabix.ir" + ) + ); + $fields[] = array( 'type' => 'sectionend', 'id' => 'api_options' ); + + return $fields; + } +//============================================================================================= + public static function ssbhesabix_api_setting() { + $businessInfo = self::getSubscriptionInfo(); + $isBusinessInfo = false; + if ( $businessInfo["expireDate"] != '' && $businessInfo["expireDate"] != null ) { + $isBusinessInfo = true; + $expireDate = strtotime( $businessInfo["expireDate"] ); + $expireDateStr = date( "Y/m/d", $expireDate ); + } + + $ssbhesabf_setting_fields = self::ssbhesabix_api_setting_fields(); + $Html_output = new Ssbhesabix_Html_output(); + ?> +
+ توجه
+
    +
  • + برای اتصال به API حسابیکس و فعال شدن این افزونه باید در اینجا + کلید API و توکن ورود به کسب و کار خود را وارد کنید. +
  • +
  • + اگر برای اتصال به API حسابیکس از توکن ورود استفاده کنید + نیازی به وارد کردن ایمیل و رمز عبور نیست. +
  • +
  • + برای پیدا کردن توکن ورود و کلید API، در حسابیکس به قسمت تنظیمات، تنظیمات API مراجعه کنید. +
  • +
  • + اگر می خواهید کسب و کار دیگری را به افزونه متصل کنید، ابتدا باید یک بار افزونه را + حذف و مجدد نصب کنید تا جدول ارتباطات کسب و کار قبلی با افزونه حذف گردد. +
  • +
+
+
+ اطلاعات کسب و کار +
+
نام کسب و کار:
+
+
طرح:
+
+
+
+
اعتبار سند:
+
+
تاریخ انقضا:
+
+
+
+ +
+ هشدار
+ برای اتصال یک کسب و کار دیگر به افزونه، ابتدا باید یک بار افزونه را حذف و مجدد + نصب کنید تا جدول ارتباطات افزونه با کسب و کار قبل حذف گردد. +
+ +
+ init( $ssbhesabf_setting_fields ); ?> +

+ +

+
+ save_fields( $ssbhesabf_setting_fields ); + + Ssbhesabix_Setting::ssbhesabix_set_webhook(); + } +//============================================================================================= + public static function ssbhesabix_export_setting() { + // Export - Bulk product export offers + $productExportResult = ( isset( $_GET['productExportResult'] ) ) ? wc_clean( $_GET['productExportResult'] ) : null; + $productImportResult = ( isset( $_GET['productImportResult'] ) ) ? wc_clean( $_GET['productImportResult'] ) : null; + $error = ( isset( $_GET['error'] ) ) ? wc_clean( $_GET['error'] ) : null; + + if ( ! is_null( $productExportResult ) && $productExportResult === 'true' ) { + $processed = ( isset( $_GET['processed'] ) ) ? wc_clean( $_GET['processed'] ) : null; + if ( $processed == 0 ) { + echo '
'; + echo '

' . __( 'No products were exported, All products were exported or there are no product', 'ssbhesabix' ); + echo '

'; + } else { + echo '
'; + echo '

' . sprintf( __( 'Export products completed. %s products added/updated.', 'ssbhesabix' ), $processed ); + echo '

'; + } + } elseif ( $productExportResult === 'false' ) { + if ( ! is_null( $error ) && $error === '-1' ) { + echo '
'; + echo '

' . __( 'Export products fail. Hesabix has already contained products.', 'ssbhesabix' ); + echo '

'; + } else { + echo '
'; + echo '

' . __( 'Export products fail. Please check the log file.', 'ssbhesabix' ); + echo '

'; + } + } + + if ( ! is_null( $productImportResult ) && $productImportResult === 'true' ) { + $processed = ( isset( $_GET['processed'] ) ) ? wc_clean( $_GET['processed'] ) : null; + if ( $processed == 0 ) { + echo '
'; + echo '

' . __( 'No products were imported, All products were imported or there are no product', 'ssbhesabix' ); + echo '

'; + } else { + echo '
'; + echo '

' . sprintf( __( 'Import products completed. %s products added/updated.', 'ssbhesabix' ), $processed ); + echo '

'; + } + } elseif ( $productImportResult === 'false' ) { + echo '
'; + echo '

' . __( 'Import products fail. Please check the log file.', 'ssbhesabix' ); + echo '

'; + } + + // Export - Product opening quantity export offers + $productOpeningQuantityExportResult = ( isset( $_GET['productOpeningQuantityExportResult'] ) ) ? wc_clean( $_GET['productOpeningQuantityExportResult'] ) : null; + if ( ! is_null( $productOpeningQuantityExportResult ) && $productOpeningQuantityExportResult === 'true' ) { + echo '
'; + echo '

' . __( 'Export product opening quantity completed.', 'ssbhesabix' ); + echo '

'; + } elseif ( ! is_null( $productOpeningQuantityExportResult ) && $productOpeningQuantityExportResult === 'false' ) { + $shareholderError = ( isset( $_GET['shareholderError'] ) ) ? wc_clean( $_GET['shareholderError'] ) : null; + $noProduct = ( isset( $_GET['noProduct'] ) ) ? wc_clean( $_GET['noProduct'] ) : null; + if ( $shareholderError == 'true' ) { + echo '
'; + echo '

' . __( 'Export product opening quantity fail. No Shareholder exists, Please define Shareholder in Hesabix', 'ssbhesabix' ); + echo '

'; + } elseif ( $noProduct == 'true' ) { + echo '
'; + echo '

' . __( 'No product available for Export product opening quantity.', 'ssbhesabix' ); + echo '

'; + } else { + echo '
'; + echo '

' . __( 'Export product opening quantity fail. Please check the log file.', 'ssbhesabix' ); + echo '

'; + } + } + + // Export - Bulk customer export offers + $customerExportResult = ( isset( $_GET['customerExportResult'] ) ) ? wc_clean( $_GET['customerExportResult'] ) : null; + + if ( ! is_null( $customerExportResult ) && $customerExportResult === 'true' ) { + $processed = ( isset( $_GET['processed'] ) ) ? wc_clean( $_GET['processed'] ) : null; + if ( $processed == 0 ) { + echo '
'; + echo '

' . __( 'No customers were exported, All customers were exported or there are no customer', 'ssbhesabix' ); + echo '

'; + } else { + echo '
'; + echo '

' . sprintf( __( 'Export customers completed. %s customers added.', 'ssbhesabix' ), $processed ); + echo '

'; + } + } elseif ( ! is_null( $customerExportResult ) && $customerExportResult === 'false' ) { + if ( ! is_null( $error ) && $error === '-1' ) { + echo '
'; + echo '

' . __( 'Export customers fail. Hesabix has already contained customers.', 'ssbhesabix' ); + echo '

'; + } else { + echo '
'; + echo '

' . __( 'Export customers fail. Please check the log file.', 'ssbhesabix' ); + echo '

'; + } + } + + ?> +
+

+
+
+
+
+
+ +
+ +
+
+

+
+
+
+
+ +
    +
  • با انجام این عملیات محصولات لینک نشده از فروشگاه وارد حسابیکس می شوند.
  • +
  • اگر محصولات از قبل هم در فروشگاه تعریف شده اند و هم در حسابیکس و به هم لینک نشده اند باید از + گزینه + همسان سازی دستی محصولات استفاده کنید. +
  • +
  • با انجام این عملیات موجودی محصولات وارد حسابیکس نمی شود و برای وارد کردن موجودی محصولات + فروشگاه + در حسابیکس، باید از گزینه استخراج موجودی اول دوره استفاده کنید. +
  • +
+
+
+
+ +
+
+
+ +
+ +
+
+

+
+
+
+
+ +
    +
  • با انجام این عملیات موجودی کنونی محصولات در فروشگاه بعنوان موجودی اول دوره محصولات در حسابیکس + ثبت می شوند. +
  • +
  • بطور کلی فقط یک بار باید از این گزینه استفاده کنید، + که این کار باید پس از خروج محصولات به حسابیکس و یا پس از همسان سازی دستی تمام محصولات + انجام شود. +
  • +
+
+
+
+ +
+
+
+ +
+ +
+
+

+
+
+
+
+ +
    +
  • با انجام این عملیات مشتریان لینک نشده از فروشگاه وارد حسابیکس می شوند.
  • +
  • + اگر یک مشتری بیش از یک بار وارد حسابیکس شده است می توانید از گزینه ادغام تراکنش ها در حسابیکس + استفاده کنید. +
  • +
+
+
+
+ +
+
+
+ +
+ +
+
+

+ +

+
+
+
+
+ +
    +
  • با انجام این عملیات محصولات لینک نشده از حسابیکس وارد فروشگاه می شوند.
  • +
  • اگر محصولات از قبل هم در فروشگاه تعریف شده اند و هم در حسابیکس و به هم لینک نشده اند باید از + گزینه + همسان سازی دستی محصولات استفاده کنید. +
  • +
  • محصولات در وضعیت خصوصی وارد فروشگاه می شوند و سپس هر زمان مایل بودید می توانید وضعیت را به + منتشر شده تغییر دهید. +
  • +
  • تمامی محصولات بعنوان محصول ساده (و نه متغیر) وارد فروشگاه می شوند.
  • +
+
+
+
+ '; + echo '

' . __( 'Sync completed, All hesabix changes synced successfully.', 'ssbhesabix' ); + echo ''; + } + + // Sync - Bulk product sync offers + $productSyncResult = ( isset( $_GET['productSyncResult'] ) ) ? wc_clean( $_GET['productSyncResult'] ) : null; + if ( ! is_null( $productSyncResult ) && $productSyncResult == 'true' ) { + echo '

'; + echo '

' . __( 'Sync completed, All products price/quantity synced successfully.', 'ssbhesabix' ); + echo '

'; + } elseif ( ! is_null( $productSyncResult ) && ! $productSyncResult == 'false' ) { + echo '
'; + echo '

' . __( 'Sync products fail. Please check the log file.', 'ssbhesabix' ); + echo '

'; + } + + // Sync - Bulk invoice sync offers + $orderSyncResult = ( isset( $_GET['orderSyncResult'] ) ) ? wc_clean( $_GET['orderSyncResult'] ) : null; + + if ( ! is_null( $orderSyncResult ) && $orderSyncResult === 'true' ) { + $processed = ( isset( $_GET['processed'] ) ) ? wc_clean( $_GET['processed'] ) : null; + echo '
'; + echo '

' . sprintf( __( 'Order sync completed. %s order added.', 'ssbhesabix' ), $processed ); + echo '

'; + } elseif ( ! is_null( $orderSyncResult ) && $orderSyncResult === 'false' ) { + $fiscal = ( isset( $_GET['fiscal'] ) ) ? wc_clean( $_GET['fiscal'] ) : false; + + if ( $fiscal === 'true' ) { + echo '
'; + echo '

' . __( 'The date entered is not within the fiscal year.', 'ssbhesabix' ); + echo '

'; + } else { + echo '
'; + echo '

' . __( 'Cannot sync orders. Please enter valid Date format.', 'ssbhesabix' ); + echo '

'; + } + } + + // Sync - Bulk product update + $productUpdateResult = ( isset( $_GET['$productUpdateResult'] ) ) ? wc_clean( $_GET['$productUpdateResult'] ) : null; + if ( ! is_null( $productUpdateResult ) && $productUpdateResult == 'true' ) { + echo '
'; + echo '

' . __( 'Update completed successfully.', 'ssbhesabix' ); + echo '

'; + } elseif ( ! is_null( $productUpdateResult ) && ! $productUpdateResult == 'false' ) { + echo '
'; + echo '

' . __( 'Update failed. Please check the log file.', 'ssbhesabix' ); + echo '

'; + } + + // Sync - Bulk product with filter update in Hesabix + $productUpdateWithFilterResult = ( isset( $_GET['$productUpdateWithFilterResult'] ) ) ? wc_clean( $_GET['$productUpdateWithFilterResult'] ) : null; + if ( ! is_null( $productUpdateWithFilterResult ) && $productUpdateWithFilterResult == 'true' ) { + echo '
'; + echo '

' . __( 'Update completed successfully.', 'ssbhesabix' ); + echo '

'; + } elseif ( ! is_null( $productUpdateWithFilterResult ) && ! $productUpdateWithFilterResult == 'false' ) { + echo '
'; + echo '

' . __( 'Update failed. Please check the log file.', 'ssbhesabix' ); + echo '

'; + } + ?> + +
+

' . $storeProductsCount . '' ?>

+

' . $hesabixProductsCount . '' ?>

+

' . $linkedProductsCount . '' ?>

+
+ +
+

+
+ +
+
+
+
+ +
+ +
+
+

+
+ +
    +
  • با انجام این عملیات کالاها، مشتریان و سفارشاتی که تا کنون در حسابیکس ثبت نشده اند در حسابیکس + ثبت می شوند. +
  • +
  • توجه کنید که بصورت نرمال با فعالسازی افزونه و تکمیل تنظیمات API + این همسان سازی بصورت خودکار انجام می شود و این گزینه صرفاْ برای مواقعی است که به دلایل فنی + مثل قطع اتصال فروشگاه با حسابیکس و یا خطا و باگ این همسان سازی صورت نگرفته است. +
  • +
+
+
+
+ +
+
+
+ +
+ + + + + +
+
+

+
+
+
+
+ +
    +
  • با انجام این عملیات موجودی و قیمت محصولات در فروشگاه، بر اساس قیمت و موجودی آنها در حسابیکس + تنظیم می شود. +
  • +
  • این عملیات بر اساس تنظیمات صورت گرفته در تب محصولات انجام می شود.
  • +
+
+
+
+ +
+
+
+ +
+ + تا + + + +
+
+

+
+
+
+
+
+
+ +
    +
  • با انجام این عملیات سفارشات فروشگاه که در حسابیکس ثبت نشده اند از تاریخ انتخاب شده بررسی و در + حسابیکس ثبت می شوند. +
  • +
  • توجه کنید که بصورت نرمال با فعالسازی افزونه و تکمیل تنظیمات API + این همسان سازی بصورت خودکار انجام می شود و این گزینه صرفاْ برای مواقعی است که به دلایل فنی + مثل قطع اتصال فروشگاه با حسابیکس و یا خطا و باگ این همسان سازی صورت نگرفته است. +
  • +
+
+
+
+ +
+
+
+ +
+ +
+
+

+
+
+
+
+ +
    +
  • با انجام این عملیات ویژگی محصولات مثل نام و قیمت در حسابیکس، بر اساس فروشگاه بروزرسانی می + شود. +
  • +
  • در این عملیات موجودی کالا در حسابیکس تغییری نمی کند و بروز رسانی نمی شود.
  • +
+
+
+
+ +
+
+
+ +
+ +

+ +

+ +
+
+

+
+ +
    +
  • با انجام این عملیات ویژگی محصولات مثل نام و قیمت در حسابیکس، بر اساس فروشگاه در بازه ID مشخص شده بروزرسانی می + شود. +
  • +
  • در این عملیات موجودی کالا در حسابیکس تغییری نمی کند و بروز رسانی نمی شود.
  • +
  • بازه ID نباید بیشتر از 200 عدد باشد.
  • +
+
+
+
+ + $storeProductsCount, + "hesabixProductsCount" => $hesabixProductsCount, + "linkedProductsCount" => $linkedProductsCount + ); + } +//============================================================================================= + public static function getProductCountsInHesabix() { + $hesabix = new Ssbhesabix_Api(); + + $filters = array( array( "Property" => "khadamat", "Operator" => "=", "Value" => 0 ) ); + + $response = $hesabix->itemGetItems( array('Filters' => $filters ) ); + if ( $response->Success ) { + return $response->data->FilteredCount; + } else { + return 0; + } + } +//============================================================================================= +// public static function getLinkedProductsCount() { +// global $wpdb; +// +// return $wpdb->get_var( "SELECT COUNT(*) FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `obj_type` = 'product'" ); +// } + + + public static function getLinkedProductsCount() { + global $wpdb; + + return $wpdb->get_var( + $wpdb->prepare( + "SELECT COUNT(*) FROM {$wpdb->prefix}ssbhesabix WHERE obj_type = 'product'" + ) + ); + } +//============================================================================================= +// public static function getProductCountsInStore() { +// global $wpdb; +// +// return $wpdb->get_var( "SELECT COUNT(*) FROM `" . $wpdb->prefix . "posts` WHERE `post_type` IN ('product','product_variation') AND `post_status` IN ('publish', 'private', 'draft') " ); +// } + + public static function getProductCountsInStore() { + global $wpdb; + + return $wpdb->get_var( + $wpdb->prepare( + "SELECT COUNT(*) + FROM {$wpdb->prefix}posts + WHERE post_type IN ('product', 'product_variation') + AND post_status IN ('publish', 'private', 'draft')" + ) + ); + } + +//============================================================================================= + public static function getSubscriptionInfo() { + $businessName = ''; + $credit = ''; + $expireDate = ''; + $plan = ''; + + $hesabix = new Ssbhesabix_Api(); + $response = $hesabix->settingGetSubscriptionInfo(); + if ( $response->Success ) { + $businessName = $response->Result->Name; + $credit = $response->Result->Credit; + $expireDate = $response->Result->ExpireDate; + $plan = $response->Result->Subscription; + } + + return array( + "businessName" => $businessName, + "credit" => $credit, + "expireDate" => $expireDate, + "plan" => $plan + ); + } +//============================================================================================= + public static function ssbhesabix_set_webhook() { + $url = get_site_url() . '/index.php?ssbhesabix_webhook=1&token=' . substr( wp_hash( AUTH_KEY . 'ssbhesabix/webhook' ), 0, 10 ); + + $hookPassword = get_option( 'ssbhesabix_webhook_password' ); + + $ssbhesabix_api = new Ssbhesabix_Api(); + $response = $ssbhesabix_api->settingSetChangeHook( $url, $hookPassword ); + + if ( is_object( $response ) ) { + if ( $response->Success ) { + update_option( 'ssbhesabix_live_mode', 1 ); + update_option( 'ssbhesabix_account_bid', $response->bid ); + update_option( 'ssbhesabix_account_year', $response->year ); + + //set the last log ID if is not set + $lastChanges = get_option( 'ssbhesabix_last_log_check_id' ); + if ( ! $lastChanges ) { + $lastChanges = 0; + } + $changes = $ssbhesabix_api->settingGetChanges( $lastChanges ); + if ( $changes->Success ) { + if ( get_option( 'ssbhesabix_last_log_check_id' ) == 0 ) { + $lastChange = end( $changes->Result ); + update_option( 'ssbhesabix_last_log_check_id', $lastChange->Id ); + } + } else { + echo '
'; + echo '

' . __( 'Cannot check the last change ID. Error Message: ', 'ssbhesabix' ) . $changes->ErrorMessage . '

'; + echo '
'; + + HesabixLogService::log( array("Cannot check the last change ID. Error Message: $changes->ErrorMessage. Error Code: $changes->ErrorCode") ); + } + + + //check if date in fiscalYear + if ( Ssbhesabix_Admin_Functions::isDateInFiscalYear( date( 'Y-m-d H:i:s' ) ) === 0 ) { + echo '
'; + echo '

' . __( 'The fiscal year has passed or not arrived. Please check the fiscal year settings in Hesabix.', 'ssbhesabix' ) . '

'; + echo '
'; + + update_option( 'ssbhesabix_live_mode', 0 ); + } + + //check the Hesabix default currency + $default_currency = $ssbhesabix_api->settingGetCurrency(); + if ( $default_currency->Success ) { + + $woocommerce_currency = get_woocommerce_currency(); + $hesabix_currency = $default_currency->Result->moneyName; + if ( $hesabix_currency == $woocommerce_currency || ( $hesabix_currency == 'IRR' && $woocommerce_currency == 'IRT' ) || ( $hesabix_currency == 'IRT' && $woocommerce_currency == 'IRR' ) ) { + update_option( 'ssbhesabix_hesabix_default_currency', $hesabix_currency ); + } else { + update_option( 'ssbhesabix_hesabix_default_currency', 0 ); + update_option( 'ssbhesabix_live_mode', 0 ); + + echo '
'; + echo '

' . __( 'Hesabix and WooCommerce default currency must be same.', 'ssbhesabix' ); + echo '

'; + } + } else { + echo '
'; + echo '

' . __( 'Cannot check the Hesabix default currency. Error Message: ', 'ssbhesabix' ) . $default_currency->ErrorMessage . '

'; + echo '
'; + + HesabixLogService::log( array( "Cannot check the Hesabix default currency. Error Message: $default_currency->ErrorMessage. Error Code: $default_currency->ErrorCode" ) ); + } + + if ( get_option( 'ssbhesabix_live_mode' ) ) { + echo '
'; + echo '

' . __( 'API Setting updated. Test Successfully', 'ssbhesabix' ) . '

'; + echo '
'; + } + + //add gift wrapping service + $wpFaService = new HesabixWpFaService(); + $wpFa = $wpFaService->getWpFa('gift_wrapping', 0); + if(!$wpFa) { + $gift_wrapping = $ssbhesabix_api->itemSave(array( + 'name' => 'خدمات بسته بندی هدیه', + 'khadamat' => 1, + 'Tag' => json_encode(array('id_product' => 0, 'id_attribute' => 0)) + )); + + if($gift_wrapping->Success) { + $wpFa = new WpFa(); + $wpFa->idPs = 0; + $wpFa->idPsAttribute = 0; + $wpFa->idHesabix = $gift_wrapping->code; + $wpFa->objType = 'gift_wrapping'; + $wpFaService->save($wpFa); + $msg = 'Hesabix Gift wrapping service added successfully. Service Code: ' . $gift_wrapping->Result->Code; + HesabixLogService::writeLogStr($msg); + } else { + $msg = 'Cannot set Gift wrapping service code. Error Message: ' . $gift_wrapping->ErrorMessage . ', Error Code: ' . $gift_wrapping->ErrorCode; + HesabixLogService::writeLogStr($msg); + } + } + } else { + update_option( 'ssbhesabix_live_mode', 0 ); + + if ( $response->ErrorCode === 108 ) { + echo '
'; + echo '

' . __( 'Cannot connect to Hesabix. Business expired.', 'ssbhesabix' ) . $response->ErrorMessage . '

'; + echo '
'; + update_option( 'ssbhesabix_business_expired', 1 ); + } else { + echo '
'; + echo '

' . __( 'Cannot set Hesabix webHook. Error Message:', 'ssbhesabix' ) . $response->ErrorMessage . '

'; + echo '
'; + update_option( 'ssbhesabix_business_expired', 0 ); + } + + HesabixLogService::log( array("Cannot set Hesabix webHook. Error Message: $response->ErrorMessage. Error Code: $response->ErrorCode") ); + } + } else { + update_option( 'ssbhesabix_live_mode', 0 ); + + echo '
'; + echo '

' . __( 'Cannot connect to Hesabix servers. Please check your Internet connection', 'ssbhesabix' ) . '

'; + echo '
'; + + HesabixLogService::log( array("Cannot connect to hesabix servers. Check your internet connection" ) ); + } + + return $response; + } +//============================================================================================= + public static function ssbhesabix_get_banks() { + $ssbhesabix_api = new Ssbhesabix_Api(); + $banks = $ssbhesabix_api->settingGetBanks(); + + if ( is_object( $banks ) && $banks->Success ) { + $available_banks = array(); + $available_banks[ - 1 ] = __( 'Choose', 'ssbhesabix' ); + foreach ( $banks->Result as $bank ) { + if ( $bank->Currency == get_woocommerce_currency() || ( get_woocommerce_currency() == 'IRT' && $bank->Currency == 'IRR' ) || ( get_woocommerce_currency() == 'IRR' && $bank->Currency == 'IRT' ) ) { + $available_banks[ 'bank'.$bank->Code ] = $bank->Name . ' - ' . $bank->Branch . ' - ' . $bank->AccountNumber; + } + } + + if ( empty( $available_banks ) ) { + $available_banks[0] = __( 'Define at least one bank in Hesabix', 'ssbhesabix' ); + } + + return $available_banks; + } else { + update_option( 'ssbhesabix_live_mode', 0 ); + + echo '
'; + echo '

' . __( 'Cannot get Banks detail.', 'ssbhesabix' ) . '

'; + echo '
'; + + HesabixLogService::log( array("Cannot get banking information. Error Code: $banks->ErrorCode. Error Message: $banks->ErrorMessage." ) ); + + return array( '0' => __( 'Cannot get Banks detail.', 'ssbhesabix' ) ); + } + } +//============================================================================================= + public static function ssbhesabix_get_cashes() { + $ssbhesabix_api = new Ssbhesabix_Api(); + $cashes = $ssbhesabix_api->settingGetCashes(); + + if ( is_object( $cashes ) && $cashes->Success ) { + $available_cashes = array(); + foreach ( $cashes->Result as $cash ) { + if ( $cash->Currency == get_woocommerce_currency() || ( get_woocommerce_currency() == 'IRT' && $cash->Currency == 'IRR' ) || ( get_woocommerce_currency() == 'IRR' && $cash->Currency == 'IRT' ) ) { + $available_cashes[ 'cash'.$cash->Code ] = $cash->Name; + } + } + return $available_cashes; + } + } +//============================================================================================= + public static function ssbhesabix_get_projects() { + $ssbhesabix_api = new Ssbhesabix_Api(); + $projects = $ssbhesabix_api->settingGetProjects(); + + if ( is_object( $projects ) && $projects->Success ) { + $available_projects = array(); + $available_projects[ - 1 ] = __( 'Choose', 'ssbhesabix' ); + foreach ( $projects->data as $project ) { + $available_projects[ $project->id ] = $project->name; + } + + return $available_projects; + } else { + update_option( 'ssbhesabix_live_mode', 0 ); + echo '
'; + echo '

' . __( 'Cannot get Projects detail.', 'ssbhesabix' ) . '

'; + echo '
'; + HesabixLogService::log( array("Cannot get projects information. Error Code:$projects->ErrorCode. Error Message: $projects->ErrorMessage.") ); + + return array( '0' => __( 'Cannot get projects detail.', 'ssbhesabix' ) ); + } + } +//============================================================================================= + public static function ssbhesabix_get_salesmen() { + $ssbhesabix_api = new Ssbhesabix_Api(); + $salesmen = $ssbhesabix_api->settingGetSalesmen(); + + if ( is_object( $salesmen ) && $salesmen->Success ) { + $available_salesmen = array(); + $available_salesmen[ - 1 ] = __( 'Choose', 'ssbhesabix' ); + foreach ( $salesmen->result as $salesman ) { + $available_salesmen[ $salesman->code ] = $salesman->nikename; + } + + return $available_salesmen; + } else { + update_option( 'ssbhesabix_live_mode', 0 ); + echo '
'; + echo '

' . __( 'Cannot get Salesmen detail.', 'ssbhesabix' ) . '

'; + echo '
'; + HesabixLogService::log( array("Cannot get salesmen information. Error Code: $salesmen->ErrorCode Error Message: .$salesmen->ErrorMessage.") ); + + return array( '0' => __( 'Cannot get salesmen detail.', 'ssbhesabix' ) ); + } + } +//============================================================================================= + public static function ssbhesabix_log_setting() { + $cleanLogResult = ( isset( $_GET['cleanLogResult'] ) ) ? wc_clean( $_GET['cleanLogResult'] ) : null; + + if ( ! is_null( $cleanLogResult ) && $cleanLogResult === 'true' ) { + echo '
'; + echo '

' . __( 'The log file was cleared.', 'ssbhesabix' ) . '

'; + echo '
'; + } elseif ( $cleanLogResult === 'false' ) { + echo '
'; + echo '

' . __( 'Log file not found.', 'ssbhesabix' ) . '

'; + echo '
'; + } + + self::ssbhesabix_tab_log_html(); + } +//============================================================================================= + public static function ssbhesabix_tab_log_html() { + ?> +
+
+ توجه فرمایید با زدن دکمه پاک کردن کل لاگ ها، تمامی فایل های لاگ ذخیره شده پاک می شوند. +
+ در صورت نیاز به پاک کردن فایل لاگ جاری می توانید از دکمه پاک کردن لاگ جاری، زمانی که فایل لاگ مدنظر انتخاب شده است، استفاده کنید. +
+ فهرست تاریخچه لاگ ها، لاگ های موجود در سیستم در بازه 10 روز گذشته را نمایش می دهد. +
+

+
+
+ +
+
+
+ +
+
+
+
+
+ +
+ "> + + +
+
+
+
+ +
+
+ "> + +
+
+
+
+
+
+
+
+
+
+ +
+ + +
+
+
+
+
+
+
+
+
+ +
+ + + +
+
+
+
+
+ 1000 ) { + + $fileSizeInMb = ( ( filesize( WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d") . '.txt' ) / 1000 ) / 1000 ); + $fileSizeInMb = round( $fileSizeInMb, 2 ); + + + $str = __( 'The log file size is large, clean log file.', 'ssbhesabix' ); + + echo '
' . + '

' . $str . ' (' . $fileSizeInMb . 'MB)' . '

' + . '
'; + + } else if ( file_exists( WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d") . '.txt' ) ) { + + $URL = WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d") . '.txt'; + $logFileContent = HesabixLogService::readLog($URL); + } + + echo '
'. + '
+

' . __("Log History", "ssbhesabix") . '

+
+
    '; + for($i = 0 ; $i < 10 ; $i++) { + if( file_exists( WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d", strtotime(-$i."day")) . '.txt' ) ) { + echo '
  • '; + } + } + echo ' +
+
+
'; + echo ''; + echo '
'; +//--------------------------------------- + if(isset($_POST["changeLogFile"])) { + echo + ''; + + $URL = WP_CONTENT_DIR . '/ssbhesabix-' . $_POST["changeLogFile"] . '.txt'; + $logFileContent = HesabixLogService::readLog($URL); + + echo '
'. + '
+

' . __("Log History", "ssbhesabix") . '

+
+
    '; + for($i = 0 ; $i < 10 ; $i++) { + if( file_exists( WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d", strtotime(-$i."day")) . '.txt' ) ) { + echo '
  • '; + } + } + echo ' +
+
+
'; + echo ''; + echo '
'; + } +//--------------------------------------- + if(isset($_POST["deleteLogFiles"])) { + $prefix = WP_CONTENT_DIR . '/ssbhesabix-'; + + $files = glob($prefix . '*'); + if ($files) { + foreach ($files as $file) { + if (is_file($file)) { + if (unlink($file)) { + header("refresh:0"); + } else { + HesabixLogService::writeLogStr("Unable to delete the file"); + } + } + } + } else { + HesabixLogService::writeLogStr("No files found"); + } + } +//--------------------------------------- + if(isset($_POST["ssbhesabix-log-clean-submit"])) { + if($_POST["currentLogFileDate"]) { + $file = WP_CONTENT_DIR . '/ssbhesabix-' . $_POST["currentLogFileDate"] . '.txt'; + } else { + $file = WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d") . '.txt'; + } + if (is_file($file)) { + if (unlink($file)) { + HesabixLogService::writeLogStr("Selected Log File Deleted"); + header("refresh:0"); + } else { + HesabixLogService::writeLogStr("Unable to delete the file"); + } + } + } +//--------------------------------------- + if(isset($_POST["ssbhesabix-delete-logs-between-two-dates"])) { + $startDate = $_POST["ssbhesabix_delete_log_date_from"]; + $endDate = $_POST["ssbhesabix_delete_log_date_to"]; + + $directory = WP_CONTENT_DIR . '/ssbhesabix-'; + $files = glob($directory . '*'); + if($files) { + foreach ($files as $file) { + if(is_file($file)) { + $fileDate = substr($file, strlen($directory), 10); + $dateObj = DateTime::createFromFormat('Y-m-d', $fileDate); + $startObj = DateTime::createFromFormat('Y-m-d', $startDate); + $endObj = DateTime::createFromFormat('Y-m-d', $endDate); + + if ($dateObj >= $startObj && $dateObj <= $endObj) { + HesabixLogService::writeLogStr("Log Files deleted"); + unlink($file); + } + } + } + } + header("refresh:0"); + } +//--------------------------------------- + if(isset($_POST["ssbhesabix-find-log-submit"])) { + echo + ''; + + $URL = WP_CONTENT_DIR . '/ssbhesabix-' . $_POST["ssbhesabix_find_log_date"] . '.txt'; + if ( file_exists( WP_CONTENT_DIR . '/ssbhesabix-' . $_POST["ssbhesabix_find_log_date"] . '.txt' ) && + ( filesize( WP_CONTENT_DIR . '/ssbhesabix-' . $_POST["ssbhesabix_find_log_date"] . '.txt' ) / 1000 ) < 1000 ) { + $logFileContent = HesabixLogService::readLog($URL); + } + + + echo '
'. + '
+

' . __("Log History", "ssbhesabix") . '

+
+
    '; + for($i = 0 ; $i < 10 ; $i++) { + if( file_exists( WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d", strtotime(-$i."day")) . '.txt' ) ) { + echo '
  • '; + } + } + echo ' +
+
+
'; + echo ''; + echo '
'; + } + ?> +
+ settingGetWarehouses(); + + if ( is_object( $warehouses->data ) ) { + $available_warehouses = array(); + $available_warehouses[ - 1 ] = __( 'Accounting quantity (Total inventory)', 'ssbhesabix' ); + + return $available_warehouses; + } + + if ( is_object( $warehouses ) && $warehouses->Success ) { + $available_warehouses = array(); + $available_warehouses[ - 1 ] = __( 'Accounting quantity (Total inventory)', 'ssbhesabix' ); + foreach ( $warehouses->data as $warehouse ) { + $available_warehouses[ $warehouse->code ] = $warehouse->name; + } + + return $available_warehouses; + } else { + update_option( 'ssbhesabix_live_mode', 0 ); + echo '
'; + echo '

' . __( 'Cannot get warehouses.', 'ssbhesabix' ) . '

'; + echo '
'; + HesabixLogService::log( array("Cannot get warehouses. Error Code: $warehouses->ErrorCode. Error Message: .$warehouses->ErrorMessage.") ); + + return array( '0' => __( 'Cannot get warehouses.', 'ssbhesabix' ) ); + } + } + +} + +Ssbhesabix_Setting::init(); diff --git a/admin/partials/ssbhesabix-html-output.php b/admin/partials/ssbhesabix-html-output.php index ac73383..77271c2 100644 --- a/admin/partials/ssbhesabix-html-output.php +++ b/admin/partials/ssbhesabix-html-output.php @@ -1,372 +1,371 @@ - - * @author HamidReza Gharahzadeh - * @author Sepehr Najafi - * @author Babak Alizadeh - */ - -class Ssbhesabix_Html_output { - public static function init($options = array()) { - if (!empty($options)) { - foreach ($options as $value) { - if (!isset($value['type'])) continue; - if (!isset($value['id'])) $value['id'] = ''; - if (!isset($value['title'])) $value['title'] = isset($value['name']) ? $value['name'] : ''; - if (!isset($value['class'])) $value['class'] = ''; - if (!isset($value['css'])) $value['css'] = ''; - if (!isset($value['default'])) $value['default'] = ''; - if (!isset($value['desc'])) $value['desc'] = ''; - if (!isset($value['desc_tip'])) $value['desc_tip'] = false; - $custom_attributes = array(); - if (!empty($value['custom_attributes']) && is_array($value['custom_attributes'])) { - foreach ($value['custom_attributes'] as $attribute => $attribute_value) { - $custom_attributes[] = esc_attr($attribute) . '="' . esc_attr($attribute_value) . '"'; - } - } - if (true === $value['desc_tip']) { - $description = ''; - $tip = $value['desc']; - } elseif (!empty($value['desc_tip'])) { - $description = $value['desc']; - $tip = $value['desc_tip']; - } elseif (!empty($value['desc'])) { - $description = $value['desc']; - $tip = ''; - } else { - $description = $tip = ''; - } - if ($description && in_array($value['type'], array('textarea', 'radio'))) { - $description = '

' . wp_kses_post($description) . '

'; - } elseif ($description && in_array($value['type'], array('checkbox'))) { - $description = wp_kses_post($description); - } elseif ($description) { - $description = '' . wp_kses_post($description) . ''; - } - if (isset($value['placeholder']) && !empty($value['placeholder'])) { - $placeholder = $value['placeholder']; - } else { - $placeholder = ''; - } - if ($tip && in_array($value['type'], array('checkbox'))) { - - $tip = '

' . $tip . '

'; - } - switch ($value['type']) { - case 'title': - if (!empty($value['title'])) { - echo '

' . esc_html($value['title']) . '

'; - } - if (!empty($value['desc'])) { - echo wpautop(wptexturize(wp_kses_post($value['desc']))); - } - echo '' . "\n\n"; - break; - case 'sectionend': - echo '
'; - break; - case 'text': - case 'email': - case 'number': - case 'color' : - case 'password' : - $type = $value['type']; - $class = ''; - $option_value = self::get_option($value['id'], $value['default']); - if ($value['type'] == 'color') { - $type = 'text'; - $value['class'] .= 'colorpick'; - $description .= ''; - } - ?> - - - - - - - /> - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
    - $val) { - ?> -
  • - -
  • - -
-
- - - - - -
- -
- - - - - -
- - - -
- $value['id'], - 'id' => $value['id'], - 'sort_column' => 'menu_order', - 'sort_order' => 'ASC', - 'show_option_none' => ' ', - 'class' => $value['class'], - 'echo' => false, - 'selected' => absint(self::get_option($value['id'])) - ); - if (isset($value['args'])) { - $args = wp_parse_args($value['args'], $args); - } - ?> - - - - - $value) { - update_option($name, wc_clean($value)); - } - echo '

' . __( 'Settings were saved successfully.', 'ssbhesabix' ) . '

'; - return true; - } -//===================================================================================================== -} - -Ssbhesabix_Html_output::init(); + + * @author HamidReza Gharahzadeh + * @author Sepehr Najafi + */ + +class Ssbhesabix_Html_output { + public static function init($options = array()) { + if (!empty($options)) { + foreach ($options as $value) { + if (!isset($value['type'])) continue; + if (!isset($value['id'])) $value['id'] = ''; + if (!isset($value['title'])) $value['title'] = isset($value['name']) ? $value['name'] : ''; + if (!isset($value['class'])) $value['class'] = ''; + if (!isset($value['css'])) $value['css'] = ''; + if (!isset($value['default'])) $value['default'] = ''; + if (!isset($value['desc'])) $value['desc'] = ''; + if (!isset($value['desc_tip'])) $value['desc_tip'] = false; + $custom_attributes = array(); + if (!empty($value['custom_attributes']) && is_array($value['custom_attributes'])) { + foreach ($value['custom_attributes'] as $attribute => $attribute_value) { + $custom_attributes[] = esc_attr($attribute) . '="' . esc_attr($attribute_value) . '"'; + } + } + if (true === $value['desc_tip']) { + $description = ''; + $tip = $value['desc']; + } elseif (!empty($value['desc_tip'])) { + $description = $value['desc']; + $tip = $value['desc_tip']; + } elseif (!empty($value['desc'])) { + $description = $value['desc']; + $tip = ''; + } else { + $description = $tip = ''; + } + if ($description && in_array($value['type'], array('textarea', 'radio'))) { + $description = '

' . wp_kses_post($description) . '

'; + } elseif ($description && in_array($value['type'], array('checkbox'))) { + $description = wp_kses_post($description); + } elseif ($description) { + $description = '' . wp_kses_post($description) . ''; + } + if (isset($value['placeholder']) && !empty($value['placeholder'])) { + $placeholder = $value['placeholder']; + } else { + $placeholder = ''; + } + if ($tip && in_array($value['type'], array('checkbox'))) { + + $tip = '

' . $tip . '

'; + } + switch ($value['type']) { + case 'title': + if (!empty($value['title'])) { + echo '

' . esc_html($value['title']) . '

'; + } + if (!empty($value['desc'])) { + echo wpautop(wptexturize(wp_kses_post($value['desc']))); + } + echo '' . "\n\n"; + break; + case 'sectionend': + echo '
'; + break; + case 'text': + case 'email': + case 'number': + case 'color' : + case 'password' : + $type = $value['type']; + $class = ''; + $option_value = self::get_option($value['id'], $value['default']); + if ($value['type'] == 'color') { + $type = 'text'; + $value['class'] .= 'colorpick'; + $description .= ''; + } + ?> + + + + + + + /> + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
    + $val) { + ?> +
  • + +
  • + +
+
+ + + + + +
+ +
+ + + + + +
+ + + +
+ $value['id'], + 'id' => $value['id'], + 'sort_column' => 'menu_order', + 'sort_order' => 'ASC', + 'show_option_none' => ' ', + 'class' => $value['class'], + 'echo' => false, + 'selected' => absint(self::get_option($value['id'])) + ); + if (isset($value['args'])) { + $args = wp_parse_args($value['args'], $args); + } + ?> + + + + + $value) { + update_option($name, wc_clean($value)); + } + echo '

' . __( 'Settings were saved successfully.', 'ssbhesabix' ) . '

'; + return true; + } +//===================================================================================================== +} + +Ssbhesabix_Html_output::init(); diff --git a/admin/services/HesabixLogService.php b/admin/services/HesabixLogService.php index 66b56da..0efb931 100644 --- a/admin/services/HesabixLogService.php +++ b/admin/services/HesabixLogService.php @@ -1,64 +1,64 @@ -format('[Y-m-d H:i:s] '); - $str = $date . $str; - - $str = mb_convert_encoding($str, 'UTF-8'); - file_put_contents($fileName, PHP_EOL . $str, FILE_APPEND); - } - - public static function writeLogObj($obj) - { - $fileName = WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d") . '.txt'; - ob_start(); - var_dump($obj); - file_put_contents($fileName, PHP_EOL . ob_get_flush(), FILE_APPEND); - } - - public static function log($params) - { - $fileName = WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d") . '.txt'; - $log = ''; - - $dateTime = new DateTimeImmutable( 'now', wp_timezone() ); - $date = $dateTime->format('[Y-m-d H:i:s] '); - - foreach ($params as $message) { - if (is_array($message) || is_object($message)) { - $log .= $date . print_r($message, true) . "\n"; - } elseif (is_bool($message)) { - $log .= $date . ($message ? 'true' : 'false') . "\n"; - } else { - $log .= $date . $message . "\n"; - } - } - - $log = mb_convert_encoding($log, 'UTF-8'); - file_put_contents($fileName, PHP_EOL . $log, FILE_APPEND); - } - - public static function readLog($URL) - { - return file_exists($URL) ? file_get_contents($URL) : ''; - } - - public static function clearLog() - { - $fileName = WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d") . '.txt'; - if (file_exists($fileName)) { - file_put_contents($fileName, ""); - } - } - - public static function getLogFilePath() - { - return WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d") . '.txt'; - } +format('[Y-m-d H:i:s] '); + $str = $date . $str; + + $str = mb_convert_encoding($str, 'UTF-8'); + file_put_contents($fileName, PHP_EOL . $str, FILE_APPEND); + } + + public static function writeLogObj($obj) + { + $fileName = WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d") . '.txt'; + ob_start(); + var_dump($obj); + file_put_contents($fileName, PHP_EOL . ob_get_flush(), FILE_APPEND); + } + + public static function log($params) + { + $fileName = WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d") . '.txt'; + $log = ''; + + $dateTime = new DateTimeImmutable( 'now', wp_timezone() ); + $date = $dateTime->format('[Y-m-d H:i:s] '); + + foreach ($params as $message) { + if (is_array($message) || is_object($message)) { + $log .= $date . print_r($message, true) . "\n"; + } elseif (is_bool($message)) { + $log .= $date . ($message ? 'true' : 'false') . "\n"; + } else { + $log .= $date . $message . "\n"; + } + } + + $log = mb_convert_encoding($log, 'UTF-8'); + file_put_contents($fileName, PHP_EOL . $log, FILE_APPEND); + } + + public static function readLog($URL) + { + return file_exists($URL) ? file_get_contents($URL) : ''; + } + + public static function clearLog() + { + $fileName = WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d") . '.txt'; + if (file_exists($fileName)) { + file_put_contents($fileName, ""); + } + } + + public static function getLogFilePath() + { + return WP_CONTENT_DIR . '/ssbhesabix-' . date("20y-m-d") . '.txt'; + } } \ No newline at end of file diff --git a/admin/services/HesabixWpFaService.php b/admin/services/HesabixWpFaService.php index 48e835a..b39f873 100644 --- a/admin/services/HesabixWpFaService.php +++ b/admin/services/HesabixWpFaService.php @@ -1,250 +1,478 @@ -id = $id; - $instance->objType = $type; - $instance->idHesabix = $idHesabix; - $instance->idWp = $idWp; - $instance->idWpAttribute = $idWpAttribute; - return $instance; - } -} - -class HesabixWpFaService -{ - public function __construct() {} - - public function getWpFa($objType, $idWp, $idWpAttribute = 0) - { - if (!isset($objType) || !isset($idWp)) return false; - - global $wpdb; - $row = $wpdb->get_row("SELECT * FROM " . $wpdb->prefix . "ssbhesabix WHERE `id_ps` = $idWp AND `id_ps_attribute` = $idWpAttribute AND `obj_type` = '$objType'"); - - if (isset($row)) return $this->mapWpFa($row); - - return null; - } -//========================================================================================================= - public function getWpFaByHesabixId($objType, $hesabixId) - { - if (!isset($objType) || !isset($hesabixId)) return false; - - global $wpdb; - $row = $wpdb->get_row("SELECT * FROM " . $wpdb->prefix . "ssbhesabix WHERE `id_hesabix` = $hesabixId AND `obj_type` = '$objType'"); - - if (isset($row)) - return $this->mapWpFa($row); - return null; - } -//========================================================================================================= - public function getWpFaId($objType, $idWp, $idWpAttribute = 0) - { - if (!isset($objType) || !isset($idWp)) - return false; - - global $wpdb; - $row = $wpdb->get_row("SELECT `id` FROM " . $wpdb->prefix . "ssbhesabix WHERE `id_ps` = $idWp AND `id_ps_attribute` = $idWpAttribute AND `obj_type` = '$objType'"); - - if (is_object($row)) - return (int)$row->id; - else - return false; - } -//========================================================================================================= - public function getWpFaIdByHesabixId($objType, $hesabixId) - { - if (!isset($objType) || !isset($hesabixId)) - return false; - - global $wpdb; - $row = $wpdb->get_row("SELECT `id` FROM " . $wpdb->prefix . "ssbhesabix WHERE `id_hesabix` = $hesabixId AND `obj_type` = '$objType'"); - - if (isset($row)) - return (int)$row->id; - return null; - } -//========================================================================================================= - public function getProductCodeByWpId($id_product, $id_attribute = 0) - { - $obj = $this->getWpFa('product', $id_product, $id_attribute); - - if ($obj != null) return $obj->idHesabix; - - return null; - } -//========================================================================================================= - public function getCustomerCodeByWpId($id_customer) - { - $obj = $this->getWpFa('customer', $id_customer); - - if ($obj != null) return $obj->idHesabix; - - return null; - } -//========================================================================================================= - public function getInvoiceCodeByWpId($id_order) - { - $obj = $this->getWpFa('order', $id_order); - - if ($obj != null) return $obj->idHesabix; - - return null; - } -//========================================================================================================= - public function getProductAndCombinations($idWp) - { - global $wpdb; - - $sql = "SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `obj_type` = 'product' AND `id_ps` = '$idWp'"; - $result = $wpdb->get_results($sql); - - $wpFaObjects = array(); - if (isset($result) && is_array($result) && count($result) > 0) { - foreach ($result as $item) - $wpFaObjects[] = $this->mapWpFa($item); - return $wpFaObjects; - } - return null; - } -//========================================================================================================= - public function mapWpFa($sqlObj): WpFa - { - $wpFa = new WpFa(); - - $wpFa->id = $sqlObj->id; - $wpFa->idHesabix = $sqlObj->id_hesabix; - $wpFa->idWp = $sqlObj->id_ps; - $wpFa->idWpAttribute = $sqlObj->id_ps_attribute; - $wpFa->objType = $sqlObj->obj_type; - - return $wpFa; - } -//========================================================================================================= - public function saveProduct($item): bool - { - $json = json_decode($item->Tag); - $wpFaService = new HesabixWpFaService(); - $wpFa = $wpFaService->getWpFaByHesabixId('product', $item->Code); - - if (!$wpFa) { - $wpFa = WpFa::newWpFa(0, 'product', (int)$item->Code, (int)$json->id_product, (int)$json->id_attribute); - $wpFaService->save($wpFa); - HesabixLogService::log(array("Item successfully added. Item code: " . (string)$item->Code . ". Product ID: $json->id_product-$json->id_attribute")); - } else { - $wpFa->idHesabix = (int)$item->Code; - $wpFaService->update($wpFa); - HesabixLogService::log(array("Item successfully updated. Item code: " . (string)$item->Code . ". Product ID: $json->id_product-$json->id_attribute")); - } - return true; - } -//========================================================================================================= - public function saveCustomer($customer): bool - { - $json = json_decode($customer->Tag); - if ((int)$json->id_customer == 0) return true; - - $id = $this->getWpFaId('customer', (int)$json->id_customer); - global $wpdb; - - if (!$id) { - $wpdb->insert($wpdb->prefix . 'ssbhesabix', array( - 'id_hesabix' => (int)$customer->Code, - 'obj_type' => 'customer', - 'id_ps' => (int)$json->id_customer - )); - HesabixLogService::writeLogStr("Customer successfully added. Customer code: " . (string)$customer->Code . ". Customer ID: $json->id_customer"); - } else { - $wpdb->update($wpdb->prefix . 'ssbhesabix', array( - 'id_hesabix' => (int)$customer->Code, - 'obj_type' => 'customer', - 'id_ps' => (int)$json->id_customer, - ), array('id' => $id)); - HesabixLogService::writeLogStr("Customer successfully updated. Customer code: " . (string)$customer->Code . ". Customer ID: $json->id_customer"); - } - return true; - } -//========================================================================================================= - public function saveInvoice($invoice, $orderType) - { - $json = json_decode($invoice->Tag); - $id = $this->getPsFaId('order', (int)$json->id_order); - - $invoiceNumber = (int)$invoice->Number; - $objType = $orderType == 0 ? 'order' : 'returnOrder'; - - if (!$id) { - Db::getInstance()->insert('ps_hesabix', array( - 'id_hesabix' => $invoiceNumber, - 'obj_type' => $objType, - 'id_ps' => (int)$json->id_order, - )); - if ($objType == 'order') - LogService::writeLogStr("Invoice successfully added. invoice number: " . (string)$invoice->Number . ", order id: " . $json->id_order); - else - LogService::writeLogStr("Return Invoice successfully added. Customer code: " . (string)$invoice->Number . ", order id: " . $json->id_order); - } else { - Db::getInstance()->update('ps_hesabix', array( - 'id_hesabix' => $invoiceNumber, - 'obj_type' => $objType, - 'id_ps' => (int)$json->id_order, - ), array('id' => $id), 0, true, true); - //check if it is order or return order - if ($objType == 'order') - LogService::writeLogStr("Invoice successfully updated. invoice number: " . (string)$invoice->Number . ", order id: " . $json->id_order); - else - LogService::writeLogStr("Return Invoice successfully updated. Customer code: " . (string)$invoice->Number . ", order id: " . $json->id_order); - } - - return true; - } -//========================================================================================================= - public function save(WpFa $wpFa) - { - global $wpdb; - $wpdb->insert($wpdb->prefix . 'ssbhesabix', array( - 'id_hesabix' => $wpFa->idHesabix, - 'obj_type' => $wpFa->objType, - 'id_ps' => (int)$wpFa->idWp, - 'id_ps_attribute' => (int)$wpFa->idWpAttribute, - )); - } -//========================================================================================================= - public function update(WpFa $wpFa) - { - global $wpdb; - $wpdb->update($wpdb->prefix . 'ssbhesabix', array( - 'id_hesabix' => $wpFa->idHesabix, - 'obj_type' => $wpFa->objType, - 'id_ps' => (int)$wpFa->idWp, - 'id_ps_attribute' => (int)$wpFa->idWpAttribute, - ), array('id' => $wpFa->id)); - } -//========================================================================================================= - public function delete(WpFa $wpFa) - { - global $wpdb; - $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id' => $wpFa->id)); - } -//========================================================================================================= - public function deleteAll($productId) - { - global $wpdb; - $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id_ps' => $productId)); - } -//========================================================================================================= +id = $id; + $instance->objType = $type; + $instance->idHesabix = $idHesabix; + $instance->idWp = $idWp; + $instance->idWpAttribute = $idWpAttribute; + return $instance; + } +} + +class HesabixWpFaService +{ + public function __construct() {} + + public function getWpFa($objType, $idWp, $idWpAttribute = 0) + { + if (!isset($objType) || !isset($idWp)) return false; + + global $wpdb; + //$row = $wpdb->get_row("SELECT * FROM " . $wpdb->prefix . "ssbhesabix WHERE `id_ps` = $idWp AND `id_ps_attribute` = $idWpAttribute AND `obj_type` = '$objType'"); + + $row = $wpdb->get_row( + $wpdb->prepare( + "SELECT * + FROM {$wpdb->prefix}ssbhesabix + WHERE `id_ps` = %d + AND `id_ps_attribute` = %d + AND `obj_type` = %s", + $idWp, + $idWpAttribute, + $objType + ) + ); + + + if (isset($row)) return $this->mapWpFa($row); + + return null; + } +//========================================================================================================= + public function getWpFaSearch($woocommerce_search_code = '', $woocommerce_attribute_search_code = '', $hesabix_search_code = '', $obj_type_search = '') + { + global $wpdb; + + $conditions = []; + $params = []; + + if ($woocommerce_search_code !== '') { + $conditions[] = "id_ps = %s"; + $params[] = $woocommerce_search_code; + } + + if ($woocommerce_attribute_search_code !== '' || $woocommerce_attribute_search_code === '0') { + $conditions[] = "id_ps_attribute = %s"; + $params[] = $woocommerce_attribute_search_code; + } + + if ($hesabix_search_code !== '') { + $conditions[] = "id_hesabix = %s"; + $params[] = $hesabix_search_code; + } + + if ($obj_type_search !== '' && $obj_type_search != '0') { + $conditions[] = "obj_type = %s"; + $params[] = $obj_type_search; + } + + $sql = "SELECT * FROM {$wpdb->prefix}ssbhesabix"; + if (!empty($conditions)) { + $sql .= " WHERE " . implode(" AND ", $conditions); + } + + $prepared_sql = $wpdb->prepare($sql, ...$params); + $result = $wpdb->get_results($prepared_sql); + + $wpFaObjects = array(); + if (isset($result) && is_array($result) && count($result) > 0) { + foreach ($result as $item) { + $wpFaObjects[] = $this->mapWpFa($item); + } + } + + return $wpFaObjects; + } + +//========================================================================================================= + public function getWpFaByHesabixId($objType, $hesabixId) + { + if (!isset($objType) || !isset($hesabixId)) return false; + + global $wpdb; + //$row = $wpdb->get_row("SELECT * FROM " . $wpdb->prefix . "ssbhesabix WHERE `id_hesabix` = $hesabixId AND `obj_type` = '$objType'"); + + $row = $wpdb->get_row( + $wpdb->prepare( + "SELECT * + FROM {$wpdb->prefix}ssbhesabix + WHERE `id_hesabix` = %d + AND `obj_type` = %s", + $hesabixId, + $objType + ) + ); + + if (isset($row)) + return $this->mapWpFa($row); + return null; + } +//========================================================================================================= + public function getWpFaId($objType, $idWp, $idWpAttribute = 0) + { + if (!isset($objType) || !isset($idWp)) + return false; + + global $wpdb; + //$row = $wpdb->get_row("SELECT `id` FROM " . $wpdb->prefix . "ssbhesabix WHERE `id_ps` = $idWp AND `id_ps_attribute` = $idWpAttribute AND `obj_type` = '$objType'"); + + $row = $wpdb->get_row( + $wpdb->prepare( + "SELECT `id` + FROM {$wpdb->prefix}ssbhesabix + WHERE `id_ps` = %d + AND `id_ps_attribute` = %d + AND `obj_type` = %s", + $idWp, + $idWpAttribute, + $objType + ) + ); + + if (is_object($row)) + return (int)$row->id; + else + return false; + } +//========================================================================================================= + public function getWpFaIdByHesabixId($objType, $hesabixId) + { + if (!isset($objType) || !isset($hesabixId)) + return false; + + global $wpdb; + //$row = $wpdb->get_row("SELECT `id` FROM " . $wpdb->prefix . "ssbhesabix WHERE `id_hesabix` = $hesabixId AND `obj_type` = '$objType'"); + + $row = $wpdb->get_row( + $wpdb->prepare( + "SELECT `id` + FROM {$wpdb->prefix}ssbhesabix + WHERE `id_hesabix` = %d + AND `obj_type` = %s", + $hesabixId, + $objType + ) + ); + + + if (isset($row)) + return (int)$row->id; + return null; + } +//========================================================================================================= + public function getProductCodeByWpId($id_product, $id_attribute = 0) + { + $obj = $this->getWpFa('product', $id_product, $id_attribute); + + if ($obj != null) return $obj->idHesabix; + + return null; + } +//========================================================================================================= + public function getCustomerCodeByWpId($id_customer) + { + $obj = $this->getWpFa('customer', $id_customer); + + if ($obj != null) return $obj->idHesabix; + + return null; + } +//========================================================================================================= + public function getInvoiceCodeByWpId($id_order) + { + $obj = $this->getWpFa('order', $id_order); + + if ($obj != null) return $obj->idHesabix; + + return null; + } +//========================================================================================================= + public function getProductAndCombinations($idWp) + { + global $wpdb; + + //$sql = "SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `obj_type` = 'product' AND `id_ps` = '$idWp'"; + //$result = $wpdb->get_results($sql); + + $sql = $wpdb->prepare( + "SELECT * + FROM {$wpdb->prefix}ssbhesabix + WHERE `obj_type` = 'product' + AND `id_ps` = %d", + $idWp + ); + + $result = $wpdb->get_results($sql); + + + $wpFaObjects = array(); + if (isset($result) && is_array($result) && count($result) > 0) { + foreach ($result as $item) + $wpFaObjects[] = $this->mapWpFa($item); + return $wpFaObjects; + } + return null; + } +//========================================================================================================= + public function mapWpFa($sqlObj): WpFa + { + $wpFa = new WpFa(); + + $wpFa->id = $sqlObj->id; + $wpFa->idHesabix = $sqlObj->id_hesabix; + $wpFa->idWp = $sqlObj->id_ps; + $wpFa->idWpAttribute = $sqlObj->id_ps_attribute; + $wpFa->objType = $sqlObj->obj_type; + + return $wpFa; + } +//========================================================================================================= + public function saveProduct($item): bool + { + $json = json_decode($item->Tag); + $wpFaService = new HesabixWpFaService(); + $wpFa = $wpFaService->getWpFaByHesabixId('product', $item->Code); + + if (!$wpFa) { + $wpFa = WpFa::newWpFa(0, 'product', (int)$item->Code, (int)$json->id_product, (int)$json->id_attribute); + $wpFaService->save($wpFa); + HesabixLogService::log(array("Item successfully added. Item code: " . (string)$item->Code . ". Product ID: $json->id_product-$json->id_attribute")); + } else { + $wpFa->idHesabix = (int)$item->Code; + $wpFaService->update($wpFa); + HesabixLogService::log(array("Item successfully updated. Item code: " . (string)$item->Code . ". Product ID: $json->id_product-$json->id_attribute")); + } + return true; + } +//========================================================================================================= + public function saveCustomer($customer): bool + { + $json = json_decode($customer->Tag); + if ((int)$json->id_customer == 0) return true; + + $id = $this->getWpFaId('customer', (int)$json->id_customer); + global $wpdb; + + if (!$id) { +// $wpdb->insert($wpdb->prefix . 'ssbhesabix', array( +// 'id_hesabix' => (int)$customer->Code, +// 'obj_type' => 'customer', +// 'id_ps' => (int)$json->id_customer +// )); + $wpdb->insert( + $wpdb->prefix . 'ssbhesabix', + array( + 'id_hesabix' => (int)$customer->Code, + 'obj_type' => 'customer', + 'id_ps' => (int)$json->id_customer + ), + array( + '%d', + '%s', + '%d' + ) + ); + + + + HesabixLogService::writeLogStr("Customer successfully added. Customer code: " . (string)$customer->Code . ". Customer ID: $json->id_customer"); + } else { +// $wpdb->update($wpdb->prefix . 'ssbhesabix', array( +// 'id_hesabix' => (int)$customer->Code, +// 'obj_type' => 'customer', +// 'id_ps' => (int)$json->id_customer, +// ), array('id' => $id)); + + $wpdb->update( + $wpdb->prefix . 'ssbhesabix', + array( + 'id_hesabix' => (int)$customer->Code, + 'obj_type' => 'customer', + 'id_ps' => (int)$json->id_customer, + ), + array('id' => $id), + array( + '%d', + '%s', + '%d' + ), + array('%d') + ); + + HesabixLogService::writeLogStr("Customer successfully updated. Customer code: " . (string)$customer->Code . ". Customer ID: $json->id_customer"); + } + return true; + } +//========================================================================================================= + public function saveInvoice($invoice, $orderType) + { + $json = json_decode($invoice->Tag); + $id = $this->getPsFaId('order', (int)$json->id_order); + + $invoiceNumber = (int)$invoice->Number; + $objType = $orderType == 0 ? 'order' : 'returnOrder'; + + if (!$id) { +// Db::getInstance()->insert('ps_hesabix', array( +// 'id_hesabix' => $invoiceNumber, +// 'obj_type' => $objType, +// 'id_ps' => (int)$json->id_order, +// )); + + Db::getInstance()->insert('ps_hesabix', array( + 'id_hesabix' => $invoiceNumber, + 'obj_type' => $objType, + 'id_ps' => (int)$json->id_order, + )); + + + if ($objType == 'order') + LogService::writeLogStr("Invoice successfully added. invoice number: " . (string)$invoice->Number . ", order id: " . $json->id_order); + else + LogService::writeLogStr("Return Invoice successfully added. Customer code: " . (string)$invoice->Number . ", order id: " . $json->id_order); + } else { +// Db::getInstance()->update('ps_hesabix', array( +// 'id_hesabix' => $invoiceNumber, +// 'obj_type' => $objType, +// 'id_ps' => (int)$json->id_order, +// ), array('id' => $id), 0, true, true); + + + Db::getInstance()->update('ps_hesabix', array( + 'id_hesabix' => $invoiceNumber, + 'obj_type' => $objType, + 'id_ps' => (int)$json->id_order, + ), array('id' => $id), 0, true, true); + + //check if it is order or return order + if ($objType == 'order') + LogService::writeLogStr("Invoice successfully updated. invoice number: " . (string)$invoice->Number . ", order id: " . $json->id_order); + else + LogService::writeLogStr("Return Invoice successfully updated. Customer code: " . (string)$invoice->Number . ", order id: " . $json->id_order); + } + + return true; + } +//========================================================================================================= + public function save(WpFa $wpFa) + { + global $wpdb; +// $wpdb->insert($wpdb->prefix . 'ssbhesabix', array( +// 'id_hesabix' => $wpFa->idHesabix, +// 'obj_type' => $wpFa->objType, +// 'id_ps' => (int)$wpFa->idWp, +// 'id_ps_attribute' => (int)$wpFa->idWpAttribute, +// )); + $wpdb->insert( + $wpdb->prefix . 'ssbhesabix', + array( + 'id_hesabix' => $wpFa->idHesabix, + 'obj_type' => $wpFa->objType, + 'id_ps' => (int)$wpFa->idWp, + 'id_ps_attribute' => (int)$wpFa->idWpAttribute, + ), + array( + '%s', + '%s', + '%d', + '%d' + ) + ); + + } +//========================================================================================================= +// public function update(WpFa $wpFa) +// { +// global $wpdb; +// $wpdb->update($wpdb->prefix . 'ssbhesabix', array( +// 'id_hesabix' => $wpFa->idHesabix, +// 'obj_type' => $wpFa->objType, +// 'id_ps' => (int)$wpFa->idWp, +// 'id_ps_attribute' => (int)$wpFa->idWpAttribute, +// ), array('id' => $wpFa->id)); +// } + + public function update(WpFa $wpFa) + { + global $wpdb; + + $idHesabix = isset($wpFa->idHesabix) ? sanitize_text_field($wpFa->idHesabix) : ''; + $objType = isset($wpFa->objType) ? sanitize_text_field($wpFa->objType) : ''; + $idWp = isset($wpFa->idWp) ? (int)$wpFa->idWp : 0; + $idWpAttribute = isset($wpFa->idWpAttribute) ? (int)$wpFa->idWpAttribute : 0; + + $wpdb->update( + $wpdb->prefix . 'ssbhesabix', + array( + 'id_hesabix' => $idHesabix, + 'obj_type' => $objType, + 'id_ps' => $idWp, + 'id_ps_attribute' => $idWpAttribute, + ), + array('id' => $wpFa->id), + array( + '%s', + '%s', + '%d', + '%d' + ), + array('%d') + ); + } + + +//========================================================================================================= +// public function delete(WpFa $wpFa) +// { +// global $wpdb; +// $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id' => $wpFa->id)); +// } + + public function delete(WpFa $wpFa) + { + global $wpdb; + + $id = isset($wpFa->id) ? (int)$wpFa->id : 0; + + $wpdb->delete( + $wpdb->prefix . 'ssbhesabix', + array('id' => $id), + array('%d') + ); + } +//========================================================================================================= +// public function deleteAll($productId) +// { +// global $wpdb; +// $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id_ps' => $productId)); +// } + public function deleteAll($productId) + { + global $wpdb; + + $productId = isset($productId) ? (int)$productId : 0; + + $wpdb->delete( + $wpdb->prefix . 'ssbhesabix', + array('id_ps' => $productId), + array('%d') + ); + } + +//========================================================================================================= } \ No newline at end of file diff --git a/admin/services/ssbhesabixCustomerService.php b/admin/services/ssbhesabixCustomerService.php index e639617..fb40ba8 100644 --- a/admin/services/ssbhesabixCustomerService.php +++ b/admin/services/ssbhesabixCustomerService.php @@ -1,228 +1,276 @@ -get_first_name() ? $customer->get_first_name() : $customer->get_billing_first_name(); - $lastName = $customer->get_last_name() ? $customer->get_last_name() : $customer->get_billing_last_name(); - $name = $firstName . ' ' . $lastName; - $nodeFamily = get_option('ssbhesabix_contact_automatic_save_node_family') == 'yes'? 'اشخاص :' . get_option('ssbhesabix_contact_node_family') : null; - - //checkout fields - $checkout_fields = ssbhesabixCustomerService::getAdditionalCheckoutFileds($id_order); - $NationalCode = $checkout_fields['NationalCode']; - $EconomicCode = $checkout_fields['EconomicCode']; - $RegistrationNumber = $checkout_fields['RegistrationNumber']; - $Website = $checkout_fields['Website']; - - if($NationalCode === false) $NationalCode = ''; - if($EconomicCode === false) $EconomicCode = ''; - if($RegistrationNumber === false) $RegistrationNumber = ''; - if($Website === false) $Website = ''; - - if (empty($name) || $name === ' ') $name = __('Not Defined', 'ssbhesabix'); - - $hesabixCustomer = array(); - - switch ($type) { - case 'first': - // - case 'billing': - $country_name = self::$countries[$order->get_billing_country()]; - $state_name = self::$states[$order->get_billing_country()][$order->get_billing_state()]; - $fullAddress = $order->get_billing_address_1() . '-' . $order->get_billing_address_2(); - - $hesabixCustomer = array( - 'Code' => $code, - 'Name' => $name, - 'FirstName' => Ssbhesabix_Validation::contactFirstNameValidation($firstName), - 'LastName' => Ssbhesabix_Validation::contactLastNameValidation($lastName), - 'ContactType' => 1, - 'NodeFamily' => $nodeFamily, - 'NationalCode' => $NationalCode, - 'EconomicCode' => $EconomicCode, - 'RegistrationNumber' => $RegistrationNumber, - 'Website' => $Website, - 'Address' => Ssbhesabix_Validation::contactAddressValidation($fullAddress), - 'City' => Ssbhesabix_Validation::contactCityValidation($customer->get_billing_city()), - 'State' => Ssbhesabix_Validation::contactStateValidation($state_name), - 'Country' => Ssbhesabix_Validation::contactCountryValidation($country_name), - 'PostalCode' => Ssbhesabix_Validation::contactPostalCodeValidation($customer->get_billing_postcode()), - 'Phone' => Ssbhesabix_Validation::contactPhoneValidation($customer->get_billing_phone()), - 'Email' => Ssbhesabix_Validation::contactEmailValidation($customer->get_email()), - 'Tag' => json_encode(array('id_customer' => $id_customer)), - 'Note' => __('Customer ID in OnlineStore: ', 'ssbhesabix') . $id_customer, - ); - break; - case 'shipping': - $country_name = self::$countries[$order->get_shipping_country()]; - $state_name = self::$states[$order->get_shipping_country()][$order->get_shipping_state()]; - $fullAddress = $order->get_shipping_address_1() . ' - ' . $order->get_shipping_address_2(); - - $hesabixCustomer = array( - 'Code' => $code, - 'Name' => $name, - 'FirstName' => Ssbhesabix_Validation::contactFirstNameValidation($firstName), - 'LastName' => Ssbhesabix_Validation::contactLastNameValidation($lastName), - 'ContactType' => 1, - 'NodeFamily' => $nodeFamily, - 'NationalCode' => $NationalCode, - 'EconomicCode' => $EconomicCode, - 'RegistrationNumber' => $RegistrationNumber, - 'Website' => $Website, - 'Address' => Ssbhesabix_Validation::contactAddressValidation($fullAddress), - 'City' => Ssbhesabix_Validation::contactCityValidation($customer->get_shipping_city()), - 'State' => Ssbhesabix_Validation::contactStateValidation($state_name), - 'Country' => Ssbhesabix_Validation::contactCountryValidation($country_name), - 'PostalCode' => Ssbhesabix_Validation::contactPostalCodeValidation($customer->get_shipping_postcode()), - 'Phone' => Ssbhesabix_Validation::contactPhoneValidation($customer->get_billing_phone()), - 'Email' => Ssbhesabix_Validation::contactEmailValidation($customer->get_email()), - 'Tag' => json_encode(array('id_customer' => $id_customer)), - 'Note' => __('Customer ID in OnlineStore: ', 'ssbhesabix') . $id_customer, - ); - break; - } - - return self::correctCustomerData($hesabixCustomer); - } -//=========================================================================================================== - public static function mapGuestCustomer($code, $id_order): array - { - $order = new WC_Order($id_order); - - $name = $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(); - if (empty($order->get_billing_first_name()) && empty($order->get_billing_last_name())) { - $name = __('Guest Customer', 'ssbhesabix'); - } - $nodeFamily = get_option('ssbhesabix_contact_automatic_save_node_family') == 'yes'? 'اشخاص :' . get_option('ssbhesabix_contact_node_family') :null; - - //checkout fields - $checkout_fields = ssbhesabixCustomerService::getAdditionalCheckoutFileds($id_order); - $NationalCode = $checkout_fields['NationalCode']; - $EconomicCode = $checkout_fields['EconomicCode']; - $RegistrationNumber = $checkout_fields['RegistrationNumber']; - $Website = $checkout_fields['Website']; - -// $country_name = self::$countries[$order->get_billing_country()]; -// $state_name = self::$states[$order->get_billing_state()]; - - - WC()->countries->countries[ $order->shipping_country ]; - $country_name = WC()->countries->countries[ $order->get_billing_country() ]; - $states = WC()->countries->get_states( $order->get_billing_country() ); - $state_name = $states[ $order->get_billing_state() ]; - if(!$state_name) $state_name = WC()->countries->states[$order->billing_country][$order->billing_state]; - if(!$state_name) $state_name = $order->get_billing_state(); - - $fullAddress = $order->get_billing_address_1() . '-' . $order->get_billing_address_2(); - - $hesabixCustomer = array( - 'Code' => $code, - 'Name' => $name, - 'FirstName' => Ssbhesabix_Validation::contactFirstNameValidation($order->get_billing_first_name()), - 'LastName' => Ssbhesabix_Validation::contactLastNameValidation($order->get_billing_last_name()), - 'ContactType' => 1, - 'NationalCode' => $NationalCode, - 'EconomicCode' => $EconomicCode, - 'RegistrationNumber' => $RegistrationNumber, - 'Website' => $Website, - 'NodeFamily' => $nodeFamily, - 'Address' => Ssbhesabix_Validation::contactAddressValidation($fullAddress), - 'City' => Ssbhesabix_Validation::contactCityValidation($order->get_billing_city()), - 'State' => Ssbhesabix_Validation::contactStateValidation($state_name), - 'Country' => Ssbhesabix_Validation::contactCountryValidation($country_name), - 'PostalCode' => Ssbhesabix_Validation::contactPostalCodeValidation($order->get_billing_postcode()), - 'Phone' => Ssbhesabix_Validation::contactPhoneValidation($order->get_billing_phone()), - 'Email' => Ssbhesabix_Validation::contactEmailValidation($order->get_billing_email()), - 'Tag' => json_encode(array('id_customer' => 0)), - 'Note' => __('Customer registered as a GuestCustomer.', 'ssbhesabix'), - ); - - return self::correctCustomerData($hesabixCustomer); - } -//=========================================================================================================== - private static function getMobileFromPhone($phone) { - if(preg_match("/^09\d{9}$/", $phone)) - return $phone; - else if(preg_match("/^9\d{9}$/", $phone)) - return '0' . $phone; - else if(preg_match("/^989\d{9}$/", $phone)) - return str_replace('98', '0' ,$phone); - else return ''; - } -//=========================================================================================================== - private static function correctCustomerData($hesabixCustomer) { - if($hesabixCustomer["Phone"] == '') - unset($hesabixCustomer["Phone"]); - else { - $mobile = self::getMobileFromPhone($hesabixCustomer["Phone"]); - - if($mobile) $hesabixCustomer["Mobile"] = $mobile; - } - - if($hesabixCustomer["Email"] == '') unset($hesabixCustomer["Email"]); - if($hesabixCustomer["Address"] == '') unset($hesabixCustomer["Address"]); - if($hesabixCustomer["PostalCode"] == '') unset($hesabixCustomer["PostalCode"]); - if($hesabixCustomer["City"] == '') unset($hesabixCustomer["City"]); - if($hesabixCustomer["State"] == '') unset($hesabixCustomer["State"]); - if($hesabixCustomer["Country"] == '') unset($hesabixCustomer["Country"]); - - return $hesabixCustomer; - } -//=========================================================================================================== - private static function getCountriesAndStates() - { - if (!isset(self::$countries)) { - $countries_obj = new WC_Countries(); - self::$countries = $countries_obj->get_countries(); - self::$states = $countries_obj->get_states(); - } - } -//=========================================================================================================== - private static function getAdditionalCheckoutFileds($id_order) { - $NationalCode = '_billing_hesabix_nationalcode'; - $EconomicCode = '_billing_hesabix_economiccode'; - $RegistrationNumber = '_billing_hesabix_registerationnumber'; - $Website = '_billing_hesabix_website'; - $NationalCode_isActive = get_option('ssbhesabix_contact_NationalCode_checkbox_hesabix'); - $EconomicCode_isActive = get_option('ssbhesabix_contact_EconomicCode_checkbox_hesabix'); - $RegistrationNumber_isActive = get_option('ssbhesabix_contact_RegistrationNumber_checkbox_hesabix'); - $Website_isActive = get_option('ssbhesabix_contact_Website_checkbox_hesabix'); - $add_additional_fileds = get_option('ssbhesabix_contact_add_additional_checkout_fields_hesabix'); - $fields = array(); - - // add additional fields to checkout - if($add_additional_fileds == '1') { - $fields['NationalCode'] = get_post_meta( $id_order, $NationalCode, true) ?? null; - $fields['EconomicCode'] = get_post_meta( $id_order, $EconomicCode, true) ?? null; - $fields['RegistrationNumber'] = get_post_meta( $id_order, $RegistrationNumber, true) ?? null; - $fields['Website'] = get_post_meta( $id_order, $Website, true) ?? null; - } elseif($add_additional_fileds == '2') { - $NationalCode = get_option('ssbhesabix_contact_NationalCode_text_hesabix'); - $EconomicCode = get_option('ssbhesabix_contact_EconomicCode_text_hesabix'); - $RegistrationNumber = get_option('ssbhesabix_contact_RegistrationNumber_text_hesabix'); - $Website = get_option('ssbhesabix_contact_Website_text_hesabix'); - - if($NationalCode_isActive == 'yes' && $NationalCode) - $fields['NationalCode'] = get_post_meta( $id_order, $NationalCode, true) ?? null; - - if($EconomicCode_isActive == 'yes' && $EconomicCode) - $fields['EconomicCode'] = get_post_meta( $id_order, $EconomicCode, true) ?? null; - - if($RegistrationNumber_isActive == 'yes' && $RegistrationNumber) - $fields['RegistrationNumber'] = get_post_meta( $id_order, $RegistrationNumber, true) ?? null; - - if($Website_isActive == 'yes' && $Website) - $fields['Website'] = get_post_meta( $id_order, $Website, true) ?? null; - } - return $fields; - } -} +get_first_name() ? $customer->get_first_name() : $customer->get_billing_first_name(); + $lastName = $customer->get_last_name() ? $customer->get_last_name() : $customer->get_billing_last_name(); + $name = $firstName . ' ' . $lastName; + $nodeFamily = get_option('ssbhesabix_contact_automatic_save_node_family') == 'yes'? 'اشخاص :' . get_option('ssbhesabix_contact_node_family') : null; + + //checkout fields + $checkout_fields = ssbhesabixCustomerService::getAdditionalCheckoutFileds($id_order); + $NationalCode = $checkout_fields['NationalCode']; + $EconomicCode = $checkout_fields['EconomicCode']; + $RegistrationNumber = $checkout_fields['RegistrationNumber']; + $Website = $checkout_fields['Website']; + + if($NationalCode === false) $NationalCode = ''; + if($EconomicCode === false) $EconomicCode = ''; + if($RegistrationNumber === false) $RegistrationNumber = ''; + if($Website === false) $Website = ''; + + if (empty($name) || $name === ' ') $name = __('Not Defined', 'ssbhesabix'); + + $hesabixCustomer = array(); + + switch ($type) { + case 'first': + // + case 'billing': + $country_name = self::$countries[$order->get_billing_country()]; + $state_name = self::$states[$order->get_billing_country()][$order->get_billing_state()]; + $fullAddress = $order->get_billing_address_1() . '-' . $order->get_billing_address_2(); + $postalCode = $order->get_billing_postcode(); + if(strlen($fullAddress) < 5) { + $fullAddress = $customer->get_billing_address_1() . '-' . $customer->get_billing_address_2(); + } + if(empty($country_name)) + $country_name = self::$countries[$customer->get_billing_country()]; + if(empty($state_name)) + $state_name = self::$states[$customer->get_billing_country()][$customer->get_billing_state()]; + if(empty($postalCode)) + $postalCode = $customer->get_billing_postcode(); + + $city = $order->get_billing_city(); + if(preg_match('/^[0-9]+$/', $city)) { + $func = new Ssbhesabix_Admin_Functions(); + $city = $func->convertCityCodeToName($order->get_billing_city()); + } + + $hesabixCustomer = array( + 'code' => $code, + 'nikename' => $name, + 'name' => Ssbhesabix_Validation::contactFirstNameValidation($firstName) . Ssbhesabix_Validation::contactLastNameValidation($lastName), + 'ContactType' => 1, + 'NodeFamily' => $nodeFamily, + 'shenasemeli' => $NationalCode, + 'codeeghtesadi' => $EconomicCode, + 'RegistrationNumber' => $RegistrationNumber, + 'website' => $Website, + 'address' => Ssbhesabix_Validation::contactAddressValidation($fullAddress), + 'shahr' => Ssbhesabix_Validation::contactCityValidation($city), + 'ostan' => Ssbhesabix_Validation::contactStateValidation($state_name), + 'keshvar' => Ssbhesabix_Validation::contactCountryValidation($country_name), + 'postalcode' => Ssbhesabix_Validation::contactPostalCodeValidation($postalCode), + 'tel' => Ssbhesabix_Validation::contactPhoneValidation($customer->get_billing_phone()), + 'emal' => Ssbhesabix_Validation::contactEmailValidation($customer->get_email()), + 'Tag' => json_encode(array('id_customer' => $id_customer)), + 'des' => __('Customer ID in OnlineStore: ', 'ssbhesabix') . $id_customer, + 'types' => [ + [ + 'checked'=>true, + 'code'=>'customer' + ] + ] + ); + break; + case 'shipping': + $country_name = self::$countries[$order->get_shipping_country()]; + $state_name = self::$states[$order->get_shipping_country()][$order->get_shipping_state()]; + $fullAddress = $order->get_shipping_address_1() . ' - ' . $order->get_shipping_address_2(); + $postalCode = $order->get_shipping_postcode(); + + if(strlen($fullAddress) < 5) + $fullAddress = $customer->get_billing_address_1() . '-' . $customer->get_billing_address_2(); + if(empty($country_name)) + $country_name = self::$countries[$customer->get_billing_country()]; + if(empty($state_name)) + $state_name = self::$states[$customer->get_billing_country()][$customer->get_billing_state()]; + if(empty($postalCode)) + $postalCode = $customer->get_shipping_postcode(); + + $city = $order->get_shipping_city(); + if(preg_match('/^[0-9]+$/', $city)) { + $func = new Ssbhesabix_Admin_Functions(); + $city = $func->convertCityCodeToName($order->get_shipping_city()); + } + + $hesabixCustomer = array( + 'code' => $code, + 'nikename' => $name, + 'name' => Ssbhesabix_Validation::contactFirstNameValidation($firstName) . Ssbhesabix_Validation::contactLastNameValidation($lastName), + 'ContactType' => 1, + 'NodeFamily' => $nodeFamily, + 'shenasemeli' => $NationalCode, + 'codeeghtesadi' => $EconomicCode, + 'RegistrationNumber' => $RegistrationNumber, + 'website' => $Website, + 'address' => Ssbhesabix_Validation::contactAddressValidation($fullAddress), + 'shahr' => Ssbhesabix_Validation::contactCityValidation($city), + 'ostan' => Ssbhesabix_Validation::contactStateValidation($state_name), + 'keshvar' => Ssbhesabix_Validation::contactCountryValidation($country_name), + 'postalcode' => Ssbhesabix_Validation::contactPostalCodeValidation($postalCode), + 'tel' => Ssbhesabix_Validation::contactPhoneValidation($customer->get_billing_phone()), + 'email' => Ssbhesabix_Validation::contactEmailValidation($customer->get_email()), + 'Tag' => json_encode(array('id_customer' => $id_customer)), + 'des' => __('Customer ID in OnlineStore: ', 'ssbhesabix') . $id_customer, + 'types' => [ + [ + 'checked'=>true, + 'code'=>'customer' + ] + ] + ); + break; + } + + return self::correctCustomerData($hesabixCustomer); + } +//=========================================================================================================== + public static function mapGuestCustomer($code, $id_order): array + { + $order = new WC_Order($id_order); + + $name = $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(); + if (empty($order->get_billing_first_name()) && empty($order->get_billing_last_name())) { + $name = __('Guest Customer', 'ssbhesabix'); + } + $nodeFamily = get_option('ssbhesabix_contact_automatic_save_node_family') == 'yes'? 'اشخاص :' . get_option('ssbhesabix_contact_node_family') :null; + + //checkout fields + $checkout_fields = ssbhesabixCustomerService::getAdditionalCheckoutFileds($id_order); + $NationalCode = $checkout_fields['NationalCode']; + $EconomicCode = $checkout_fields['EconomicCode']; + $RegistrationNumber = $checkout_fields['RegistrationNumber']; + $Website = $checkout_fields['Website']; + +// $country_name = self::$countries[$order->get_billing_country()]; +// $state_name = self::$states[$order->get_billing_state()]; + + + WC()->countries->countries[ $order->shipping_country ]; + $country_name = WC()->countries->countries[ $order->get_billing_country() ]; + $states = WC()->countries->get_states( $order->get_billing_country() ); + $state_name = $states[ $order->get_billing_state() ]; + if(!$state_name) $state_name = WC()->countries->states[$order->billing_country][$order->billing_state]; + if(!$state_name) $state_name = $order->get_billing_state(); + + $city = $order->get_billing_city(); + if(preg_match('/^[0-9]+$/', $city)) { + $func = new Ssbhesabix_Admin_Functions(); + $city = $func->convertCityCodeToName($order->get_billing_city()); + } + + $fullAddress = $order->get_billing_address_1() . '-' . $order->get_billing_address_2(); + + $hesabixCustomer = array( + 'Code' => $code, + 'Name' => $name, + 'FirstName' => Ssbhesabix_Validation::contactFirstNameValidation($order->get_billing_first_name()), + 'LastName' => Ssbhesabix_Validation::contactLastNameValidation($order->get_billing_last_name()), + 'ContactType' => 1, + 'NationalCode' => $NationalCode, + 'EconomicCode' => $EconomicCode, + 'RegistrationNumber' => $RegistrationNumber, + 'Website' => $Website, + 'NodeFamily' => $nodeFamily, + 'Address' => Ssbhesabix_Validation::contactAddressValidation($fullAddress), + 'City' => Ssbhesabix_Validation::contactCityValidation($city), + 'State' => Ssbhesabix_Validation::contactStateValidation($state_name), + 'Country' => Ssbhesabix_Validation::contactCountryValidation($country_name), + 'PostalCode' => Ssbhesabix_Validation::contactPostalCodeValidation($order->get_billing_postcode()), + 'Phone' => Ssbhesabix_Validation::contactPhoneValidation($order->get_billing_phone()), + 'Email' => Ssbhesabix_Validation::contactEmailValidation($order->get_billing_email()), + 'Tag' => json_encode(array('id_customer' => 0)), + 'Note' => __('Customer registered as a GuestCustomer.', 'ssbhesabix'), + ); + + return self::correctCustomerData($hesabixCustomer); + } +//=========================================================================================================== + private static function getMobileFromPhone($phone) { + if(preg_match("/^09\d{9}$/", $phone)) + return $phone; + else if(preg_match("/^9\d{9}$/", $phone)) + return '0' . $phone; + else if(preg_match("/^989\d{9}$/", $phone)) + return str_replace('98', '0' ,$phone); + else return ''; + } +//=========================================================================================================== + private static function correctCustomerData($hesabixCustomer) { + if($hesabixCustomer["Phone"] == '') + unset($hesabixCustomer["Phone"]); + else { + $mobile = self::getMobileFromPhone($hesabixCustomer["Phone"]); + + if($mobile) $hesabixCustomer["Mobile"] = $mobile; + } + + if($hesabixCustomer["Email"] == '') unset($hesabixCustomer["Email"]); + if($hesabixCustomer["Address"] == '') unset($hesabixCustomer["Address"]); + if($hesabixCustomer["PostalCode"] == '') unset($hesabixCustomer["PostalCode"]); + if($hesabixCustomer["City"] == '') unset($hesabixCustomer["City"]); + if($hesabixCustomer["State"] == '') unset($hesabixCustomer["State"]); + if($hesabixCustomer["Country"] == '') unset($hesabixCustomer["Country"]); + + return $hesabixCustomer; + } +//=========================================================================================================== + private static function getCountriesAndStates() + { + if (!isset(self::$countries)) { + $countries_obj = new WC_Countries(); + self::$countries = $countries_obj->get_countries(); + self::$states = $countries_obj->get_states(); + } + } +//=========================================================================================================== + private static function getAdditionalCheckoutFileds($id_order) { + $NationalCode = '_billing_hesabix_nationalcode'; + $EconomicCode = '_billing_hesabix_economiccode'; + $RegistrationNumber = '_billing_hesabix_registerationnumber'; + $Website = '_billing_hesabix_website'; + $NationalCode_isActive = get_option('ssbhesabix_contact_NationalCode_checkbox_hesabix'); + $EconomicCode_isActive = get_option('ssbhesabix_contact_EconomicCode_checkbox_hesabix'); + $RegistrationNumber_isActive = get_option('ssbhesabix_contact_RegistrationNumber_checkbox_hesabix'); + $Website_isActive = get_option('ssbhesabix_contact_Website_checkbox_hesabix'); + $add_additional_fileds = get_option('ssbhesabix_contact_add_additional_checkout_fields_hesabix'); + $fields = array(); + + // add additional fields to checkout + if($add_additional_fileds == '1') { + $fields['NationalCode'] = get_post_meta( $id_order, $NationalCode, true) ?? null; + $fields['EconomicCode'] = get_post_meta( $id_order, $EconomicCode, true) ?? null; + $fields['RegistrationNumber'] = get_post_meta( $id_order, $RegistrationNumber, true) ?? null; + $fields['Website'] = get_post_meta( $id_order, $Website, true) ?? null; + } elseif($add_additional_fileds == '2') { + $NationalCode = get_option('ssbhesabix_contact_NationalCode_text_hesabix'); + $EconomicCode = get_option('ssbhesabix_contact_EconomicCode_text_hesabix'); + $RegistrationNumber = get_option('ssbhesabix_contact_RegistrationNumber_text_hesabix'); + $Website = get_option('ssbhesabix_contact_Website_text_hesabix'); + + if($NationalCode_isActive == 'yes' && $NationalCode) + $fields['NationalCode'] = get_post_meta( $id_order, $NationalCode, true) ?? null; + + if($EconomicCode_isActive == 'yes' && $EconomicCode) + $fields['EconomicCode'] = get_post_meta( $id_order, $EconomicCode, true) ?? null; + + if($RegistrationNumber_isActive == 'yes' && $RegistrationNumber) + $fields['RegistrationNumber'] = get_post_meta( $id_order, $RegistrationNumber, true) ?? null; + + if($Website_isActive == 'yes' && $Website) + $fields['Website'] = get_post_meta( $id_order, $Website, true) ?? null; + } + return $fields; + } +} diff --git a/admin/services/ssbhesabixItemService.php b/admin/services/ssbhesabixItemService.php index e155e76..1728036 100644 --- a/admin/services/ssbhesabixItemService.php +++ b/admin/services/ssbhesabixItemService.php @@ -1,95 +1,119 @@ -get_category_ids(); - $code = $new ? null : $wpFaService->getProductCodeByWpId($id) ; - $price = $product->get_regular_price() ? $product->get_regular_price() : $product->get_price(); - - $hesabixItem = array( - 'Code' => $code, - 'Name' => Ssbhesabix_Validation::itemNameValidation($product->get_title()), - 'PurchasesTitle' => Ssbhesabix_Validation::itemNameValidation($product->get_title()), - 'SalesTitle' => Ssbhesabix_Validation::itemNameValidation($product->get_title()), - 'ItemType' => $product->is_virtual() == 1 ? 1 : 0, - 'Tag' => json_encode(array('id_product' => $id, 'id_attribute' => 0)) - ); - - if(!$code || get_option("ssbhesabix_do_not_update_product_price_in_hesabix", "no") === "no") - $hesabixItem["SellPrice"] = self::getPriceInHesabixDefaultCurrency($price); - if(get_option("ssbhesabix_do_not_update_product_barcode_in_hesabix", "no") === "no") - $hesabixItem["Barcode"] = Ssbhesabix_Validation::itemBarcodeValidation($product->get_sku()); - if(get_option("ssbhesabix_do_not_update_product_category_in_hesabix", "no") === "no") - if($categories) $hesabixItem["NodeFamily"] = self::getCategoryPath($categories[0]); - if(get_option("ssbhesabix_do_not_update_product_product_code_in_hesabix", "no") === "no") - $hesabixItem["ProductCode"] = $id; - - return $hesabixItem; - } -//=========================================================================================================== - public static function mapProductVariation($product, $variation, $id_product, $new = true) { - $wpFaService = new HesabixWpFaService(); - - $id_attribute = $variation->get_id(); - $categories = $product->get_category_ids(); - $code = $new ? null : $wpFaService->getProductCodeByWpId($id_product, $id_attribute); - - $productName = $product->get_title(); - $variationName = $variation->get_attribute_summary(); - $fullName = Ssbhesabix_Validation::itemNameValidation($productName . ' - ' . $variationName); - $price = $variation->get_regular_price() ? $variation->get_regular_price() : $variation->get_price(); - - $hesabixItem = array( - 'Code' => $code, - 'Name' => $fullName, - 'PurchasesTitle' => $fullName, - 'SalesTitle' => $fullName, - 'ItemType' => $variation->is_virtual() == 1 ? 1 : 0, - 'Tag' => json_encode(array( - 'id_product' => $id_product, - 'id_attribute' => $id_attribute - )), - ); - - if(!$code || get_option("ssbhesabix_do_not_update_product_price_in_hesabix", "no") === "no") $hesabixItem["SellPrice"] = self::getPriceInHesabixDefaultCurrency($price); - if(get_option("ssbhesabix_do_not_update_product_barcode_in_hesabix", "no") === "no") $hesabixItem["Barcode"] = Ssbhesabix_Validation::itemBarcodeValidation($variation->get_sku()); - if(get_option("ssbhesabix_do_not_update_product_category_in_hesabix", "no") === "no") $hesabixItem["NodeFamily"] = self::getCategoryPath($categories[0]); - if(get_option("ssbhesabix_do_not_update_product_product_code_in_hesabix", "no") === "no") $hesabixItem["ProductCode"] = $id_attribute; - - return $hesabixItem; - } -//=========================================================================================================== - public static function getPriceInHesabixDefaultCurrency($price) - { - if (!isset($price)) return false; - - $woocommerce_currency = get_woocommerce_currency(); - $hesabix_currency = get_option('ssbhesabix_hesabix_default_currency'); - - if (!is_numeric($price)) $price = intval($price); - - if ($hesabix_currency == 'IRR' && $woocommerce_currency == 'IRT') $price *= 10; - - if ($hesabix_currency == 'IRT' && $woocommerce_currency == 'IRR') $price /= 10; - - return $price; - } -//=========================================================================================================== - public static function getCategoryPath($id_category) - { - if (!isset($id_category)) return ''; - - $path = get_term_parents_list($id_category, 'product_cat', array( - 'format' => 'name', - 'separator' => ':', - 'link' => false, - 'inclusive' => true, - )); - - return substr('products: ' . $path, 0, -1); - } -//=========================================================================================================== +get_category_ids(); + $code = $new ? null : $wpFaService->getProductCodeByWpId($id) ; + $price = $product->get_regular_price() ? $product->get_regular_price() : $product->get_price(); + + $hesabixItem = array( + 'code' => $code, + 'name' => Ssbhesabix_Validation::itemNameValidation($product->get_title()), + 'khadamat' => $product->is_virtual() == 1 ? 1 : 0, + 'Tag' => json_encode(array('id_product' => $id, 'id_attribute' => 0)) + ); + + if(get_option("ssbhesabix_do_not_update_titles_in_hesabix", "no") === "no") { + $hesabixItem['PurchasesTitle'] = Ssbhesabix_Validation::itemNameValidation($product->get_title()); + $hesabixItem['SalesTitle'] = Ssbhesabix_Validation::itemNameValidation($product->get_title()); + } + + if(!$code || get_option("ssbhesabix_do_not_update_product_price_in_hesabix", "no") === "no") + $hesabixItem["priceSell"] = self::getPriceInHesabixDefaultCurrency($price); + if(get_option("ssbhesabix_do_not_update_product_barcode_in_hesabix", "no") === "no") + $hesabixItem["barcodes"] = Ssbhesabix_Validation::itemBarcodeValidation($product->get_sku()); + if(get_option("ssbhesabix_do_not_update_product_category_in_hesabix", "no") === "no") + if($categories) $hesabixItem["NodeFamily"] = self::getCategoryPath($categories[0]); + if(get_option("ssbhesabix_do_not_update_product_product_code_in_hesabix", "no") === "no") + $hesabixItem["ProductCode"] = $id; + + return $hesabixItem; + } +//=========================================================================================================== + public static function mapProductVariation($product, $variation, $id_product, $new = true) { + $wpFaService = new HesabixWpFaService(); + + $id_attribute = $variation->get_id(); + $categories = $product->get_category_ids(); + $code = $new ? null : $wpFaService->getProductCodeByWpId($id_product, $id_attribute); + + $productName = $product->get_title(); + $variationName = $variation->get_attribute_summary(); + + if(get_option("ssbhesabix_remove_attributes_titles") == "yes" || get_option("ssbhesabix_remove_attributes_titles") == "1") { + $values = self::getAttributesValues($variationName); + $fullName = Ssbhesabix_Validation::itemNameValidation($productName . ' - ' . implode(", ", $values)); + } else { + $fullName = Ssbhesabix_Validation::itemNameValidation($productName . ' - ' . $variationName); + } + + $price = $variation->get_regular_price() ? $variation->get_regular_price() : $variation->get_price(); + + $hesabixItem = array( + 'code' => $code, + 'name' => $fullName, + 'khadamat' => $variation->is_virtual() == 1 ? 1 : 0, + 'Tag' => json_encode(array( + 'id_product' => $id_product, + 'id_attribute' => $id_attribute + )), + ); + + if(get_option("ssbhesabix_do_not_update_titles_in_hesabix", "no") === "no") { + $hesabixItem['PurchasesTitle'] = $fullName; + $hesabixItem['SalesTitle'] = $fullName; + } + + if(!$code || get_option("ssbhesabix_do_not_update_product_price_in_hesabix", "no") === "no") $hesabixItem["SellPrice"] = self::getPriceInHesabixDefaultCurrency($price); + if(get_option("ssbhesabix_do_not_update_product_barcode_in_hesabix", "no") === "no") $hesabixItem["Barcode"] = Ssbhesabix_Validation::itemBarcodeValidation($variation->get_sku()); + if(get_option("ssbhesabix_do_not_update_product_category_in_hesabix", "no") === "no") $hesabixItem["NodeFamily"] = self::getCategoryPath($categories[0]); + if(get_option("ssbhesabix_do_not_update_product_product_code_in_hesabix", "no") === "no") $hesabixItem["ProductCode"] = $id_attribute; + + return $hesabixItem; + } +//=========================================================================================================== + public static function getAttributesValues($variationName) { + $pairs = explode(",", $variationName); + + $values = array(); + foreach ($pairs as $pair) { + list($title, $value) = explode(":", $pair); + $values[] = trim($value); + } + return $values; + } +//=========================================================================================================== + public static function getPriceInHesabixDefaultCurrency($price) + { + if (!isset($price)) return false; + + $woocommerce_currency = get_woocommerce_currency(); + $hesabix_currency = get_option('ssbhesabix_hesabix_default_currency'); + + if (!is_numeric($price)) $price = intval($price); + + if ($hesabix_currency == 'IRR' && $woocommerce_currency == 'IRT') $price *= 10; + + if ($hesabix_currency == 'IRT' && $woocommerce_currency == 'IRR') $price /= 10; + + return $price; + } +//=========================================================================================================== + public static function getCategoryPath($id_category) + { + if (!isset($id_category)) return ''; + + $path = get_term_parents_list($id_category, 'product_cat', array( + 'format' => 'name', + 'separator' => ':', + 'link' => false, + 'inclusive' => true, + )); + + return substr('products: ' . $path, 0, -1); + } +//=========================================================================================================== } \ No newline at end of file diff --git a/includes/class-ssbhesabix-activator.php b/includes/class-ssbhesabix-activator.php index 73231a6..4d58713 100644 --- a/includes/class-ssbhesabix-activator.php +++ b/includes/class-ssbhesabix-activator.php @@ -1,71 +1,69 @@ - - * @author HamidReza Gharahzadeh - * @author Sepehr Najafi - */ -class Ssbhesabix_Activator { - public static $ssbhesabix_db_version = '1.1'; - - /** - * Short Description. (use period) - * - * Long Description. - * - * @since 1.0.0 - */ -//=============================================================================================================== - public static function activate() { - add_option('ssbhesabix_webhook_password', bin2hex(openssl_random_pseudo_bytes(16))); - add_option('ssbhesabix_last_log_check_id', 0); - add_option('ssbhesabix_live_mode', 0); - add_option('ssbhesabix_debug_mode', 0); - add_option('ssbhesabix_contact_address_status', 1); - add_option('ssbhesabix_contact_node_family', 'مشتریان فروشگاه آن‌لاین'); - add_option('ssbhesabix_contact_automaatic_save_node_family', 'yes'); - add_option('ssbhesabix_contact_automatically_save_in_hesabix', 'yes'); - add_option('ssbhesabix_activation_date', date("Y-m-d")); - add_option('ssbhesabix_use_export_product_opening_quantity', false); - add_option('ssbhesabix_business_expired', 0); - add_option('ssbhesabix_do_not_submit_product_automatically', "no"); - add_option('ssbhesabix_do_not_update_product_price_in_hesabix', "no"); - add_option('ssbhesabix_contact_add_additional_checkout_fields_hesabix', 1); - add_option('ssbhesabix_account_bid', 0); - add_option('ssbhesabix_account_year', 0); - - self::ssbhesabix_create_database_table(); - } -//=============================================================================================================== - public static function ssbhesabix_create_database_table() - { - global $wpdb; - $table_name = $wpdb->prefix . "ssbhesabix"; - $charset_collate = $wpdb->get_charset_collate(); - - $sql = " - CREATE TABLE $table_name ( - id int(11) UNSIGNED NOT NULL AUTO_INCREMENT, - obj_type varchar(32) NOT NULL, - id_hesabix int(11) UNSIGNED NOT NULL, - id_ps int(11) UNSIGNED NOT NULL, - id_ps_attribute int(11) UNSIGNED NOT NULL DEFAULT 0, - PRIMARY KEY (id) - ) $charset_collate;"; - - require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); - dbDelta($sql); - - update_option('ssbhesabix_db_version', self::$ssbhesabix_db_version); - } -//=============================================================================================================== -} + + * @author HamidReza Gharahzadeh + * @author Sepehr Najafi + */ +class Ssbhesabix_Activator { + public static $ssbhesabix_db_version = '1.1'; + + /** + * Short Description. (use period) + * + * Long Description. + * + * @since 1.0.0 + */ +//=============================================================================================================== + public static function activate() { + add_option('ssbhesabix_webhook_password', bin2hex(openssl_random_pseudo_bytes(16))); + add_option('ssbhesabix_last_log_check_id', 0); + add_option('ssbhesabix_live_mode', 0); + add_option('ssbhesabix_debug_mode', 0); + add_option('ssbhesabix_contact_address_status', 1); + add_option('ssbhesabix_contact_node_family', 'مشتریان فروشگاه آن‌لاین'); + add_option('ssbhesabix_contact_automaatic_save_node_family', 'yes'); + add_option('ssbhesabix_contact_automatically_save_in_hesabix', 'yes'); + add_option('ssbhesabix_activation_date', date("Y-m-d")); + add_option('ssbhesabix_use_export_product_opening_quantity', false); + add_option('ssbhesabix_business_expired', 0); + add_option('ssbhesabix_do_not_submit_product_automatically', "no"); + add_option('ssbhesabix_do_not_update_product_price_in_hesabix', "no"); + add_option('ssbhesabix_contact_add_additional_checkout_fields_hesabix', 1); + + self::ssbhesabix_create_database_table(); + } +//=============================================================================================================== + public static function ssbhesabix_create_database_table() + { + global $wpdb; + $table_name = $wpdb->prefix . "ssbhesabix"; + $charset_collate = $wpdb->get_charset_collate(); + + $sql = " + CREATE TABLE $table_name ( + id int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + obj_type varchar(32) NOT NULL, + id_hesabix int(11) UNSIGNED NOT NULL, + id_ps int(11) UNSIGNED NOT NULL, + id_ps_attribute int(11) UNSIGNED NOT NULL DEFAULT 0, + PRIMARY KEY (id) + ) $charset_collate;"; + + require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); + dbDelta($sql); + + update_option('ssbhesabix_db_version', self::$ssbhesabix_db_version); + } +//=============================================================================================================== +} diff --git a/includes/class-ssbhesabix-api.php b/includes/class-ssbhesabix-api.php index 09d9a6f..1db5e2a 100644 --- a/includes/class-ssbhesabix-api.php +++ b/includes/class-ssbhesabix-api.php @@ -1,443 +1,532 @@ - - * @author HamidReza Gharahzadeh - * @author Sepehr Najafi - */ - -class Ssbhesabix_Api -{ -//================================================================================================ - public function apiRequest($method, $data = array()) - { - if ($method == null) return false; - - $endpoint = 'https://hesabix.ir/' . $method; - - $apiAddress = get_option('ssbhesabix_api_address', 0); - - if($apiAddress == 1) $endpoint = 'https://next.hesabix.ir/' . $method; - - $body = array_merge(array( - 'API-KEY' => get_option('ssbhesabix_account_api'), - ), $data); - - //Debug mode - if (get_option('ssbhesabix_debug_mode')) { - HesabixLogService::log(array("Debug Mode - Data: " . print_r($data, true))); - } - - $options = array( - 'body' => wp_json_encode($body), - 'headers' => array( - 'Content-Type' => 'application/json', - 'API-KEY' => get_option('ssbhesabix_account_api'), - 'activeBid' => get_option('ssbhesabix_account_bid'), - 'activeYear' => get_option('ssbhesabix_account_year'), - ), - 'timeout' => 60, - 'redirection' => 5, - 'blocking' => true, - 'httpversion' => '1.0', - 'sslverify' => false, - 'data_format' => 'body', - ); - - //HesabixLogService::writeLogObj($options); - $wp_remote_post = wp_remote_post($endpoint, $options); - $result = json_decode(wp_remote_retrieve_body($wp_remote_post)); - //Debug mode - if (get_option('ssbhesabix_debug_mode')) { - HesabixLogService::log(array("Debug Mode - Result: " . print_r($result, true))); - } - - //fix API limit request - Maximum request per minutes is 60 times, - sleep(1); - - if ($result == null) { - return 'No response from Hesabix'; - } else { - return $result; - } - return false; - } -//================================================================================================ - //Contact functions - public function contactGet($code) - { - $method = 'contact/get'; - $data = array( - 'code' => $code, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function contactGetById($idList) - { - $method = 'contact/getById'; - $data = array( - 'idList' => $idList, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function contactGetContacts($queryInfo) - { - $method = 'contact/getcontacts'; - $data = array( - 'queryInfo' => $queryInfo, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function contactSave($contact) - { - $method = 'contact/save'; - $data = array( - 'contact' => $contact, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function contactDelete($code) - { - $method = 'contact/delete'; - $data = array( - 'code' => $code, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function contactGetByPhoneOrEmail($phone, $email) { - $method = 'contact/findByPhoneOrEmail'; - $data = array( - 'mobile' => $phone, - 'email' => $email, - 'phone' => $phone, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - //Items functions - public function itemGet($code) - { - $method = 'item/get'; - $data = array( - 'code' => $code, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function itemGetByBarcode($barcode) - { - $method = 'item/getByBarcode'; - $data = array( - 'barcode' => $barcode, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function itemGetById($idList) - { - $method = 'item/getById'; - $data = array( - 'idList' => $idList, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function itemGetItems($queryInfo = null) - { - $method = 'hooks/item/getitems'; - $data = array( - 'queryInfo' => $queryInfo, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function itemSave($item) - { - $method = 'item/save'; - $data = array( - 'item' => $item, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function itemBatchSave($items) - { - $method = 'item/batchsave'; - $data = array( - 'items' => $items, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function itemDelete($code) - { - $method = 'item/delete'; - $data = array( - 'code' => $code, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function itemGetQuantity($warehouseCode, $codes) - { - $method = 'item/GetQuantity'; - $data = array( - 'warehouseCode' => $warehouseCode, - 'codes' => $codes, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - //Invoice functions - public function invoiceGet($number, $type = 0) - { - $method = 'invoice/get'; - $data = array( - 'number' => $number, - 'type' => $type, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function invoiceGetById($id) - { - $method = 'invoice/getById'; - $data = array( - 'id' => $id, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function invoiceGetByIdList($idList) - { - $method = 'invoice/getById'; - $data = array( - 'idList' => $idList, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function invoiceGetInvoices($queryinfo, $type = 0) - { - $method = 'invoice/getinvoices'; - $data = array( - 'type' => $type, - 'queryInfo' => $queryinfo, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function invoiceSave($invoice, $GUID='') - { - $method = 'invoice/save'; - $data = array( - 'invoice' => $invoice, - ); - - if($GUID != '') $data['requestUniqueId'] = $GUID; - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function invoiceDelete($number, $type = 0) - { - $method = 'invoice/delete'; - $data = array( - 'code' => $number, - 'type' => $type, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function invoiceSavePayment($number, $financialData, $accountPath, $date, $amount, $transactionNumber = null, $description = null, $transactionFee = 0) - { - if(get_option('ssbhesabix_invoice_transaction_fee') && get_option('ssbhesabix_invoice_transaction_fee') > 0) { - $transactionFeeOption = get_option('ssbhesabix_invoice_transaction_fee'); - - $func = new Ssbhesabix_Admin_Functions(); - $transactionFeeOption = $func->convertPersianDigitsToEnglish($transactionFeeOption); - - if($transactionFeeOption<100 && $transactionFeeOption>0) $transactionFeeOption /= 100; - $transactionFee = $amount * $transactionFeeOption; - if($transactionFee < 1) $transactionFee = 0; - } - - $method = 'invoice/savepayment'; - $data = array( - 'number' => (int)$number, - 'date' => $date, - 'amount' => $amount, - 'transactionNumber' => $transactionNumber, - 'description' => $description, - 'transactionFee' => $transactionFee, - ); - - $data = array_merge($data, $financialData); - if($accountPath != []) $data = array_merge($data, $accountPath); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function invoiceGetOnlineInvoiceURL($number, $type = 0) - { - $method = 'invoice/getonlineinvoiceurl'; - $data = array( - 'number' => $number, - 'type' => $type, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function itemUpdateOpeningQuantity($items) - { - $method = 'item/UpdateOpeningQuantity'; - $data = array( - 'items' => $items, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function saveWarehouseReceipt($receipt) { - $method = 'invoice/SaveWarehouseReceipt'; - $data = array( - 'deleteOldReceipts' => true, - 'receipt' => $receipt, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function warehouseReceiptGetByIdList($idList) - { - $method = 'invoice/getWarehouseReceipt'; - $data = array( - 'idList' => $idList, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - //Settings functions - public function settingSetChangeHook($url, $hookPassword) - { - $method = 'hooks/setting/SetChangeHook'; - $data = array( - 'url' => $url, - 'hookPassword' => $hookPassword, - ); - - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function settingGetChanges($start = 0) - { - $method = 'hooks/setting/GetChanges'; - $data = array( - 'start' => $start, - ); - return $this->apiRequest($method, $data); - } -//================================================================================================ - public function settingGetAccounts() - { - $method = 'hooks/setting/GetAccounts'; - return $this->apiRequest($method); - } -//================================================================================================ - public function settingGetBanks() - { - $method = 'hooks/setting/getBanks'; - return $this->apiRequest($method); - } -//================================================================================================ - public function settingGetCashes() - { - $method = 'setting/GetCashes'; - return $this->apiRequest($method); - } - -//================================================================================================ - public function settingGetSalesmen() - { - $method = 'setting/getSalesmen'; - return $this->apiRequest($method); - } -//================================================================================================ - public function settingGetCurrency() - { - $method = 'hooks/setting/getCurrency'; - - return $this->apiRequest($method); - } -//================================================================================================ - public function settingGetFiscalYear() - { - $method = 'setting/GetFiscalYear'; - - return $this->apiRequest($method); - } -//================================================================================================ - public function settingGetWarehouses() - { - $method = 'setting/GetWarehouses'; - return $this->apiRequest($method); - } -//================================================================================================ - public function fixClearTags() - { - $method = 'fix/clearTag'; - return $this->apiRequest($method); - } -//================================================================================================ - public function settingGetSubscriptionInfo() - { - $method = 'hooks/setting/getBusinessInfo'; - return $this->apiRequest($method); - } -//================================================================================================ - public function settingExportProdects($data) - { - $method = 'hooks/commodity/import'; - return $this->apiRequest($method,$data); - } - -//================================================================================================ - public function personsImport($data) - { - $method = 'hooks/person/import'; - return $this->apiRequest($method,$data); - } + + * @author HamidReza Gharahzadeh + * @author Sepehr Najafi + */ + +class Ssbhesabix_Api +{ + //================================================================================================ + public function apiRequest($method, $data = array()) + { + if ($method == null) + return false; + + $endpoint = 'https://hesabix.ir/' . $method; + + $apiAddress = get_option('ssbhesabix_api_address', 0); + + if ($apiAddress == 1) + $endpoint = 'https://next.hesabix.ir/' . $method; + + $body = array_merge(array( + 'API-KEY' => get_option('ssbhesabix_account_api'), + ), $data); + + //Debug mode + if (get_option('ssbhesabix_debug_mode')) { + HesabixLogService::log(array("Debug Mode - Data: " . print_r($data, true))); + } + + $options = array( + 'body' => wp_json_encode($body), + 'headers' => array( + 'Content-Type' => 'application/json', + 'API-KEY' => get_option('ssbhesabix_account_api'), + 'activeBid' => get_option('ssbhesabix_account_bid'), + 'activeYear' => get_option('ssbhesabix_account_year'), + ), + 'timeout' => 60, + 'redirection' => 5, + 'blocking' => true, + 'httpversion' => '1.0', + 'sslverify' => false, + 'data_format' => 'body', + ); + + //HesabixLogService::writeLogObj($options); + + $wp_remote_post = wp_remote_post($endpoint, $options); + $result = json_decode(wp_remote_retrieve_body($wp_remote_post)); + + //Debug mode + if (get_option('ssbhesabix_debug_mode')) { + HesabixLogService::log(array("Debug Mode - Result: " . print_r($result, true))); + } + + //fix API limit request - Maximum request per minutes is 60 times, + sleep(1); + + if ($result == null) { + return 'No response from Hesabix'; + } else { + if (!isset($result->Success)) { + switch ($result->ErrorCode) { + case '100': + return 'InternalServerError'; + case '101': + return 'TooManyRequests'; + case '103': + return 'MissingData'; + case '104': + return 'MissingParameter' . '. ErrorMessage: ' . $result->ErrorMessage; + case '105': + return 'ApiDisabled'; + case '106': + return 'UserIsNotOwner'; + case '107': + return 'BusinessNotFound'; + case '108': + return 'BusinessExpired'; + case '110': + return 'IdMustBeZero'; + case '111': + return 'IdMustNotBeZero'; + case '112': + return 'ObjectNotFound' . '. ErrorMessage: ' . $result->ErrorMessage; + case '113': + return 'MissingApiKey'; + case '114': + return 'ParameterIsOutOfRange' . '. ErrorMessage: ' . $result->ErrorMessage; + case '190': + return 'ApplicationError' . '. ErrorMessage: ' . $result->ErrorMessage; + } + } else { + return $result; + } + } + return false; + } + //================================================================================================ + //Contact functions + public function contactGet($code) + { + $method = 'contact/get'; + $data = array( + 'code' => $code, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function contactGetById($idList) + { + $method = 'contact/getById'; + $data = array( + 'idList' => $idList, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function contactGetContacts($queryInfo) + { + $method = 'contact/getcontacts'; + $data = array( + 'queryInfo' => $queryInfo, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function contactSave($contact) + { + $method = 'api/person/mod'; + return $this->apiRequest($method, $contact); + } + //================================================================================================ + public function contactBatchSave($contacts) + { + $method = 'api/person/group/mod'; + $data = array( + 'items' => $contacts, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function contactDelete($code) + { + $method = 'contact/delete'; + $data = array( + 'code' => $code, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function contactGetByPhoneOrEmail($phone, $email) + { + $method = 'contact/findByPhoneOrEmail'; + $data = array( + 'mobile' => $phone, + 'email' => $email, + 'phone' => $phone, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + //Items functions + public function itemGet($code) + { + $method = 'item/get'; + $data = array( + 'code' => $code, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function itemGetByBarcode($barcode) + { + $method = 'item/getByBarcode'; + $data = array( + 'barcode' => $barcode, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function itemGetById($idList) + { + $method = 'item/getById'; + $data = array( + 'idList' => $idList, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function itemGetItems($queryInfo = null) + { + $method = 'api/commodity/search/extra'; + $data = array( + 'queryInfo' => $queryInfo, + ); + + return $this->apiRequest($method, $data); + } + + public function itemGetItemsByCodes($values = []) + { + $method = 'api/commodity/search/bycodes'; + return $this->apiRequest($method, $values); + } + //================================================================================================ + public function itemSave($item) + { + $method = 'api/commodity/mod/0'; + return $this->apiRequest($method, $item); + } + //================================================================================================ + public function itemBatchSave($items) + { + $method = 'api/commodity/group/mod'; + $data = array( + 'items' => $items, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function itemDelete($code) + { + $method = 'item/delete'; + $data = array( + 'code' => $code, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function itemGetQuantity($warehouseCode, $codes) + { + $method = 'item/GetQuantity'; + $data = array( + 'warehouseCode' => $warehouseCode, + 'codes' => $codes, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + //Invoice functions + public function invoiceGet($number, $type = 0) + { + $method = 'invoice/get'; + $data = array( + 'number' => $number, + 'type' => $type, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function invoiceGetById($id) + { + $method = 'invoice/getById'; + $data = array( + 'id' => $id, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function invoiceGetByIdList($idList) + { + $method = 'invoice/getById'; + $data = array( + 'idList' => $idList, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function invoiceGetInvoices($queryinfo, $type = 0) + { + $method = 'invoice/getinvoices'; + $data = array( + 'type' => $type, + 'queryInfo' => $queryinfo, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function invoiceSave($invoice, $GUID = '') + { + $method = 'invoice/save'; + $data = array( + 'invoice' => $invoice, + ); + if ($GUID != '') + $data['requestUniqueId'] = $GUID; + $this->saveStatistics(); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function invoiceDelete($number, $type = 0) + { + $method = 'invoice/delete'; + $data = array( + 'code' => $number, + 'type' => $type, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function invoiceSavePayment($number, $financialData, $accountPath, $date, $amount, $transactionNumber = null, $description = null, $transactionFee = 0) + { + $method = 'invoice/savepayment'; + $data = array( + 'number' => (int) $number, + 'date' => $date, + 'amount' => $amount, + 'transactionNumber' => $transactionNumber, + 'description' => $description, + 'transactionFee' => $transactionFee, + ); + + $data = array_merge($data, $financialData); + if ($accountPath != []) + $data = array_merge($data, $accountPath); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function invoiceGetOnlineInvoiceURL($number, $type = 0) + { + $method = 'invoice/getonlineinvoiceurl'; + $data = array( + 'number' => $number, + 'type' => $type, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function itemUpdateOpeningQuantity($items) + { + $method = 'item/UpdateOpeningQuantity'; + $data = array( + 'items' => $items, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function saveWarehouseReceipt($receipt) + { + $method = 'invoice/SaveWarehouseReceipt'; + $data = array( + 'deleteOldReceipts' => true, + 'receipt' => $receipt, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function warehouseReceiptGetByIdList($idList) + { + $method = 'invoice/getWarehouseReceipt'; + $data = array( + 'idList' => $idList, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function getWarehouseReceipt($objectId) + { + $method = 'warehouse/GetById'; + $data = array( + 'id' => $objectId, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + //Settings functions + public function settingSetChangeHook($url, $hookPassword) + { + $method = 'hooks/setting/SetChangeHook'; + $data = array( + 'url' => $url, + 'hookPassword' => $hookPassword, + ); + + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function settingGetChanges($start = 0) + { + $method = 'hooks/setting/GetChanges'; + $data = array( + 'start' => $start, + ); + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function settingGetAccounts() + { + $method = 'hooks/setting/GetAccounts'; + return $this->apiRequest($method); + } + //================================================================================================ + public function settingGetBanks() + { + $method = 'hooks/setting/getBanks'; + return $this->apiRequest($method); + } + //================================================================================================ + public function settingGetCashes() + { + $method = 'setting/GetCashes'; + return $this->apiRequest($method); + } + //================================================================================================ + public function settingGetProjects() + { + $method = 'api/projects/list'; + return $this->apiRequest($method); + } + //================================================================================================ + public function settingGetSalesmen() + { + $method = 'api/person/list/salesmen'; + return $this->apiRequest($method); + } + //================================================================================================ + public function settingGetCurrency() + { + $method = 'hooks/setting/getCurrency'; + + return $this->apiRequest($method); + } + //================================================================================================ + public function settingGetFiscalYear() + { + $method = 'hooks/setting/GetFiscalYear'; + + return $this->apiRequest($method); + } + //================================================================================================ + public function settingGetWarehouses() + { + $method = 'api/storeroom/list'; + return $this->apiRequest($method); + } + //================================================================================================ + public function fixClearTags() + { + $method = 'fix/clearTag'; + return $this->apiRequest($method); + } + //================================================================================================ + public function settingGetSubscriptionInfo() + { + $method = 'hooks/setting/getBusinessInfo'; + return $this->apiRequest($method); + } + //========================================================================================================================= + public function getLastChangeId($start = 1000000000) + { + $method = 'setting/GetChanges'; + $data = array( + 'start' => $start, + ); + return $this->apiRequest($method, $data); + } + //================================================================================================ + public function saveStatistics() + { + $plugin_version = constant('SSBHESABFA_VERSION'); + + $endpoint = "https://hesabix.ir/statistics/save"; + $body = array( + "Platform" => "Woocommerce/" . $plugin_version, + "Website" => get_site_url(), + 'APIKEY' => get_option('ssbhesabix_account_api'), + "IP" => $_SERVER['REMOTE_ADDR'] + ); + + $options = array( + 'body' => wp_json_encode($body), + 'headers' => array( + 'Content-Type' => 'application/json', + ), + 'timeout' => 60, + 'redirection' => 5, + 'blocking' => true, + 'httpversion' => '1.0', + 'sslverify' => false, + 'data_format' => 'body', + ); + + $wp_remote_post = wp_remote_post($endpoint, $options); + $result = json_decode(wp_remote_retrieve_body($wp_remote_post)); + } + //================================================================================================ + public function checkMobileAndNationalCode($nationalCode, $billingPhone) + { + $method = 'inquiry/checkMobileAndNationalCode'; + $data = array( + 'nationalCode' => $nationalCode, + 'mobile' => $billingPhone, + ); + return $this->apiRequest($method, $data); + } + //================================================================================================ } \ No newline at end of file diff --git a/includes/class-ssbhesabix-deactivator.php b/includes/class-ssbhesabix-deactivator.php index f721a66..86dd543 100644 --- a/includes/class-ssbhesabix-deactivator.php +++ b/includes/class-ssbhesabix-deactivator.php @@ -1,28 +1,28 @@ - - * @author HamidReza Gharahzadeh - * @author Sepehr Najafi - */ -class Ssbhesabix_Deactivator { - - /** - * Short Description. (use period) - * - * Long Description. - * - * @since 1.0.0 - */ - public static function deactivate() { - - } - -} + + * @author HamidReza Gharahzadeh + * @author Sepehr Najafi + */ +class Ssbhesabix_Deactivator { + + /** + * Short Description. (use period) + * + * Long Description. + * + * @since 1.0.0 + */ + public static function deactivate() { + + } + +} diff --git a/includes/class-ssbhesabix-i18n.php b/includes/class-ssbhesabix-i18n.php index 7eb3708..f0ab1e0 100644 --- a/includes/class-ssbhesabix-i18n.php +++ b/includes/class-ssbhesabix-i18n.php @@ -1,33 +1,34 @@ - - * @author HamidReza Gharahzadeh - * @author Sepehr Najafi - */ -class Ssbhesabix_i18n { - - - /** - * Load the plugin text domain for translation. - * - * @since 1.0.0 - */ - public function load_plugin_textdomain() { - - load_plugin_textdomain( - 'ssbhesabix', - false, - dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages1/' - ); - - } -} + + * @author HamidReza Gharahzadeh + * @author Sepehr Najafi + * @author Babak Alizadeh + */ +class Ssbhesabix_i18n { + + + /** + * Load the plugin text domain for translation. + * + * @since 1.0.0 + */ + public function load_plugin_textdomain() { + + load_plugin_textdomain( + 'ssbhesabix', + false, + dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages/' + ); + + } +} diff --git a/includes/class-ssbhesabix-loader.php b/includes/class-ssbhesabix-loader.php index 89784d5..8a9cc4b 100644 --- a/includes/class-ssbhesabix-loader.php +++ b/includes/class-ssbhesabix-loader.php @@ -1,122 +1,123 @@ - - * @author HamidReza Gharahzadeh - * @author Sepehr Najafi - */ - -class Ssbhesabix_Loader { - - /** - * The array of actions registered with WordPress. - * - * @since 1.0.0 - * @access protected - * @var array $actions The actions registered with WordPress to fire when the plugin loads. - */ - protected $actions; - - /** - * The array of filters registered with WordPress. - * - * @since 1.0.0 - * @access protected - * @var array $filters The filters registered with WordPress to fire when the plugin loads. - */ - protected $filters; - - /** - * Initialize the collections used to maintain the actions and filters. - * - * @since 1.0.0 - */ - public function __construct() { - - $this->actions = array(); - $this->filters = array(); - - } - - /** - * Add a new action to the collection to be registered with WordPress. - * - * @since 1.0.0 - * @param string $hook The name of the WordPress action that is being registered. - * @param object $component A reference to the instance of the object on which the action is defined. - * @param string $callback The name of the function definition on the $component. - * @param int $priority Optional. The priority at which the function should be fired. Default is 10. - * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1. - */ - public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) { - $this->actions = $this->add( $this->actions, $hook, $component, $callback, $priority, $accepted_args ); - } - - /** - * Add a new filter to the collection to be registered with WordPress. - * - * @since 1.0.0 - * @param string $hook The name of the WordPress filter that is being registered. - * @param object $component A reference to the instance of the object on which the filter is defined. - * @param string $callback The name of the function definition on the $component. - * @param int $priority Optional. The priority at which the function should be fired. Default is 10. - * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1 - */ - public function add_filter( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) { - $this->filters = $this->add( $this->filters, $hook, $component, $callback, $priority, $accepted_args ); - } - - /** - * A utility function that is used to register the actions and hooks into a single - * collection. - * - * @since 1.0.0 - * @access private - * @param array $hooks The collection of hooks that is being registered (that is, actions or filters). - * @param string $hook The name of the WordPress filter that is being registered. - * @param object $component A reference to the instance of the object on which the filter is defined. - * @param string $callback The name of the function definition on the $component. - * @param int $priority The priority at which the function should be fired. - * @param int $accepted_args The number of arguments that should be passed to the $callback. - * @return array The collection of actions and filters registered with WordPress. - */ - private function add( $hooks, $hook, $component, $callback, $priority, $accepted_args ) { - - $hooks[] = array( - 'hook' => $hook, - 'component' => $component, - 'callback' => $callback, - 'priority' => $priority, - 'accepted_args' => $accepted_args - ); - - return $hooks; - - } - - /** - * Register the filters and actions with WordPress. - * - * @since 1.0.0 - */ - public function run() { - - foreach ( $this->filters as $hook ) { - add_filter( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] ); - } - - foreach ( $this->actions as $hook ) { - add_action( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] ); - } - - } - -} + + * @author HamidReza Gharahzadeh + * @author Sepehr Najafi + * @author Babak Alizadeh + */ + +class Ssbhesabix_Loader { + + /** + * The array of actions registered with WordPress. + * + * @since 1.0.0 + * @access protected + * @var array $actions The actions registered with WordPress to fire when the plugin loads. + */ + protected $actions; + + /** + * The array of filters registered with WordPress. + * + * @since 1.0.0 + * @access protected + * @var array $filters The filters registered with WordPress to fire when the plugin loads. + */ + protected $filters; + + /** + * Initialize the collections used to maintain the actions and filters. + * + * @since 1.0.0 + */ + public function __construct() { + + $this->actions = array(); + $this->filters = array(); + + } + + /** + * Add a new action to the collection to be registered with WordPress. + * + * @since 1.0.0 + * @param string $hook The name of the WordPress action that is being registered. + * @param object $component A reference to the instance of the object on which the action is defined. + * @param string $callback The name of the function definition on the $component. + * @param int $priority Optional. The priority at which the function should be fired. Default is 10. + * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1. + */ + public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) { + $this->actions = $this->add( $this->actions, $hook, $component, $callback, $priority, $accepted_args ); + } + + /** + * Add a new filter to the collection to be registered with WordPress. + * + * @since 1.0.0 + * @param string $hook The name of the WordPress filter that is being registered. + * @param object $component A reference to the instance of the object on which the filter is defined. + * @param string $callback The name of the function definition on the $component. + * @param int $priority Optional. The priority at which the function should be fired. Default is 10. + * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1 + */ + public function add_filter( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) { + $this->filters = $this->add( $this->filters, $hook, $component, $callback, $priority, $accepted_args ); + } + + /** + * A utility function that is used to register the actions and hooks into a single + * collection. + * + * @since 1.0.0 + * @access private + * @param array $hooks The collection of hooks that is being registered (that is, actions or filters). + * @param string $hook The name of the WordPress filter that is being registered. + * @param object $component A reference to the instance of the object on which the filter is defined. + * @param string $callback The name of the function definition on the $component. + * @param int $priority The priority at which the function should be fired. + * @param int $accepted_args The number of arguments that should be passed to the $callback. + * @return array The collection of actions and filters registered with WordPress. + */ + private function add( $hooks, $hook, $component, $callback, $priority, $accepted_args ) { + + $hooks[] = array( + 'hook' => $hook, + 'component' => $component, + 'callback' => $callback, + 'priority' => $priority, + 'accepted_args' => $accepted_args + ); + + return $hooks; + + } + + /** + * Register the filters and actions with WordPress. + * + * @since 1.0.0 + */ + public function run() { + + foreach ( $this->filters as $hook ) { + add_filter( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] ); + } + + foreach ( $this->actions as $hook ) { + add_action( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] ); + } + + } + +} diff --git a/includes/class-ssbhesabix-validation.php b/includes/class-ssbhesabix-validation.php index 9c803c4..02e23ef 100644 --- a/includes/class-ssbhesabix-validation.php +++ b/includes/class-ssbhesabix-validation.php @@ -1,317 +1,318 @@ - - * @author HamidReza Gharahzadeh - * @author Sepehr Najafi - */ - -class Ssbhesabix_Validation -{ - public static function itemCodeValidation($code) - { - $code = preg_replace('/[^0-9]/', '', $code); - $code = self::formatFarsiNumbers($code); - return mb_substr($code, 0, 5); - } -//============================================================================================= - public static function itemNameValidation($name) - { - $name = self::formatFarsiNumbers($name); - return self::remove_emoji($name, 199); - } -//============================================================================================= - public static function formatFarsiNumbers($str) { - $farsiNumbers = ["۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹"]; - $englishNumbers = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]; - for ($i = 0; $i < 10; $i++) - $str = str_replace($farsiNumbers[$i], $englishNumbers[$i], $str); - return $str; - } -//============================================================================================= - public static function itemBarcodeValidation($barcode) - { - $barcode = self::formatFarsiNumbers($barcode); - return mb_substr($barcode, 0, 999); - } -//============================================================================================= - public static function itemCategoryValidation($category) {return $category;} -//============================================================================================= - public static function itemDescriptionValidation($description) {return mb_substr($description, 0, 199);} -//============================================================================================= - public static function itemMainUnitValidation($mainUnit) {return mb_substr($mainUnit, 0, 29);} -//============================================================================================= - public static function itemSubUnitValidation($subUnit) {return mb_substr($subUnit, 0, 29);} -//============================================================================================= - public static function itemConversionFactorValidation($conversionFactor) - { - if ($conversionFactor < 0) { - return 0; - } else { - return $conversionFactor; - } - } -//============================================================================================= - public static function itemSalesTaxValidation($salesTax) - { - if ($salesTax >= 0 && $salesTax <= 100) { - return $salesTax; - } else { - return 0; - } - } -//============================================================================================= - public static function itemSalesInfoValidation($salesInfo) {return mb_substr($salesInfo, 0, 99);} -//============================================================================================= - public static function itemPurchaseCostValidation($purchaseCost) - { - if ($purchaseCost >= 0) { - return $purchaseCost; - } else { - return 0; - } - } -//============================================================================================= - public static function itemPurchaseInfoValidation($purchaseInfo) {return mb_substr($purchaseInfo, 0, 99);} -//============================================================================================= - public static function itemTagValidation($tag) {return mb_substr($tag, 0, 254);} -//============================================================================================= - public static function contactCodeValidation($code) - { - $code = preg_replace('/[^0-9]/', '', $code); - return mb_substr($code, 0, 5); - } -//============================================================================================= - public static function contactDisplayNameValidation($displayName) {return mb_substr($displayName, 0, 99);} -//============================================================================================= - public static function contactCompanyValidation($company) {return mb_substr($company, 0, 99);} -//============================================================================================= - public static function contactTitleValidation($title) {return mb_substr($title, 0, 49);} -//============================================================================================= - public static function contactFirstNameValidation($firstName) {return mb_substr($firstName, 0, 49);} -//============================================================================================= - public static function contactLastNameValidation($lastName) {return mb_substr($lastName, 0, 49);} -//============================================================================================= - public static function contactAddressValidation($address) {return mb_substr($address, 0, 149);} -//============================================================================================= - public static function contactCountryValidation($country) {return mb_substr($country, 0, 49);} -//============================================================================================= - public static function contactStateValidation($state) { - if ( is_numeric( $state ) ) { - if(is_plugin_active("persian-woocommerce-shipping/woocommerce-shipping.php")) { - $state = PWS()::get_state( $state ); - } - } - return mb_substr($state, 0, 49); - } -//============================================================================================= - public static function contactCityValidation($city) { - if ( is_numeric( $city ) ) { - if(is_plugin_active("persian-woocommerce-shipping/woocommerce-shipping.php")) { - $city = PWS()::get_city($city); - } - } - return mb_substr($city, 0, 49); - } -//============================================================================================= - public static function contactPostalCodeValidation($postalCode) - { - $postalCode = preg_replace('/[^0-9]/', '', $postalCode); - $postalCode = self::formatFarsiNumbers($postalCode); - return mb_substr($postalCode, 0, 10); - } -//============================================================================================= - public static function contactPhoneValidation($phone) - { - $phone = preg_replace('/[^0-9]/', '', $phone); - $phone = self::formatFarsiNumbers($phone); - return mb_substr($phone, 0, 14); - } -//============================================================================================= - public static function contactMobileValidation($mobile) - { - $mobile = preg_replace('/[^0-9]/', '', $mobile); - return mb_substr($mobile, 0, 14); - } -//============================================================================================= - public static function contactFaxValidation($fax) - { - $fax = preg_replace('/[^0-9]/', '', $fax); - return mb_substr($fax, 0, 14); - } -//============================================================================================= - public static function contactEmailValidation($email) - { - $isValid = true; - $atIndex = strrpos($email, "@"); - if (is_bool($atIndex) && !$atIndex) { - $isValid = false; - } else { - $domain = substr($email, $atIndex + 1); - $local = substr($email, 0, $atIndex); - $localLen = strlen($local); - $domainLen = strlen($domain); - if ($localLen < 1 || $localLen > 64) { - // local part length exceeded - $isValid = false; - } else if ($domainLen < 1 || $domainLen > 255) { - // domain part length exceeded - $isValid = false; - } else if ($local[0] == '.' || $local[$localLen - 1] == '.') { - // local part starts or ends with '.' - $isValid = false; - } else if (preg_match('/\\.\\./', $local)) { - // local part has two consecutive dots - $isValid = false; - } else if (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain)) { - // character not valid in domain part - $isValid = false; - } else if (preg_match('/\\.\\./', $domain)) { - // domain part has two consecutive dots - $isValid = false; - } else if - (!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/', - str_replace("\\\\", "", $local))) { - // character not valid in local part unless - // local part is quoted - if (!preg_match('/^"(\\\\"|[^"])+"$/', - str_replace("\\\\", "", $local))) { - $isValid = false; - } - } - } - - if ($isValid) { - return $email; - } else { - return null; - } - } -//============================================================================================= - public static function contactWebsiteValidation($website) {return mb_substr($website, 0, 119);} -//============================================================================================= - public static function contactNoteValidation($note) {return mb_substr($note, 0, 499);} -//============================================================================================= - public static function contactCategoryValidation($category) {return $category;} -//============================================================================================= - public static function contactTagValidation($tag) {return mb_substr($tag, 0, 254);} -//============================================================================================= - public static function invoiceFinancialYearValidation($financialYear) {return $financialYear;} -//============================================================================================= - public static function invoiceCurrencyRateValidation($currencyRate) - { - if ($currencyRate > 0) { - return $currencyRate; - } else { - return 1; - } - } -//============================================================================================= - public static function invoiceNumberValidation($number) {return mb_substr($number, 0, 49);} -//============================================================================================= - public static function invoiceContactTitleValidation($contactTitle) {return mb_substr($contactTitle, 0, 199);} -//============================================================================================= - public static function invoiceDueDateValidation($dueDate) {return $dueDate;} -//============================================================================================= - public static function invoiceNoteValidation($note) {return mb_substr($note, 0, 499);} -//============================================================================================= - public static function invoiceReferenceValidation($reference) {return mb_substr($reference, 0, 49);} -//============================================================================================= - public static function invoiceTagValidation($tag) {return mb_substr($tag, 0, 254);} -//============================================================================================= - public function invoiceItemsValidation($items) {return $items;} -//============================================================================================= - public static function invoiceItemDescriptionValidation($description) { - return self::remove_emoji($description, 249); - } -//============================================================================================= - public static function invoiceItemQuantityValidation($quantity) - { - if ($quantity > 0) { - return $quantity; - } else { - return 1; - } - } -//============================================================================================= - public static function invoiceItemUnitValidation($unit) {return mb_substr($unit, 0, 29);} -//============================================================================================= - public static function invoiceItemUnitPriceValidation($unitPrice) - { - if ($unitPrice >= 0) { - return $unitPrice; - } else { - return 0; - } - } -//============================================================================================= - public static function invoiceItemAmountValidation($amount) - { - if ($amount >= 0) { - return $amount; - } else { - return 0; - } - } -//============================================================================================= - public static function invoiceItemDiscountValidation($discount) - { - if ($discount >= 0) { - return $discount; - } else { - return 0; - } - } -//============================================================================================= - public static function invoiceItemTaxValidation($tax) - { - if ($tax >= 0) { - return $tax; - } else { - return 0; - } - } -//============================================================================================= - public static function invoiceItemTotalAmountValidation($totalAmount) - { - if ($totalAmount >= 0) { - return $totalAmount; - } else { - return 0; - } - } -//============================================================================================= - public static function remove_emoji($string, $length = 200) : string - { - $regex_alphanumeric = '/[\x{1F100}-\x{1F1FF}]/u'; - $clear_string = preg_replace($regex_alphanumeric, '', $string); - - $regex_symbols = '/[\x{1F300}-\x{1F5FF}]/u'; - $clear_string = preg_replace($regex_symbols, '', $clear_string); - - $regex_emoticons = '/[\x{1F600}-\x{1F64F}]/u'; - $clear_string = preg_replace($regex_emoticons, '', $clear_string); - - $regex_transport = '/[\x{1F680}-\x{1F6FF}]/u'; - $clear_string = preg_replace($regex_transport, '', $clear_string); - - $regex_supplemental = '/[\x{1F900}-\x{1F9FF}]/u'; - $clear_string = preg_replace($regex_supplemental, '', $clear_string); - - $regex_misc = '/[\x{2600}-\x{26FF}\x{1F7E9}-\x{1F7EF}]/u'; - $clear_string = preg_replace($regex_misc, '', $clear_string); - - $regex_dingbats = '/[\x{2700}-\x{27BF}]/u'; - $clear_string = preg_replace($regex_dingbats, '', $clear_string); - - $truncated_string = mb_substr($clear_string, 0, $length); - - return $truncated_string; - } -//============================================================================================= -} + + * @author HamidReza Gharahzadeh + * @author Sepehr Najafi + * @author Babak Alizadeh + */ + +class Ssbhesabix_Validation +{ + public static function itemCodeValidation($code) + { + $code = preg_replace('/[^0-9]/', '', $code); + $code = self::formatFarsiNumbers($code); + return mb_substr($code, 0, 5); + } +//============================================================================================= + public static function itemNameValidation($name) + { + $name = self::formatFarsiNumbers($name); + return self::remove_emoji($name, 199); + } +//============================================================================================= + public static function formatFarsiNumbers($str) { + $farsiNumbers = ["۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹"]; + $englishNumbers = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]; + for ($i = 0; $i < 10; $i++) + $str = str_replace($farsiNumbers[$i], $englishNumbers[$i], $str); + return $str; + } +//============================================================================================= + public static function itemBarcodeValidation($barcode) + { + $barcode = self::formatFarsiNumbers($barcode); + return mb_substr($barcode, 0, 999); + } +//============================================================================================= + public static function itemCategoryValidation($category) {return $category;} +//============================================================================================= + public static function itemDescriptionValidation($description) {return mb_substr($description, 0, 199);} +//============================================================================================= + public static function itemMainUnitValidation($mainUnit) {return mb_substr($mainUnit, 0, 29);} +//============================================================================================= + public static function itemSubUnitValidation($subUnit) {return mb_substr($subUnit, 0, 29);} +//============================================================================================= + public static function itemConversionFactorValidation($conversionFactor) + { + if ($conversionFactor < 0) { + return 0; + } else { + return $conversionFactor; + } + } +//============================================================================================= + public static function itemSalesTaxValidation($salesTax) + { + if ($salesTax >= 0 && $salesTax <= 100) { + return $salesTax; + } else { + return 0; + } + } +//============================================================================================= + public static function itemSalesInfoValidation($salesInfo) {return mb_substr($salesInfo, 0, 99);} +//============================================================================================= + public static function itemPurchaseCostValidation($purchaseCost) + { + if ($purchaseCost >= 0) { + return $purchaseCost; + } else { + return 0; + } + } +//============================================================================================= + public static function itemPurchaseInfoValidation($purchaseInfo) {return mb_substr($purchaseInfo, 0, 99);} +//============================================================================================= + public static function itemTagValidation($tag) {return mb_substr($tag, 0, 254);} +//============================================================================================= + public static function contactCodeValidation($code) + { + $code = preg_replace('/[^0-9]/', '', $code); + return mb_substr($code, 0, 5); + } +//============================================================================================= + public static function contactDisplayNameValidation($displayName) {return mb_substr($displayName, 0, 99);} +//============================================================================================= + public static function contactCompanyValidation($company) {return mb_substr($company, 0, 99);} +//============================================================================================= + public static function contactTitleValidation($title) {return mb_substr($title, 0, 49);} +//============================================================================================= + public static function contactFirstNameValidation($firstName) {return mb_substr($firstName, 0, 49);} +//============================================================================================= + public static function contactLastNameValidation($lastName) {return mb_substr($lastName, 0, 49);} +//============================================================================================= + public static function contactAddressValidation($address) {return mb_substr($address, 0, 149);} +//============================================================================================= + public static function contactCountryValidation($country) {return mb_substr($country, 0, 49);} +//============================================================================================= + public static function contactStateValidation($state) { + if ( is_numeric( $state ) ) { + if(is_plugin_active("persian-woocommerce-shipping/woocommerce-shipping.php")) { + $state = PWS()::get_state( $state ); + } + } + return mb_substr($state, 0, 49); + } +//============================================================================================= + public static function contactCityValidation($city) { + if ( is_numeric( $city ) ) { + if(is_plugin_active("persian-woocommerce-shipping/woocommerce-shipping.php")) { + $city = PWS()::get_city($city); + } + } + return mb_substr($city, 0, 49); + } +//============================================================================================= + public static function contactPostalCodeValidation($postalCode) + { + $postalCode = preg_replace('/[^0-9]/', '', $postalCode); + $postalCode = self::formatFarsiNumbers($postalCode); + return mb_substr($postalCode, 0, 10); + } +//============================================================================================= + public static function contactPhoneValidation($phone) + { + $phone = preg_replace('/[^0-9]/', '', $phone); + $phone = self::formatFarsiNumbers($phone); + return mb_substr($phone, 0, 14); + } +//============================================================================================= + public static function contactMobileValidation($mobile) + { + $mobile = preg_replace('/[^0-9]/', '', $mobile); + return mb_substr($mobile, 0, 14); + } +//============================================================================================= + public static function contactFaxValidation($fax) + { + $fax = preg_replace('/[^0-9]/', '', $fax); + return mb_substr($fax, 0, 14); + } +//============================================================================================= + public static function contactEmailValidation($email) + { + $isValid = true; + $atIndex = strrpos($email, "@"); + if (is_bool($atIndex) && !$atIndex) { + $isValid = false; + } else { + $domain = substr($email, $atIndex + 1); + $local = substr($email, 0, $atIndex); + $localLen = strlen($local); + $domainLen = strlen($domain); + if ($localLen < 1 || $localLen > 64) { + // local part length exceeded + $isValid = false; + } else if ($domainLen < 1 || $domainLen > 255) { + // domain part length exceeded + $isValid = false; + } else if ($local[0] == '.' || $local[$localLen - 1] == '.') { + // local part starts or ends with '.' + $isValid = false; + } else if (preg_match('/\\.\\./', $local)) { + // local part has two consecutive dots + $isValid = false; + } else if (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain)) { + // character not valid in domain part + $isValid = false; + } else if (preg_match('/\\.\\./', $domain)) { + // domain part has two consecutive dots + $isValid = false; + } else if + (!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/', + str_replace("\\\\", "", $local))) { + // character not valid in local part unless + // local part is quoted + if (!preg_match('/^"(\\\\"|[^"])+"$/', + str_replace("\\\\", "", $local))) { + $isValid = false; + } + } + } + + if ($isValid) { + return $email; + } else { + return null; + } + } +//============================================================================================= + public static function contactWebsiteValidation($website) {return mb_substr($website, 0, 119);} +//============================================================================================= + public static function contactNoteValidation($note) {return mb_substr($note, 0, 499);} +//============================================================================================= + public static function contactCategoryValidation($category) {return $category;} +//============================================================================================= + public static function contactTagValidation($tag) {return mb_substr($tag, 0, 254);} +//============================================================================================= + public static function invoiceFinancialYearValidation($financialYear) {return $financialYear;} +//============================================================================================= + public static function invoiceCurrencyRateValidation($currencyRate) + { + if ($currencyRate > 0) { + return $currencyRate; + } else { + return 1; + } + } +//============================================================================================= + public static function invoiceNumberValidation($number) {return mb_substr($number, 0, 49);} +//============================================================================================= + public static function invoiceContactTitleValidation($contactTitle) {return mb_substr($contactTitle, 0, 199);} +//============================================================================================= + public static function invoiceDueDateValidation($dueDate) {return $dueDate;} +//============================================================================================= + public static function invoiceNoteValidation($note) {return mb_substr($note, 0, 499);} +//============================================================================================= + public static function invoiceReferenceValidation($reference) {return mb_substr($reference, 0, 49);} +//============================================================================================= + public static function invoiceTagValidation($tag) {return mb_substr($tag, 0, 254);} +//============================================================================================= + public function invoiceItemsValidation($items) {return $items;} +//============================================================================================= + public static function invoiceItemDescriptionValidation($description) { + return self::remove_emoji($description, 249); + } +//============================================================================================= + public static function invoiceItemQuantityValidation($quantity) + { + if ($quantity > 0) { + return $quantity; + } else { + return 1; + } + } +//============================================================================================= + public static function invoiceItemUnitValidation($unit) {return mb_substr($unit, 0, 29);} +//============================================================================================= + public static function invoiceItemUnitPriceValidation($unitPrice) + { + if ($unitPrice >= 0) { + return $unitPrice; + } else { + return 0; + } + } +//============================================================================================= + public static function invoiceItemAmountValidation($amount) + { + if ($amount >= 0) { + return $amount; + } else { + return 0; + } + } +//============================================================================================= + public static function invoiceItemDiscountValidation($discount) + { + if ($discount >= 0) { + return $discount; + } else { + return 0; + } + } +//============================================================================================= + public static function invoiceItemTaxValidation($tax) + { + if ($tax >= 0) { + return $tax; + } else { + return 0; + } + } +//============================================================================================= + public static function invoiceItemTotalAmountValidation($totalAmount) + { + if ($totalAmount >= 0) { + return $totalAmount; + } else { + return 0; + } + } +//============================================================================================= + public static function remove_emoji($string, $length = 200) : string + { + $regex_alphanumeric = '/[\x{1F100}-\x{1F1FF}]/u'; + $clear_string = preg_replace($regex_alphanumeric, '', $string); + + $regex_symbols = '/[\x{1F300}-\x{1F5FF}]/u'; + $clear_string = preg_replace($regex_symbols, '', $clear_string); + + $regex_emoticons = '/[\x{1F600}-\x{1F64F}]/u'; + $clear_string = preg_replace($regex_emoticons, '', $clear_string); + + $regex_transport = '/[\x{1F680}-\x{1F6FF}]/u'; + $clear_string = preg_replace($regex_transport, '', $clear_string); + + $regex_supplemental = '/[\x{1F900}-\x{1F9FF}]/u'; + $clear_string = preg_replace($regex_supplemental, '', $clear_string); + + $regex_misc = '/[\x{2600}-\x{26FF}\x{1F7E9}-\x{1F7EF}]/u'; + $clear_string = preg_replace($regex_misc, '', $clear_string); + + $regex_dingbats = '/[\x{2700}-\x{27BF}]/u'; + $clear_string = preg_replace($regex_dingbats, '', $clear_string); + + $truncated_string = mb_substr($clear_string, 0, $length); + + return $truncated_string; + } +//============================================================================================= +} diff --git a/includes/class-ssbhesabix-webhook.php b/includes/class-ssbhesabix-webhook.php index 233ae68..0dce617 100644 --- a/includes/class-ssbhesabix-webhook.php +++ b/includes/class-ssbhesabix-webhook.php @@ -1,279 +1,352 @@ - - * @author HamidReza Gharahzadeh - * @author Sepehr Najafi - */ - -class Ssbhesabix_Webhook -{ - public $invoicesObjectId = array(); - public $invoiceItemsCode = array(); - public $itemsObjectId = array(); - public $contactsObjectId = array(); - public $warehouseReceiptsObjectId = array(); - - public function __construct() - { - //HesabixLogService::writeLogStr("Calling Webhook"); - $wpFaService = new HesabixWpFaService(); - - $hesabixApi = new Ssbhesabix_Api(); - - $lastChange = get_option('ssbhesabix_last_log_check_id'); - $changes = $hesabixApi->settingGetChanges($lastChange + 1); - - if ($changes->Success) { - update_option('ssbhesabix_business_expired', 0); - - foreach ($changes->Result as $item) { - if (!$item->API) { - switch ($item->ObjectType) { - case 'Invoice': - if ($item->Action == 123) { - $wpFa1 = $wpFaService->getWpFaByHesabixId('order', $item->Extra2); - if($wpFa1) { - $wpFaService->delete($wpFa1); - HesabixLogService::writeLogStr("The invoice link with the order deleted. Invoice number: " . $item->Extra2 . ", Order id: " . $wpFa1->idWp); - } - } - $this->invoicesObjectId[] = $item->ObjectId; - foreach (explode(',', $item->Extra) as $invoiceItem) { - if ($invoiceItem != '') { - $this->invoiceItemsCode[] = $invoiceItem; - } - } - break; - case 'WarehouseReceipt': - $this->warehouseReceiptsObjectId[] = $item->ObjectId; - break; - case 'Product': - if ($item->Action == 53) { - $wpFa = $wpFaService->getWpFaByHesabixId('product', $item->Extra); - if ($wpFa) { - global $wpdb; - $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id' => $wpFa->id)); - } - break; - } - - $this->itemsObjectId[] = $item->ObjectId; - break; - case 'Contact': - if ($item->Action == 33) { - $id_obj = $wpFaService->getWpFaIdByHesabixId('customer', $item->Extra); - global $wpdb; - $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id' => $id_obj)); - break; - } - - $this->contactsObjectId[] = $item->ObjectId; - break; - } - } - } - - $this->invoiceItemsCode = array_unique($this->invoiceItemsCode); - $this->contactsObjectId = array_unique($this->contactsObjectId); - $this->itemsObjectId = array_unique($this->itemsObjectId); - $this->invoicesObjectId = array_unique($this->invoicesObjectId); - - $this->setChanges(); - - $lastChange = end($changes->Result); - if (is_object($lastChange)) - update_option('ssbhesabix_last_log_check_id', $lastChange->Id); - else if ($changes->LastId) - update_option('ssbhesabix_last_log_check_id', $changes->LastId); - - } else { - HesabixLogService::log(array("ssbhesabix - Cannot check last changes. Error Message: " . (string)$changes->ErrorMessage . ". Error Code: " . (string)$changes->ErrorCode)); - return false; - } - - return true; - } -//================================================================================================================================= - public function setChanges() - { - //Items - $items = array(); - - if (!empty($this->warehouseReceiptsObjectId)) { - $receipts = $this->getObjectsByIdList($this->warehouseReceiptsObjectId, 'WarehouseReceipt'); - if ($receipts != false) { - foreach ($receipts as $receipt) { - foreach ($receipt->Items as $item) - array_push($this->invoiceItemsCode, $item->ItemCode); - } - } - } - - if (!empty($this->itemsObjectId)) { - $objects = $this->getObjectsByIdList($this->itemsObjectId, 'item'); - if ($objects != false) { - foreach ($objects as $object) { - array_push($items, $object); - } - } - } - - if (!empty($this->invoiceItemsCode)) { - $objects = $this->getObjectsByCodeList($this->invoiceItemsCode); - - if ($objects != false) { - foreach ($objects as $object) { - array_push($items, $object); - } - } - } - - if (!empty($items)) { - update_option("ssbhesabix_inside_product_edit", 1); - try { - foreach ($items as $item) { - Ssbhesabix_Admin_Functions::setItemChanges($item); - } - } catch (Exception $e) { - } finally { - update_option("ssbhesabix_inside_product_edit", 0); - } - } - - return true; - } -//================================================================================================================================= - public function setInvoiceChanges($invoice) - { - if (!is_object($invoice)) return false; - - $wpFaService = new HesabixWpFaService(); - - $number = $invoice->Number; - $json = json_decode($invoice->Tag); - if (is_object($json)) { - $id_order = $json->id_order; - } else { - $id_order = 0; - } - - if ($invoice->InvoiceType == 0) { - if ($id_order == 0) { - HesabixLogService::log(array("This invoice is not defined in OnlineStore. Invoice Number: " . $number)); - } else { - //check if order exist in wooCommerce - $id_obj = $wpFaService->getWpFaId('order', $id_order); - if ($id_obj != false) { - global $wpdb; - $row = $wpdb->get_row("SELECT `id_hesabix` FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id` = $id_obj"); - if (is_object($row) && $row->id_hesabix != $number) { - $id_hesabix_old = $row->id_hesabix; - //ToDo: number must be int in hesabix, what can I do - $wpdb->update($wpdb->prefix . 'ssbhesabix', array('id_hesabix' => $number), array('id' => $id_obj)); - HesabixLogService::log(array("Invoice Number changed. Old Number: $id_hesabix_old. New ID: $number")); - } - } - } - } - } -//================================================================================================================================= - public function setContactChanges($contact) - { - if (!is_object($contact)) return false; - - $code = $contact->Code; - - $json = json_decode($contact->Tag); - if (is_object($json)) { - $id_customer = $json->id_customer; - } else { - $id_customer = 0; - } - - if ($id_customer == 0) { - HesabixLogService::log(array("This Customer is not define in OnlineStore. Customer code: $code")); - return false; - } - - $wpFaService = new HesabixWpFaService(); - $id_obj = $wpFaService->getWpFaId('customer', $id_customer); - - if ($id_obj != false) { - global $wpdb; - $row = $wpdb->get_row("SELECT `id_hesabix` FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id` = $id_obj"); - - if (is_object($row) && $row->id_hesabix != $code) { - $id_hesabix_old = $row->id_hesabix; - $wpdb->update($wpdb->prefix . 'ssbhesabix', array('id_hesabix' => (int)$code), array('id' => $id_obj)); - - HesabixLogService::log(array("Contact Code changed. Old ID: $id_hesabix_old. New ID: $code")); - } - } - - return true; - } -//================================================================================================================================= - public function getObjectsByIdList($idList, $type) - { - $hesabixApi = new Ssbhesabix_Api(); - $warehouseCode = get_option('ssbhesabix_item_update_quantity_based_on'); - switch ($type) { - case 'item': - if($warehouseCode == '-1') { - $result = $hesabixApi->itemGetById($idList); - } else { - $items = $hesabixApi->itemGetById($idList); - $codeList = []; - foreach ($items->Result as $item) { - array_push($codeList, $item->Code); - } - $result = $hesabixApi->itemGetQuantity($warehouseCode, $codeList); - } - break; - case 'contact': - $result = $hesabixApi->contactGetById($idList); - break; - case 'invoice': - $result = $hesabixApi->invoiceGetInvoices(array("Filters" => array("Property" => "Id", "Operator" => "in", "Value" => $idList))); - break; - case 'WarehouseReceipt': - $result = $hesabixApi->warehouseReceiptGetByIdList($idList); - break; - default: - return false; - } - - if (is_object($result) && $result->Success) { - return $result->Result; - } - - return false; - } -//================================================================================================================================= - public function getObjectsByCodeList($codeList) - { - $filters = array(array("Property" => "Code", "Operator" => "in", "Value" => $codeList)); - $hesabixApi = new Ssbhesabix_Api(); - - $warehouse = get_option('ssbhesabix_item_update_quantity_based_on', "-1"); - if ($warehouse == "-1") - $result = $hesabixApi->itemGetItems(array('Take' => 100000, 'Filters' => $filters)); - else { - $result = $hesabixApi->itemGetQuantity($warehouse, $codeList); - } - - //$result = $hesabixApi->itemGetItems($queryInfo); - - if (is_object($result) && $result->Success) { - return $warehouse == "-1" ? $result->Result->List : $result->Result; - } - - return false; - } -} + + * @author HamidReza Gharahzadeh + * @author Sepehr Najafi + * @author Babak Alizadeh + */ + +class Ssbhesabix_Webhook +{ + public $invoicesObjectId = array(); + public $invoiceItemsCode = array(); + public $itemsObjectId = array(); + public $contactsObjectId = array(); + public $warehouseReceiptsObjectId = array(); + + public function __construct() + { + //hesabixLogService::writeLogStr("Calling Webhook"); + $wpFaService = new HesabixWpFaService(); + + $hesabixApi = new Ssbhesabix_Api(); + + $lastChange = get_option('ssbhesabix_last_log_check_id'); + $changes = $hesabixApi->settingGetChanges($lastChange + 1); + + if ($changes->Success) { + update_option('ssbhesabix_business_expired', 0); + + foreach ($changes->Result as $item) { + if (!$item->API) { + switch ($item->ObjectType) { + case 'Invoice': + if ($item->Action == 123) { + $wpFa1 = $wpFaService->getWpFaByHesabixId('order', $item->Extra2); + if($wpFa1) { + $wpFaService->delete($wpFa1); + HesabixLogService::writeLogStr("The invoice link with the order deleted. Invoice number: " . $item->Extra2 . ", Order id: " . $wpFa1->idWp); + } + } + $this->invoicesObjectId[] = $item->ObjectId; + foreach (explode(',', $item->Extra) as $invoiceItem) { + if ($invoiceItem != '') { + $this->invoiceItemsCode[] = $invoiceItem; + } + } + break; + case 'WarehouseReceipt': + if ($item->Action == 261) { + global $wpdb; + $hesabixApi = new Ssbhesabix_Api(); + $receipt = $hesabixApi->getWarehouseReceipt($item->ObjectId); +// HesabixLogService::writeLogObj($receipt->Result->Items); + foreach ($receipt->Result->Items as $receiptItem) { + $wpFa = $wpFaService->getWpFaByHesabixId('product', $receiptItem->ItemCode); + $wpdb->insert($wpdb->prefix . 'ssbhesabix', array( + 'id_hesabix' => (int)$item->ObjectId, + 'obj_type' => "receiptItems", + 'id_ps' => $wpFa->idWp, + 'id_ps_attribute' => $wpFa->idWpAttribute + )); + } + + if (get_option('ssbhesabix_item_update_quantity', 'no') == 'no') { + HesabixLogService::writeLogStr("Sync Products Quantity is Off"); + } + } + if ($item->Action == 263) { + global $wpdb; + $rows = $wpdb->get_results("SELECT * FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id_hesabix` = $item->ObjectId"); + $receiptID = $item->ObjectId; + foreach ($rows as $row) { + $post_id = ($row->id_ps_attribute && $row->id_ps_attribute > 0) ? $row->id_ps_attribute : $row->id_ps; + //$product = wc_get_product( $post_id ); + + if (get_option('ssbhesabix_item_update_quantity', 'no') == 'no') { + HesabixLogService::writeLogStr("Sync Products Quantity is Off"); + } + + $productId = $row->id_ps; + $attributeId = $row->id_ps_attribute; + + if (get_option('ssbhesabix_item_update_quantity', 'no') == 'yes') + update_post_meta($attributeId, '_manage_stock', 'yes'); + + if ($productId == $attributeId) $attributeId = 0; + $result = array(); + + $wpFaService = new HesabixWpFaService(); + $wpFa = $wpFaService->getWpFa('product', $productId, $attributeId); + if ($wpFa) { + + $api = new Ssbhesabix_Api(); + $warehouse = get_option('ssbhesabix_item_update_quantity_based_on', "-1"); + if ($warehouse == "-1") + $response = $api->itemGet($wpFa->idHesabix); + else { + $response = $api->itemGetQuantity($warehouse, array($wpFa->idHesabix)); + } + + if ($response->Success) { + $item = $warehouse == "-1" ? $response->Result : $response->Result[0]; + $newProps = Ssbhesabix_Admin_Functions::setItemChanges($item); + } else { + HesabixLogService::writeLogStr("Product is not defined in Hesabix"); + } + } + } + + $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id_hesabix' => $receiptID)); + break; + } + $this->warehouseReceiptsObjectId[] = $item->ObjectId; + break; + case 'Product': + if ($item->Action == 53) { + $wpFa = $wpFaService->getWpFaByHesabixId('product', $item->Extra); + if ($wpFa) { + global $wpdb; + $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id' => $wpFa->id)); + } + break; + } + + $this->itemsObjectId[] = $item->ObjectId; + break; + case 'Contact': + if ($item->Action == 33) { + $id_obj = $wpFaService->getWpFaIdByHesabixId('customer', $item->Extra); + global $wpdb; + $wpdb->delete($wpdb->prefix . 'ssbhesabix', array('id' => $id_obj)); + break; + } + + $this->contactsObjectId[] = $item->ObjectId; + break; + } + } + } + + $this->invoiceItemsCode = array_unique($this->invoiceItemsCode); + $this->contactsObjectId = array_unique($this->contactsObjectId); + $this->itemsObjectId = array_unique($this->itemsObjectId); + $this->invoicesObjectId = array_unique($this->invoicesObjectId); + + $this->setChanges(); + + $lastChange = end($changes->Result); + if (is_object($lastChange)) + update_option('ssbhesabix_last_log_check_id', $lastChange->Id); + else if ($changes->LastId) + update_option('ssbhesabix_last_log_check_id', $changes->LastId); + + } else { + HesabixLogService::log(array("ssbhesabix - Cannot check last changes. Error Message: " . (string)$changes->ErrorMessage . ". Error Code: " . (string)$changes->ErrorCode)); + if ($changes->ErrorCode == 108) { + update_option('ssbhesabix_business_expired', 1); + add_action('admin_notices', array(__CLASS__, 'ssbhesabix_business_expired_notice')); + } + return false; + } + + return true; + } +//================================================================================================================================= + public function ssbhesabix_business_expired_notice() + { + echo '

' . __('Cannot connect to Hesabix. Business expired.', 'ssbhesabix') . '

'; + } +//================================================================================================================================= + public function setChanges() + { + //Items + $items = array(); + + if (!empty($this->warehouseReceiptsObjectId)) { + $receipts = $this->getObjectsByIdList($this->warehouseReceiptsObjectId, 'WarehouseReceipt'); + if ($receipts != false) { + foreach ($receipts as $receipt) { + foreach ($receipt->Items as $item) + array_push($this->invoiceItemsCode, $item->ItemCode); + } + } + } + + if (!empty($this->itemsObjectId)) { + $objects = $this->getObjectsByIdList($this->itemsObjectId, 'item'); + if ($objects != false) { + foreach ($objects as $object) { + array_push($items, $object); + } + } + } + + if (!empty($this->invoiceItemsCode)) { + $objects = $this->getObjectsByCodeList($this->invoiceItemsCode); + + if ($objects != false) { + foreach ($objects as $object) { + array_push($items, $object); + } + } + } + + if (!empty($items)) { + update_option("ssbhesabix_inside_product_edit", 1); + try { + foreach ($items as $item) { + Ssbhesabix_Admin_Functions::setItemChanges($item); + } + } catch (Exception $e) { + } finally { + update_option("ssbhesabix_inside_product_edit", 0); + } + } + + return true; + } +//================================================================================================================================= + public function setInvoiceChanges($invoice) + { + if (!is_object($invoice)) return false; + + $wpFaService = new HesabixWpFaService(); + + $number = $invoice->Number; + $json = json_decode($invoice->Tag); + if (is_object($json)) { + $id_order = $json->id_order; + } else { + $id_order = 0; + } + + if ($invoice->InvoiceType == 0) { + if ($id_order == 0) { + HesabixLogService::log(array("This invoice is not defined in OnlineStore. Invoice Number: " . $number)); + } else { + //check if order exist in wooCommerce + $id_obj = $wpFaService->getWpFaId('order', $id_order); + if ($id_obj != false) { + global $wpdb; + $row = $wpdb->get_row("SELECT `id_hesabix` FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id` = $id_obj"); + if (is_object($row) && $row->id_hesabix != $number) { + $id_hesabix_old = $row->id_hesabix; + //ToDo: number must be int in hesabix + $wpdb->update($wpdb->prefix . 'ssbhesabix', array('id_hesabix' => $number), array('id' => $id_obj)); + HesabixLogService::log(array("Invoice Number changed. Old Number: $id_hesabix_old. New ID: $number")); + } + } + } + } + } +//================================================================================================================================= + public function setContactChanges($contact) + { + if (!is_object($contact)) return false; + + $code = $contact->Code; + + $json = json_decode($contact->Tag); + if (is_object($json)) { + $id_customer = $json->id_customer; + } else { + $id_customer = 0; + } + + if ($id_customer == 0) { + HesabixLogService::log(array("This Customer is not define in OnlineStore. Customer code: $code")); + return false; + } + + $wpFaService = new HesabixWpFaService(); + $id_obj = $wpFaService->getWpFaId('customer', $id_customer); + + if ($id_obj != false) { + global $wpdb; + $row = $wpdb->get_row("SELECT `id_hesabix` FROM `" . $wpdb->prefix . "ssbhesabix` WHERE `id` = $id_obj"); + + if (is_object($row) && $row->id_hesabix != $code) { + $id_hesabix_old = $row->id_hesabix; + $wpdb->update($wpdb->prefix . 'ssbhesabix', array('id_hesabix' => (int)$code), array('id' => $id_obj)); + + HesabixLogService::log(array("Contact Code changed. Old ID: $id_hesabix_old. New ID: $code")); + } + } + + return true; + } +//================================================================================================================================= + public function getObjectsByIdList($idList, $type) + { + $hesabixApi = new Ssbhesabix_Api(); + $warehouseCode = get_option('ssbhesabix_item_update_quantity_based_on'); + switch ($type) { + case 'item': + if($warehouseCode == '-1') { + $result = $hesabixApi->itemGetById($idList); + } else { + $items = $hesabixApi->itemGetById($idList); + $codeList = []; + foreach ($items->Result as $item) { + array_push($codeList, $item->Code); + } + $result = $hesabixApi->itemGetQuantity($warehouseCode, $codeList); + } + break; + case 'contact': + $result = $hesabixApi->contactGetById($idList); + break; + case 'invoice': + $result = $hesabixApi->invoiceGetInvoices(array("Filters" => array("Property" => "Id", "Operator" => "in", "Value" => $idList))); + break; + case 'WarehouseReceipt': + $result = $hesabixApi->warehouseReceiptGetByIdList($idList); + break; + default: + return false; + } + + if (is_object($result) && $result->Success) { + return $result->Result; + } + + return false; + } +//================================================================================================================================= + public function getObjectsByCodeList($codeList) + { + $hesabixApi = new Ssbhesabix_Api(); + + $warehouse = get_option('ssbhesabix_item_update_quantity_based_on', "-1"); + if ($warehouse == "-1") + $result = $hesabixApi->itemGetItemsByCodes($codeList); + else { + $result = $hesabixApi->itemGetQuantity($warehouse, $codeList); + } + + //$result = $hesabixApi->itemGetItems($queryInfo); + + if (is_object($result) && $result->Success) { + return $warehouse == "-1" ? $result->Result->List : $result->Result; + } + + return false; + } +} diff --git a/includes/class-ssbhesabix.php b/includes/class-ssbhesabix.php index 59650b2..2b10951 100644 --- a/includes/class-ssbhesabix.php +++ b/includes/class-ssbhesabix.php @@ -1,321 +1,343 @@ - - * @author HamidReza Gharahzadeh - * @author Sepehr Najafi - */ - -class Ssbhesabix -{ - - /** - * The loader that's responsible for maintaining and registering all hooks that power - * the plugin. - * - * @since 1.0.0 - * @access protected - * @var Ssbhesabix_Loader $loader Maintains and registers all hooks for the plugin. - */ - protected $loader; - - /** - * The unique identifier of this plugin. - * - * @since 1.0.0 - * @access protected - * @var string $plugin_name The string used to uniquely identify this plugin. - */ - protected $plugin_name; - - /** - * The current version of the plugin. - * - * @since 1.0.0 - * @access protected - * @var string $version The current version of the plugin. - */ - protected $version; -//========================================================================================================== - /** - * Define the core functionality of the plugin. - * - * Set the plugin name and the plugin version that can be used throughout the plugin. - * Load the dependencies, define the locale, and set the hooks for the admin area and - * the public-facing side of the site. - * - * @since 1.0.0 - */ - public function __construct() - { - if (defined('SSBHESABIX_VERSION')) { - $this->version = SSBHESABIX_VERSION; - } else { - $this->version = '0.1.1'; - } - $this->plugin_name = 'ssbhesabix'; - - $this->load_dependencies(); - $this->set_locale(); - $this->define_admin_hooks(); - } -//========================================================================================================== - /** - * Load the required dependencies for this plugin. - * - * Include the following files that make up the plugin: - * - * - Ssbhesabix_Loader. Orchestrates the hooks of the plugin. - * - Ssbhesabix_i18n. Defines internationalization functionality. - * - Ssbhesabix_Admin. Defines all hooks for the admin area. - * - Ssbhesabix_Public. Defines all hooks for the public side of the site. - * - * Create an instance of the loader which will be used to register the hooks - * with WordPress. - * - * @since 1.0.0 - * @access private - */ - private function load_dependencies() - { - - /** - * The class responsible for orchestrating the actions and filters of the - * core plugin. - */ - require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-ssbhesabix-loader.php'; - - /** - * The class responsible for defining internationalization functionality - * of the plugin. - */ - require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-ssbhesabix-i18n.php'; - - /** - * The class responsible for defining all actions that occur in the admin area. - */ - require_once plugin_dir_path(dirname(__FILE__)) . 'admin/class-ssbhesabix-admin.php'; - - /** - * The class responsible for defining all Hesabix API methods - */ - require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-ssbhesabix-api.php'; - - $this->loader = new Ssbhesabix_Loader(); - - /** - * The class responsible for defining all Hesabix data Validations - */ - require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-ssbhesabix-validation.php'; - - $this->loader = new Ssbhesabix_Loader(); - - } -//===================================================================================== - /** - * Define the locale for this plugin for internationalization. - * - * Uses the Plugin_Name_i18n class in order to set the domain and to register the hook - * with WordPress. - * - * @since 1.0.0 - * @access private - */ - private function set_locale() - { - $plugin_i18n = new Ssbhesabix_i18n(); - - $this->loader->add_action('plugins_loaded', $plugin_i18n, 'load_plugin_textdomain'); - } -//===================================================================================== - /** - * Register all of the hooks related to the admin area functionality - * of the plugin. - * - * @since 1.0.0 - * @access private - */ - private function define_admin_hooks() - { - $plugin_admin = new Ssbhesabix_Admin($this->get_plugin_name(), $this->get_version()); - - //Related to check DB ver on plugin update - $this->loader->add_action('plugins_loaded', $plugin_admin, 'ssbhesabix_update_db_check'); - - $this->loader->add_action('admin_enqueue_scripts', $plugin_admin, 'enqueue_styles'); - $this->loader->add_action('admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts'); - - //Related to webhook set - $this->loader->add_filter('query_vars', $plugin_admin, 'ssbhesabix_query_vars'); - $this->loader->add_action('parse_request', $plugin_admin, 'ssbhesabix_parse_request'); - - $this->loader->add_action('wp_ajax_nopriv_handle_webhook_request', $plugin_admin, 'handle_webhook_request'); - $this->loader->add_action('wp_ajax_handle_webhook_request', $plugin_admin, 'handle_webhook_request'); - - if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) { - - $this->loader->add_action('init', $plugin_admin, 'ssbhesabix_init_internal'); - - //Check plugin live mode - if (get_option('ssbhesabix_live_mode')) { - if (get_option('ssbhesabix_hesabix_default_currency') === 0) { - $this->loader->add_action('admin_notices', $plugin_admin, 'ssbhesabix_currency_notice'); - } - - // these lines add hesabix id to the all products list page and make it sortable as well - /////////////////////////////////////////////////////////////////////////////////////////////////////// - if(get_option('ssbhesabix_show_product_code_in_products_page') === 'yes') { - $this->loader->add_filter( 'manage_edit-product_columns', $plugin_admin,'admin_products_hesabixId_column', 12 ); - $this->loader->add_action( 'manage_product_posts_custom_column', $plugin_admin, 'admin_products_hesabixId_column_content', 10, 2 ); - $this->loader->add_filter( 'manage_edit-product_sortable_columns', $plugin_admin,'admin_products_hesabixId_column'); - } - - $this->loader->add_action('custom_product_tabs', $plugin_admin, 'ssbhesabix_general_notices'); - - // add filter and action for woocommerce order list - $this->loader->add_filter('manage_edit-shop_order_columns', $plugin_admin, 'custom_hesabix_column_order_list', 20); - $this->loader->add_action('manage_shop_order_posts_custom_column', $plugin_admin, 'custom_orders_list_column_content', 20, 2); - $this->loader->add_filter('bulk_actions-edit-shop_order', $plugin_admin, 'custom_orders_list_bulk_action', 20, 1); - $this->loader->add_filter('handle_bulk_actions-edit-shop_order', $plugin_admin, 'custom_orders_list_bulk_action_run', 10, 3); - // check add fields to checkout page by hesabix plugin - if(get_option('ssbhesabix_contact_add_additional_checkout_fields_hesabix') == 1) - $this->loader->add_filter('woocommerce_checkout_fields', $plugin_admin, 'add_additional_fields_to_checkout', 10, 3); - - // show checkout additional fields in order detail - if(get_option('ssbhesabix_contact_add_additional_checkout_fields_hesabix') == 1) - $this->loader->add_action('woocommerce_admin_order_data_after_billing_address', $plugin_admin, 'show_additional_fields_in_order_detail', 10, 3); - - //Runs when a new order added. - $this->loader->add_action('woocommerce_order_status_changed', $plugin_admin, 'ssbhesabix_hook_order_status_change', 10, 3); - - //Runs when an order paid. -// $this->loader->add_action('woocommerce_payment_complete', $plugin_admin, 'ssbhesabix_hook_payment_confirmation', 10, 1); -// $this->loader->add_filter('woocommerce_payment_complete_order_status', $plugin_admin, 'ssbhesabix_hook_payment_confirmation', 10, 1); -// $this->loader->add_filter('woocommerce_order_status_completed', $plugin_admin, 'ssbhesabix_hook_payment_confirmation', 10, 1); - $this->loader->add_filter('woocommerce_order_status_changed', $plugin_admin, 'ssbhesabix_hook_payment_confirmation', 11, 3); - - //Runs when a user's profile is first created. - $this->loader->add_action('edit_user_profile', $plugin_admin, 'ssbhesabix_hook_edit_user'); - - $this->loader->add_action('user_register', $plugin_admin, 'ssbhesabix_hook_user_register'); -// $this->loader->add_action('woocommerce_new_customer', $plugin_admin, 'ssbhesabix_hook_user_register'); -// $this->loader->add_action('woocommerce_created_customer', $plugin_admin, 'ssbhesabix_hook_user_register'); - //Runs when a user updates personal options from the admin screen. - $this->loader->add_action('personal_options_update', $plugin_admin, 'ssbhesabix_hook_user_register'); - //Runs when a user's profile is updated. - $this->loader->add_action('profile_update', $plugin_admin, 'ssbhesabix_hook_user_register'); - //Runs when a user is deleted. - $this->loader->add_action('delete_user', $plugin_admin, 'ssbhesabix_hook_delete_user'); - - //Runs when a product is added. -// $this->loader->add_action('woocommerce_new_product', $plugin_admin, 'ssbhesabix_hook_new_product'); -// $this->loader->add_action('woocommerce_new_product_variation', $plugin_admin, 'ssbhesabix_hook_new_product_variation', 10, 2); - //Runs when a product is updated. - $this->loader->add_action('woocommerce_update_product', $plugin_admin, 'ssbhesabix_hook_new_product'); -// $this->loader->add_action('woocommerce_update_product_variation', $plugin_admin, 'ssbhesabix_hook_new_product'); - //Runs when a product is deleted. - $this->loader->add_action('before_delete_post', $plugin_admin, 'ssbhesabix_hook_delete_product'); - //$this->loader->add_action('woocommerce_delete_product_variation', $plugin_admin, 'ssbhesabix_hook_delete_product_variation'); - - //Display Hesabix item code in Product data section - $this->loader->add_action('woocommerce_product_options_general_product_data', $plugin_admin, 'ssbhesabix_hook_product_options_general_product_data'); - $this->loader->add_action('woocommerce_process_product_meta', $plugin_admin, 'ssbhesabix_hook_process_product_meta'); - //Display Hesabix item code in Product variable attribute section - $this->loader->add_action('woocommerce_product_after_variable_attributes', $plugin_admin, 'ssbhesabix_hook_product_after_variable_attributes', 10, 3); - $this->loader->add_action('woocommerce_save_product_variation', $plugin_admin, 'ssbhesabix_hook_save_product_variation', 10, 3); - - $this->loader->add_filter('woocommerce_product_data_tabs', $plugin_admin, 'add_hesabix_product_data_tab'); - $this->loader->add_action('woocommerce_product_data_panels', $plugin_admin, 'add_hesabix_product_data_fields'); - - } elseif (!get_option('ssbhesabix_live_mode')) { - $this->loader->add_action('admin_notices', $plugin_admin, 'ssbhesabix_live_mode_notice'); - } - - /* - * Action - Ajax 'Export Tabs' from Hesabix/Export - * @since 1.0.0 - */ - $this->loader->add_filter('wp_ajax_adminExportProducts', $plugin_admin, 'adminExportProductsCallback'); - $this->loader->add_filter('wp_ajax_adminImportProducts', $plugin_admin, 'adminImportProductsCallback'); - $this->loader->add_filter('wp_ajax_adminExportProductsOpeningQuantity', $plugin_admin, 'adminExportProductsOpeningQuantityCallback'); - $this->loader->add_filter('wp_ajax_adminExportCustomers', $plugin_admin, 'adminExportCustomersCallback'); - - /* - * Action - Ajax 'Sync Tabs' from Hesabix/Sync - * @since 1.0.0 - */ - $this->loader->add_filter('wp_ajax_adminSyncChanges', $plugin_admin, 'adminSyncChangesCallback'); - $this->loader->add_filter('wp_ajax_adminSyncProducts', $plugin_admin, 'adminSyncProductsCallback'); - $this->loader->add_filter('wp_ajax_adminSyncOrders', $plugin_admin, 'adminSyncOrdersCallback'); - $this->loader->add_filter('wp_ajax_adminUpdateProducts', $plugin_admin, 'adminUpdateProductsCallback'); - $this->loader->add_filter('wp_ajax_adminUpdateProductsWithFilter', $plugin_admin, 'adminUpdateProductsWithFilterCallback'); - $this->loader->add_filter('wp_ajax_adminSubmitInvoice', $plugin_admin, 'adminSubmitInvoiceCallback'); - - /* - * Action - Ajax 'Log Tab' from Hesabix/Log - * @since 1.0.0 - */ - $this->loader->add_filter('wp_ajax_adminCleanLogFile', $plugin_admin, 'adminCleanLogFileCallback'); - - $this->loader->add_filter('wp_ajax_adminSyncProductsManually', $plugin_admin, 'adminSyncProductsManuallyCallback', 10, 4); - $this->loader->add_filter('wp_ajax_adminClearPluginData', $plugin_admin, 'adminClearPluginDataCallback', 10, 4); - $this->loader->add_filter('wp_ajax_adminInstallPluginData', $plugin_admin, 'adminInstallPluginDataCallback', 10, 4); - - $this->loader->add_filter('wp_ajax_adminChangeProductCode', $plugin_admin, 'adminChangeProductCodeCallback'); - $this->loader->add_filter('wp_ajax_adminDeleteProductLink', $plugin_admin, 'adminDeleteProductLinkCallback'); - $this->loader->add_filter('wp_ajax_adminUpdateProduct', $plugin_admin, 'adminUpdateProductCallback'); - $this->loader->add_filter('wp_ajax_adminChangeProductsCode', $plugin_admin, 'adminChangeProductsCodeCallback'); - $this->loader->add_filter('wp_ajax_adminDeleteProductsLink', $plugin_admin, 'adminDeleteProductsLinkCallback'); - $this->loader->add_filter('wp_ajax_adminUpdateProductAndVariations', $plugin_admin, 'adminUpdateProductAndVariationsCallback'); - - } else { - $this->loader->add_action('admin_notices', $plugin_admin, 'ssbhesabix_missing_notice'); - } - } -//===================================================================================== - /** - * Run the loader to execute all of the hooks with WordPress. - * - * @since 1.0.0 - */ - public function run() {$this->loader->run();} -//===================================================================================== - /** - * The name of the plugin used to uniquely identify it within the context of - * WordPress and to define internationalization functionality. - * - * @return string The name of the plugin. - * @since 1.0.0 - */ - public function get_plugin_name() {return $this->plugin_name;} -//===================================================================================== - /** - * The reference to the class that orchestrates the hooks with the plugin. - * - * @return Ssbhesabix_Loader Orchestrates the hooks of the plugin. - * @since 1.0.0 - */ - public function get_loader() {return $this->loader;} -//===================================================================================== - /** - * Retrieve the version number of the plugin. - * - * @return string The version number of the plugin. - * @since 1.0.0 - */ - public function get_version() {return $this->version;} -//===================================================================================== -} + + * @author HamidReza Gharahzadeh + * @author Sepehr Najafi + * @author Babak Alizadeh + */ + +class Ssbhesabix +{ + + /** + * The loader that's responsible for maintaining and registering all hooks that power + * the plugin. + * + * @since 1.0.0 + * @access protected + * @var Ssbhesabix_Loader $loader Maintains and registers all hooks for the plugin. + */ + protected $loader; + + /** + * The unique identifier of this plugin. + * + * @since 1.0.0 + * @access protected + * @var string $plugin_name The string used to uniquely identify this plugin. + */ + protected $plugin_name; + + /** + * The current version of the plugin. + * + * @since 1.0.0 + * @access protected + * @var string $version The current version of the plugin. + */ + protected $version; +//========================================================================================================== + /** + * Define the core functionality of the plugin. + * + * Set the plugin name and the plugin version that can be used throughout the plugin. + * Load the dependencies, define the locale, and set the hooks for the admin area and + * the public-facing side of the site. + * + * @since 1.0.0 + */ + public function __construct() + { + if (defined('SSBHESABIX_VERSION')) { + $this->version = SSBHESABIX_VERSION; + } else { + $this->version = '0.40.1'; + } + $this->plugin_name = 'ssbhesabix'; + + $this->load_dependencies(); + $this->set_locale(); + $this->define_admin_hooks(); + } +//========================================================================================================== + /** + * Load the required dependencies for this plugin. + * + * Include the following files that make up the plugin: + * + * - Ssbhesabix_Loader. Orchestrates the hooks of the plugin. + * - Ssbhesabix_i18n. Defines internationalization functionality. + * - Ssbhesabix_Admin. Defines all hooks for the admin area. + * - Ssbhesabix_Public. Defines all hooks for the public side of the site. + * + * Create an instance of the loader which will be used to register the hooks + * with WordPress. + * + * @since 1.0.0 + * @access private + */ + private function load_dependencies() + { + + /** + * The class responsible for orchestrating the actions and filters of the + * core plugin. + */ + require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-ssbhesabix-loader.php'; + + /** + * The class responsible for defining internationalization functionality + * of the plugin. + */ + require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-ssbhesabix-i18n.php'; + + /** + * The class responsible for defining all actions that occur in the admin area. + */ + require_once plugin_dir_path(dirname(__FILE__)) . 'admin/class-ssbhesabix-admin.php'; + + /** + * The class responsible for defining all hesabix API methods + */ + require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-ssbhesabix-api.php'; + + $this->loader = new Ssbhesabix_Loader(); + + /** + * The class responsible for defining all hesabix data Validations + */ + require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-ssbhesabix-validation.php'; + + $this->loader = new Ssbhesabix_Loader(); + + } +//===================================================================================== + /** + * Define the locale for this plugin for internationalization. + * + * Uses the Plugin_Name_i18n class in order to set the domain and to register the hook + * with WordPress. + * + * @since 1.0.0 + * @access private + */ + private function set_locale() + { + $plugin_i18n = new Ssbhesabix_i18n(); + + $this->loader->add_action('plugins_loaded', $plugin_i18n, 'load_plugin_textdomain'); + } +//===================================================================================== + /** + * Register all of the hooks related to the admin area functionality + * of the plugin. + * + * @since 1.0.0 + * @access private + */ + private function define_admin_hooks() + { + $plugin_admin = new Ssbhesabix_Admin($this->get_plugin_name(), $this->get_version()); + + //Related to check DB ver on plugin update + //$this->loader->add_action('plugins_loaded', $plugin_admin, 'ssbhesabix_update_db_check'); + + $this->loader->add_action('admin_enqueue_scripts', $plugin_admin, 'enqueue_styles'); + $this->loader->add_action('admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts'); + + //Related to webhook set + $this->loader->add_filter('query_vars', $plugin_admin, 'ssbhesabix_query_vars'); + $this->loader->add_action('parse_request', $plugin_admin, 'ssbhesabix_parse_request'); + + $this->loader->add_action('wp_ajax_nopriv_handle_webhook_request', $plugin_admin, 'ssbhesabix_parse_request'); + $this->loader->add_action('wp_ajax_handle_webhook_request', $plugin_admin, 'ssbhesabix_parse_request'); + + if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) { + + $this->loader->add_action('init', $plugin_admin, 'ssbhesabix_init_internal'); + + //Check plugin live mode + if (get_option('ssbhesabix_live_mode')) { + if (get_option('ssbhesabix_hesabix_default_currency') === 0) { + $this->loader->add_action('admin_notices', $plugin_admin, 'ssbhesabix_currency_notice'); + } + + if(get_option('ssbhesabix_show_hesabix_code_in_excel_export', 'no') == 'yes' || get_option('ssbhesabix_show_hesabix_code_in_excel_export', 0) == 1) { + ///////////ADD COLUMN TO WOOCOMMERCE CSV + $this->loader->add_filter( 'woocommerce_product_export_column_names', $plugin_admin, 'admin_product_add_column' ); + $this->loader->add_filter( 'woocommerce_product_export_product_default_columns', $plugin_admin, 'admin_product_add_column' ); + $this->loader->add_filter('woocommerce_product_export_rows', $plugin_admin, 'admin_product_export_rows', 10, 2); + } + // these lines add hesabix id to the all products list page and make it sortable as well + /////////////////////////////////////////////////////////////////////////////////////////////////////// + if(get_option('ssbhesabix_show_product_code_in_products_page') === 'yes') { + $this->loader->add_filter( 'manage_edit-product_columns', $plugin_admin,'admin_products_hesabixId_column', 12 ); + $this->loader->add_action( 'manage_product_posts_custom_column', $plugin_admin, 'admin_products_hesabixId_column_content', 10, 2 ); + $this->loader->add_filter( 'manage_edit-product_sortable_columns', $plugin_admin,'admin_products_hesabixId_column'); + } + + $this->loader->add_action('custom_product_tabs', $plugin_admin, 'ssbhesabix_general_notices'); + + // add filter and action for woocommerce order list + + $this->loader->add_filter('bulk_actions-edit-shop_order', $plugin_admin, 'custom_orders_list_bulk_action', 20, 1); + $this->loader->add_filter('handle_bulk_actions-edit-shop_order', $plugin_admin, 'custom_orders_list_bulk_action_run', 10, 3); + + if (get_option('woocommerce_custom_orders_table_enabled') == 'yes') { + $this->loader->add_filter( 'woocommerce_shop_order_list_table_columns', $plugin_admin, 'custom_hesabix_column_order_list', 20); + $this->loader->add_action( 'woocommerce_shop_order_list_table_custom_column', $plugin_admin, 'custom_orders_list_column_content', 10, 2 ); + } else { + $this->loader->add_filter('manage_edit-shop_order_columns', $plugin_admin, 'custom_hesabix_column_order_list', 20); + $this->loader->add_action('manage_shop_order_posts_custom_column', $plugin_admin, 'custom_orders_list_column_content', 20, 2); + } + + // check add fields to checkout page by hesabix plugin + if(get_option('ssbhesabix_contact_add_additional_checkout_fields_hesabix') == 1) { + $this->loader->add_filter('woocommerce_checkout_fields', $plugin_admin, 'add_additional_fields_to_checkout', 10, 3); + } + + // show checkout additional fields in order detail + if(get_option('ssbhesabix_contact_add_additional_checkout_fields_hesabix') == 1) { + $this->loader->add_action('woocommerce_admin_order_data_after_billing_address', $plugin_admin, 'show_additional_fields_in_order_detail', 10, 3); + } + + //Runs when a new order added. + $this->loader->add_action('woocommerce_order_status_changed', $plugin_admin, 'ssbhesabix_hook_order_status_change', 10, 3); + + //Runs when an order paid. +// $this->loader->add_action('woocommerce_payment_complete', $plugin_admin, 'ssbhesabix_hook_payment_confirmation', 10, 1); +// $this->loader->add_filter('woocommerce_payment_complete_order_status', $plugin_admin, 'ssbhesabix_hook_payment_confirmation', 10, 1); +// $this->loader->add_filter('woocommerce_order_status_completed', $plugin_admin, 'ssbhesabix_hook_payment_confirmation', 10, 1); + $this->loader->add_filter('woocommerce_order_status_changed', $plugin_admin, 'ssbhesabix_hook_payment_confirmation', 11, 3); + + $this->loader->add_action('woocommerce_new_order', $plugin_admin, 'ssbhesabix_hook_new_order', 11, 2); + + //Runs when a user's profile is first created. + $this->loader->add_action('edit_user_profile', $plugin_admin, 'ssbhesabix_hook_edit_user'); + + $this->loader->add_action('user_register', $plugin_admin, 'ssbhesabix_hook_user_register'); +// $this->loader->add_action('woocommerce_new_customer', $plugin_admin, 'ssbhesabix_hook_user_register'); +// $this->loader->add_action('woocommerce_created_customer', $plugin_admin, 'ssbhesabix_hook_user_register'); + //Runs when a user updates personal options from the admin screen. + $this->loader->add_action('personal_options_update', $plugin_admin, 'ssbhesabix_hook_user_register'); + //Runs when a user's profile is updated. + $this->loader->add_action('profile_update', $plugin_admin, 'ssbhesabix_hook_user_register'); + //Runs when a user is deleted. + $this->loader->add_action('delete_user', $plugin_admin, 'ssbhesabix_hook_delete_user'); + + //Runs when a product is added. +// $this->loader->add_action('woocommerce_new_product', $plugin_admin, 'ssbhesabix_hook_new_product'); +// $this->loader->add_action('woocommerce_new_product_variation', $plugin_admin, 'ssbhesabix_hook_new_product_variation', 10, 2); + //Runs when a product is updated. + $this->loader->add_action('woocommerce_update_product', $plugin_admin, 'ssbhesabix_hook_new_product'); +// $this->loader->add_action('woocommerce_update_product_variation', $plugin_admin, 'ssbhesabix_hook_new_product'); + //Runs when a product is deleted. + $this->loader->add_action('before_delete_post', $plugin_admin, 'ssbhesabix_hook_delete_product'); + //$this->loader->add_action('woocommerce_delete_product_variation', $plugin_admin, 'ssbhesabix_hook_delete_product_variation'); + + //Display hesabix item code in Product data section + $this->loader->add_action('woocommerce_product_options_general_product_data', $plugin_admin, 'ssbhesabix_hook_product_options_general_product_data'); + $this->loader->add_action('woocommerce_process_product_meta', $plugin_admin, 'ssbhesabix_hook_process_product_meta'); + //Display hesabix item code in Product variable attribute section + $this->loader->add_action('woocommerce_product_after_variable_attributes', $plugin_admin, 'ssbhesabix_hook_product_after_variable_attributes', 10, 3); + $this->loader->add_action('woocommerce_save_product_variation', $plugin_admin, 'ssbhesabix_hook_save_product_variation', 10, 3); + + $this->loader->add_filter('woocommerce_product_data_tabs', $plugin_admin, 'add_hesabix_product_data_tab'); + $this->loader->add_action('woocommerce_product_data_panels', $plugin_admin, 'add_hesabix_product_data_fields'); + + } elseif (!get_option('ssbhesabix_live_mode')) { + if (get_option('ssbhesabix_business_expired')) + $this->loader->add_action('admin_notices', $plugin_admin, 'ssbhesabix_business_expired_notice'); + else + $this->loader->add_action('admin_notices', $plugin_admin, 'ssbhesabix_live_mode_notice'); + } + + /* + * Action - Ajax 'Export Tabs' from hesabix/Export + * @since 1.0.0 + */ + $this->loader->add_filter('wp_ajax_adminExportProducts', $plugin_admin, 'adminExportProductsCallback'); + $this->loader->add_filter('wp_ajax_adminImportProducts', $plugin_admin, 'adminImportProductsCallback'); + $this->loader->add_filter('wp_ajax_adminExportProductsOpeningQuantity', $plugin_admin, 'adminExportProductsOpeningQuantityCallback'); + $this->loader->add_filter('wp_ajax_adminExportCustomers', $plugin_admin, 'adminExportCustomersCallback'); + + /* + * Action - Ajax 'Sync Tabs' from hesabix/Sync + * @since 1.0.0 + */ + $this->loader->add_filter('wp_ajax_adminSyncChanges', $plugin_admin, 'adminSyncChangesCallback'); + $this->loader->add_filter('wp_ajax_adminSyncProducts', $plugin_admin, 'adminSyncProductsCallback'); + $this->loader->add_filter('wp_ajax_adminSyncOrders', $plugin_admin, 'adminSyncOrdersCallback'); + $this->loader->add_filter('wp_ajax_adminUpdateProducts', $plugin_admin, 'adminUpdateProductsCallback'); + $this->loader->add_filter('wp_ajax_adminUpdateProductsWithFilter', $plugin_admin, 'adminUpdateProductsWithFilterCallback'); + $this->loader->add_filter('wp_ajax_adminSubmitInvoice', $plugin_admin, 'adminSubmitInvoiceCallback'); + + /* + * Action - Ajax 'Log Tab' from hesabix/Log + * @since 1.0.0 + */ + $this->loader->add_filter('wp_ajax_adminCleanLogFile', $plugin_admin, 'adminCleanLogFileCallback'); + + $this->loader->add_filter('wp_ajax_adminSyncProductsManually', $plugin_admin, 'adminSyncProductsManuallyCallback', 10, 4); + $this->loader->add_filter('wp_ajax_adminClearPluginData', $plugin_admin, 'adminClearPluginDataCallback', 10, 4); + $this->loader->add_filter('wp_ajax_adminInstallPluginData', $plugin_admin, 'adminInstallPluginDataCallback', 10, 4); + + $this->loader->add_filter('wp_ajax_adminChangeProductCode', $plugin_admin, 'adminChangeProductCodeCallback'); + $this->loader->add_filter('wp_ajax_adminDeleteProductLink', $plugin_admin, 'adminDeleteProductLinkCallback'); + $this->loader->add_filter('wp_ajax_adminUpdateProduct', $plugin_admin, 'adminUpdateProductCallback'); + $this->loader->add_filter('wp_ajax_adminChangeProductsCode', $plugin_admin, 'adminChangeProductsCodeCallback'); + $this->loader->add_filter('wp_ajax_adminDeleteProductsLink', $plugin_admin, 'adminDeleteProductsLinkCallback'); + $this->loader->add_filter('wp_ajax_adminUpdateProductAndVariations', $plugin_admin, 'adminUpdateProductAndVariationsCallback'); + + } else { + $this->loader->add_action('admin_notices', $plugin_admin, 'ssbhesabix_missing_notice'); + } + } +//===================================================================================== + /** + * Run the loader to execute all of the hooks with WordPress. + * + * @since 1.0.0 + */ + public function run() {$this->loader->run();} +//===================================================================================== + /** + * The name of the plugin used to uniquely identify it within the context of + * WordPress and to define internationalization functionality. + * + * @return string The name of the plugin. + * @since 1.0.0 + */ + public function get_plugin_name() {return $this->plugin_name;} +//===================================================================================== + /** + * The reference to the class that orchestrates the hooks with the plugin. + * + * @return Ssbhesabix_Loader Orchestrates the hooks of the plugin. + * @since 1.0.0 + */ + public function get_loader() {return $this->loader;} +//===================================================================================== + /** + * Retrieve the version number of the plugin. + * + * @return string The version number of the plugin. + * @since 1.0.0 + */ + public function get_version() {return $this->version;} +//===================================================================================== +} diff --git a/includes/ssbhesabix-webhook.php b/includes/ssbhesabfa-webhook.php similarity index 90% rename from includes/ssbhesabix-webhook.php rename to includes/ssbhesabfa-webhook.php index c405ed2..c31cd0e 100644 --- a/includes/ssbhesabix-webhook.php +++ b/includes/ssbhesabfa-webhook.php @@ -1,30 +1,31 @@ - - * @author HamidReza Gharahzadeh - * @author Sepehr Najafi - */ - -/* Check security token */ -if (!(defined('STDIN') || (strtolower(php_sapi_name()) == 'cli' && (!isset($_SERVER['REMOTE_ADDR']) - || empty($_SERVER['REMOTE_ADDR']))))) { - if (substr(wp_hash(AUTH_KEY . 'ssbhesabix/webhook'), 0, 10) != $_GET['token']) { - die('Bad token'); - } -} - -$post = file_get_contents('php://input'); -$result = json_decode($post); - -if (!is_object($result)) { - die('Invalid request.'); -} - -if ($result->Password != get_option('ssbhesabix_webhook_password')) { - die('Invalid password.'); -} - -include(dirname(__FILE__) . '/class-ssbhesabix-webhook.php'); -HesabixLogService::writeLogStr("Hesabix Webhook Called"); -new Ssbhesabix_Webhook(); + + * @author HamidReza Gharahzadeh + * @author Sepehr Najafi + * @author Babak Alizadeh + */ + +/* Check security token */ +if (!(defined('STDIN') || (strtolower(php_sapi_name()) == 'cli' && (!isset($_SERVER['REMOTE_ADDR']) + || empty($_SERVER['REMOTE_ADDR']))))) { + if (substr(wp_hash(AUTH_KEY . 'ssbhesabix/webhook'), 0, 10) != $_GET['token']) { + die('Bad token'); + } +} + +$post = file_get_contents('php://input'); +$result = json_decode($post); + +if (!is_object($result)) { + die('Invalid request.'); +} + +if ($result->Password != get_option('ssbhesabix_webhook_password')) { + die('Invalid password.'); +} + +include(dirname(__FILE__) . '/class-ssbhesabix-webhook.php'); +HesabixLogService::writeLogStr("Hesabix Webhook Called"); +new Ssbhesabix_Webhook(); diff --git a/languages/ssbhesabix-fa_IR.mo b/languages/ssbhesabix-fa_IR.mo index 13dd56ede0a9441e9da18bb37f8af1d9b284e683..087250a5cc6cf352a5ec4f103f9bc127b3b82b0a 100644 GIT binary patch delta 6802 zcmbW(c~n)`y}-&BJMaaKSPi6!FYav2o3aJh&>k{c78R(x4W zjv4xDthHG|QGUi&1(^ScpYk178AiJt_1?!HA@N?nNfyP<@?r9B8QqTKQsrr}i_ zj0r=PO2rJ6{!)y`b(W7}HtlC|1pXEWD&S22^COj7fcM}Wd>ti2LrF&-R-wG`LA(i{!Xfx$tKE;Xu;(xd-$7a674%4I262__ zs}YtdC@aZBnOF%XViU>)x8Y{oi!4T^&?)2Gfs&a5l<}6Jfva#LdN3c4Tm6?~$iM7K zc&t)0aVpAIY(z=fA++Idun?!j>47$40qrB0i&wA`M^SOqqgsbDp)Dvc-ieZt*Ki8{ z3U_080{NE*ddPwQq`cObQ8+NcB1U{53P1T%0NHEQ2ZL@ znEnsS)`T0norICJ$0FHRg(w;E+(}SI(10@2lPD>A9T($(WNjJBzKf<9F%b%Q^TyR$~}1kp0Wg$@I@fSx6Jggxfp>vR99x{CVEG;RTeHow9rzt7xCc5jY`VSMyw)O?v~%L|?JI zjJ32!PSD4*3+24;!baSO%g{53JarP(pj`L>3vtFB`nY-UPTH@c6JsaoV%&jz{M3`U z2v6V>7)rrJ;t$Y`{U{kpZAc0nWkqQBoT}O;`U6 zl+)nASaf4NK7=x%UYvoiBPUPYGF|`n9ES$&^~f%(?_-{v|2GNlrsG>|!Hvv9W_}49 z@GeG^{?oV$^JnUmK8muUKD-T2S$=@jt-6eH7*(jZcs$CBmm>#AZN;%3f<6K!tIpw4 zjG_{Yu?g93bqGJj4^dWhhKu3&8A=AevK%o>AKxsjpufuUF!H||K%uO}IVfBCBlOe} z3@_mq4z9y9_%^!maq_W;Yxf1M^jl8vib~>MeBPQ2Ni7l7E@`MLOg~S1=w^%5-XHpbS`r(%*(A?nF7qM!DYO zbTnue<8ZWNI(DKI# zd;xF6^EeAXN11Uxhd&wbL@BCGn20|_4vKmiWg%fTy2?l4?X)MNWN4+;-iigZ58`SM z!DWI4xL~#Z;5>%1@^5i1HrsUDht0I-*6JEKhEf|J<7XJbnS33;LF!nY=4|i9NQbV8 z6DV8o9?Djw)|0I-3Dyzxhw=Syu=bR<$eyR-$C!uXFsemoXf|?`l>@0y)rajE%B*F@ zowykP6DQ*(q-<2OQ~zsuJzl2W=Oq8*2)^H@tMm*O)BXg9URx zjhrBpyc(G)q(n^?s-sGT4N;@bpGO@v-$@y5wngufuA5`p16N`yg|jj9HB%yPNXXfk z$>tAYBjoDA*i^GHcF5>Xm%Y)};RwvC!`AHRFx*XUfjkCh^UK%^Bgk+`tD7X)uBG?I zxC9x=AGc6Qi+?+`-j;2iicdCU5{64xWw$+3Id;ZMfD|+9o^G5p0{8#)3h-_FDTs!;pdY8TrC@Mx^;C zBQTloj9TfjCr^y6w;8pv<|enJC9uQSp6*XBm74~nd=P$J9fgfP7%}S~Qt5qq^o|g@ zb69GOIXCrEL5q_OtZ3v%XRqGrGK$=8S5s}Ln`EwNbhH}FZ0lHwQRZ^ib=uuVh0_QY zYF1i-S(o;v449j~47^*?HwVVQHKSU3>obaTnRRdyE1XWdvxTa)JB*U`c1JURw>e#I zwXBhP3Xa;Falbs9JvJ(VoG$CEZJ~UFZ@+GNtH(A(EV6aDjaiMh)&_?$f3|sQ>~wkb zyRjAFyp{@~zr);<8E>x7d_t}a&zd2WXRR0B%9<+NGOkFs;>@~naT4A)?#DuE_G|ir zbz7oYoD(SU^*N8rg<-i4p(}T$a56V>G;g)J4L1pGZfadiCAv77U0vB$NoKQr^DnvI zRgy$|;4I3m|Ly>185^9PMytb7CuhwODC1fu$Go^R4MiZ<2f&=0naH zb9%uhos8u2k>=TgINkWNpfeD7n`b-_Vh*ZEieQoQRx1nUg_-r%V+*3pRfV4q3XJGG z$kKbwqT(s0Su{r9aH^<17!;cui&KJ)DDz}-g-1U|zF6Z?!@u?10smGNSn&xaf0$MF z8e>@HR<5&f!@o^dm0|dv_4RW@A4@eDLmoe7$dav0SiAJEhwlsIu$yPR*|UyV)w8N3 z*8FyMnx39Cic6w`jopFZ=$sy zdZKLM=lX_{MGJNC_@bU*P-;H9c!h3!zId7ra+j>p!QLfS&&4IFfqheE`HVEw=aKYKwx@P&GReby=7IWLOj=P+ZJl|1u05v2aWSP z&mAzR=EG7_{%&jUZgL<{Qs^8U%Y`*JT>-v4G3d~_O>4UFdta-7<%+f^^ zIAByARdYz@(ZhlFGI3_VUA_fOhFO~5TOF(4uyOSlI%u;cS?{zNI(WhMQs%!{+Wgsu zZ=Wt~DqSZ`5@BwxiZ*xFZW$P?<{s1L7-dd(M4Ltn=Fdt`Mm%1d!@F;9=PB8R!e6{KId8v_-5$lV9WQE0+A0Y-(k{n{KlGN zhfg-8d9M3L_sZvy7s>Ab!vN>_u*lbZJ7dblz^CK-uluzpZ~V;bZ_0jIMqm-XUgpC% z^6h7STm9y}(+8PL+oR0o&U^Lh%iCkj|7wrdjf*vjW=@-R>MqudGP~Oz3f>lN=CpsT g8!@gL9o*x3LkEjGrVqQ}_g#*8$erNr>o^_qzsnp|;Q#;t delta 7518 zcmajh33OCdn!xcJc7kjnAqiP{$QB@#jlDu30TKu#B!RGLAgNS}q<~Z{yZ60% zcdu~rTEq|EMg+f%>aas`T_qBUQJs|<8KG2B52;luu8&gfF&?{N67q-|hC?tD@4*E) z7+q%lW=x=b-1ID_QT`UAFg{wTu1W<}Dv6znF_?jkI2~WaRJ@LH7#E{dU(CeeI2}i# zAEiV4uooV|PWV2iNAZzBz=uDm1@`(P~Xt9%j}`63*Kt5F)*i$n1o%8PHKjJQjz z@uGB;k&H)apvZJF`Y1QxK)i~KL3L&nQcgq}P%a-Ow67MD6ykoIf!|{RPK-BZ;t`Yv z&SFQrjNS2?S^fcOL;Zxw7}d`hP$tSu%)*{H*VKj5@g@vPk2aAc;X$NrbsE>>Rb;u8 zi-nXItwNcJ2T@+Q4K;iLN8?G9CHc{;Pi0zV35szNu0@&pcTi^dW+LW3Xa?vH5glQq%$LfTvJq;xvxKOUO1+eeN|nHXLODRoDf$ zp>$*?GD+&iAc;)ryU0Ivjt}YKcPMM#k@b;sEXqiSV|%PZIgT|bOVnVNAI2EUTTy1@ zB`n1gC>`xM$e5uRET$YRF_T}Ryzn~82yY{^s-ig5ESJhe>G>?=pPI*qjA#wYiyuMR zJ3GwsVPrDYyC_R=8Kq-4F%mltY5jgs^&*iG#2XdLhSGsCW_=mT7hRZw51{_yp3 z$53YID%$ZsQ96{#I?4>@p*%kaX5S zvZ-d28QO)?z)_SD{TgM-PNIfqaRlB(S-J!YvMKGDi+)VQ6PSlrF(}7uFu$|%1t-d` z+<*_^Zd{4?+Kh9&6Dug6M(OBK-j+t#}0YwxdyQcBK3V)~OR-M;YjMcn?Nq zG5_o{6`N)J^iIIhl$W4P=`NHdIf&B1&yiVE-y;V^CGl$`BgsWs>kTM-XFD

Iinm zOV|ysU?04J8nzq7{L705j#8>W7MLzU*(@7z03Jjc!C90JUqD%!pYRDrnoO_d{^7Ca z(wLsa1=OFzC`@5J7`)2HsaPK*k)9qm{XN!D?!wQQjJO`V`G z32hVE@mP-qcpGIVCvtNLID9sUg6SUB0J4`CwZfm4hDmR;rLEA>ZQfwEVsn1)E)h%(}Brmr9;O`XDdc*}J9G-jLj z)pI2G;ZG;2+?49^xX8Bu^Z6vZ8*32^2>`Ba}`~nWgD|iOGm#~xZ63Q_>P|C)|%P0fT%Zw?$ zfoYTzW*fhNGccC&9F!SYh6C~BZ0294_8Jw7F`KR36L;c0cmPM@YbcxNI?5*N%$KA* z9OcCYW_dB{lviUX>@n9^>loB1XP|8EG8~G|xy*kzlFd|X#iz{&Q|M+jwtTF|0EUo3sT9_aRaEQoS^V6zq0-nB_f#26H6A0mUxu_3 zR23u{R6K_op2t3T3ptUhqr+IMLX-|QqV#+RCgEGiiBcD_A8M>y3})jXEHhn!Ih3D8 z{;7+6%#iax!D;-EJc=^XTeu9XYWQyzoNVCj3;7GHCZUG)$dOiCko~DHp&v8o zos4iVmf*)Y4&xh*V>TPdP~MOKftOLyA|@yVZlT`PO1KZpYDh z9_`qPh0nq~lm-K)hft>e8p`+Xn2u}Wzuc7D6Tc+ba_SJltOnJCBYskufjdV`$Rn>y0ICNFjgTvqxGV`*fN&6xNrCHvLF;js^j~HC z@0pb{6IH}#X1N79Nv#(rOI;$a7{&1CP_i9FH)0{-CuS2(1ix466GAqqT(TjbYRx$N z_;188ng2;72hAI^Ogoxx#@`diiJioLXMAy+BUKrA3$BHktB3K8vyp2S)riI_{& z5WgT!6Rnqw`dMNW@hFi(JW2E-tm{iFK^u{1mgVn2J~7QK_r(FkN5nr6@|z&nMuXPB zGtJ~H&2kh5e`gj3;m5=iX4ztynY@6@iF3ppB9}NqyiSZEwh?zR9o8E_+ zM6#@ZB}pW)f_RNMMfixZ#6F@Qv6Prd$kl;x5_^ew2E# zEuzS*co+-i*J2Gx53}+Ej5TwM94o=ciDI){r}kXx5fS5VR+Ak*r?-ZA5JJ*Kynei_ryPMPWb#Vjq3vsP&d=ux9JD>E6)xGf_a#!hJYyI^F{rpDt zOF~n^Ss_1hkgzPV)W&n>OlWydr?<%yaC>UQRV57px0gRM)?|H?IHMcwhRZogn!Kno zX{4|{X^8N4QnjEZkB)aYYt;@vV-2|KHJSPFH$BNE^3Z$97xb_CBt#W@R(SvCr0Bc* zzY?m})!ehg|(Q+2&N zpq2iwsn(YdjgzM~4z1NAQpQL+KBaZ7pGbLAN;8K|6gCfQ7CH{M3wguygolTZ65brX zN2nZeQV2hiq_0VBy?;FQDY-Gj<`RzCCgm^Q<)@3Vq zIqL5!+qET*%EH-^#f8QBZJo?a%ZQxfZHO1(%T{HR|ZhEF`)k?3g#$V+22kcs9Wp<@2yV7INOwG!!Y!;l*81m#{`pnkdeSZiuL)|!UjTj}w78;nLh%|>CQ(NJZj zr`8pa$qzr%HbZk<{H)fMGIO>J=I-xqL~|#<*}1%_##JLv3{P9?j|{z$wLhZM7mr`s z-xAW7j2dR8`lu2swT~XEcOSjfDn2lJt(D#x{ezVn4|Ub=lt$`lV;|FxkBioij+<@W z{-7d3A25EERjewG){l?xXBE$nZ|ZDxLFtX|=+I)jCqnNwVUBhG!GgYe^MspLaam5C zl@?8$tjAAGZ!6YV>4}L}k3;Jxoe2-IEN_zaL|I(rq2ROrEiVOFjmnilTu^V4Tq-?%w_Ut3zD|FLksRh&8_+e#mr zVRc-;)mED^bFlS*RvhlLf96)JwsTRYl};#{Wu;q+a;@}6LA-vwDAp==D$cM{d-3~L z`g3u3(&x?^*3(>+mcuRkE^fT|sNPr-r|+4S(aosWT3)8^>-!T!Kh7$M&~KD<)j!RS zPgEDzx9np-9k{ru<(SrTs3p|0ujOUqE1~(NWf7s@ls(hVTyVSItvn&LuKa@t{k3`Z zq4fFA@EpFqAW=WQV6)Y=yoH~cX(;x-zlNV$cYlq(rlO1W)TRpEN^2JV*-95IPPWq3 zi#03Vz4&eYXn9|KQFRafK;_D|QMK%2RMGn1#&^>Tt9F}@hptzRjQBsEiRB&P1>9Br zvem+{nhd?!nPn9ZJ6Briu$u7NA9g0|FV_6Ux^tr-L4VctlU4k?SIpBJYOAfgzpXuC zrCaKbSZSVnyOmyaSM!1r}=p3-K9Fqq>&9kYZzdqNq#k#9`WA&dsSFPe7yp>iuz2RdkjcJ^4_aDcq#w!v3 E4W>VN*Z=?k diff --git a/languages/ssbhesabix-fa_IR.po b/languages/ssbhesabix-fa_IR.po index 76b762b..46ee61d 100644 --- a/languages/ssbhesabix-fa_IR.po +++ b/languages/ssbhesabix-fa_IR.po @@ -1,968 +1,1005 @@ -msgid "" -msgstr "" -"Project-Id-Version: Hesabix Accounting\n" -"POT-Creation-Date: 2021-01-08 14:20+0330\n" -"PO-Revision-Date: 2021-01-08 14:20+0330\n" -"Last-Translator: \n" -"Language-Team: \n" -"Language: fa_IR\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.4.2\n" -"X-Poedit-Basepath: ..\n" -"X-Poedit-WPHeader: ssbhesabix.php\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Poedit-SourceCharset: UTF-8\n" -"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;" -"esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;" -"_nx_noop:3c,1,2;__ngettext_noop:1,2\n" -"X-Poedit-SearchPath-0: .\n" -"X-Poedit-SearchPathExcluded-0: *.js\n" - -#: admin/class-ssbhesabix-admin.php:137 -#, php-format -msgid "Hesabix Plugin requires the %s to work!" -msgstr "افزونه حسابیکس نیازمند %s است!" - -#: admin/class-ssbhesabix-admin.php:137 -msgid "WooCommerce" -msgstr "ووکامرس" - -#: admin/class-ssbhesabix-admin.php:146 -msgid "" -"Hesabix Plugin need to connect to Hesabix Accounting, Please check the API " -"credential!" -msgstr "" -"افزونه حسابیکس نیازمند\t اتصال به نرم‌افزار حسابداری حسابیکس است، لطفا اطلاعات " -"دسترسی به API حسابیکس را بررسی کنید!" - -#: admin/class-ssbhesabix-admin.php:155 -msgid "" -"Hesabix Plugin cannot works! because WooCommerce currency in not match with " -"Hesabix." -msgstr "" -"افزونه حسابیکس نمی‌تواند به درستی عمل کند! واحد پول پیش‌فرض ووکامرس با واحد پول " -"پیش‌فرض حسابیکس همخوانی ندارد." - -#: admin/class-ssbhesabix-admin.php:410 admin/class-ssbhesabix-admin.php:502 -msgid "The new Item code already used for another Item" -msgstr "این کد قبلا برای کالایی دیگر استفاده شده است." - -#: admin/class-ssbhesabix-admin.php:483 -msgid "Hesabix base item code" -msgstr "کد کالای پایه در حسابیکس" - -#: admin/class-ssbhesabix-admin.php:485 -msgid "" -"The base Item code of this product in Hesabix, if you want to map this product " -"to another item in Hesabix, enter the new Item code." -msgstr "" -"این فیلد کد کالای پایه در حسابیکس است، اگر می‌خواهید این کالا را به کالای دیگری " -"در حسابیکس ارتباط دهید، کد کالای جدید را وارد نمایید." - -#: admin/class-ssbhesabix-admin.php:521 -msgid "Hesabix variable item code" -msgstr "کد کالای متغیر در حسابیکس" - -#: admin/class-ssbhesabix-admin.php:523 -msgid "" -"The variable Item code of this product variable in Hesabix, if you want to map " -"this product to another item in Hesabix, enter the new Item code." -msgstr "" -"این فیلد کد کالای متغییر در حسابیکس است، اگر می‌خواهید این کالا را به کالای " -"دیگری در حسابیکس ارتباط دهید، کد کالای جدید را وارد نمایید." - -#: admin/partials/ssbhesabix-admin-display.php:305 -msgid "Extra Settings" -msgstr "تنظیمات پیشرفته" - -#: admin/partials/ssbhesabix-admin-display.php:28 -msgid "Hesabix Options" -msgstr "تنظیمات افزونه حسابیکس" - -#: admin/partials/ssbhesabix-admin-display.php:28 -msgid "Hesabix" -msgstr "حسابیکس" - -#: admin/partials/ssbhesabix-admin-display.php:38 -msgid "Home" -msgstr "خانه" - -#: admin/partials/ssbhesabix-admin-display.php:39 -msgid "API" -msgstr "‏API" - -#: admin/partials/ssbhesabix-admin-display.php:40 -msgid "Catalog" -msgstr "محصولات" - -#: admin/partials/ssbhesabix-admin-display.php:41 -msgid "Customers" -msgstr "مشتریان" - -#: admin/partials/ssbhesabix-admin-display.php:42 -msgid "Invoice" -msgstr "فاکتور" - -#: admin/partials/ssbhesabix-admin-display.php:43 -msgid "Payment Methods" -msgstr "روش‌های پرداخت" - -#: admin/partials/ssbhesabix-admin-display.php:44 -msgid "Export" -msgstr "خروجی" - -msgid "Import and export data" -msgstr "ورود و خروج اطلاعات" - -#: admin/partials/ssbhesabix-admin-display.php:45 -msgid "Sync" -msgstr "همسان‌سازی" - -#: admin/partials/ssbhesabix-admin-display.php:65 -msgid "" -"Hesabix Plugin requires the WooCommerce to work!, Please install/activate " -"woocommerce and try again" -msgstr "" -"افزونه حسابیکس جهت راه‌اندازی نیاز به ووکامرس دارد! لطفا ووکامرس را نصب/فعال " -"کنید و مجدد سعی کنید." - -#: admin/partials/ssbhesabix-admin-functions.php:269 -#: admin/partials/ssbhesabix-admin-functions.php:964 -msgid "Not Defined" -msgstr "وارد نشده" - -#: admin/partials/ssbhesabix-admin-functions.php:290 -#: admin/partials/ssbhesabix-admin-functions.php:311 -#: admin/partials/ssbhesabix-admin-functions.php:332 -#: admin/partials/ssbhesabix-admin-functions.php:981 -msgid "Customer ID in OnlineStore: " -msgstr "شناسه مشتری در فروشگاه آن‌لاین:" - -#: admin/partials/ssbhesabix-admin-functions.php:383 -msgid "Guest Customer" -msgstr "مشتری مهمان" - -#: admin/partials/ssbhesabix-admin-functions.php:402 -msgid "Customer registered as a GuestCustomer." -msgstr "مشتری به عنوان مهمان ثبت‌نام کرده است." - -#. Plugin Name of the plugin/theme -#: admin/partials/ssbhesabix-admin-setting.php:44 -msgid "Hesabix Accounting" -msgstr "نرم‌افزار حسابداری آنلاین حسابیکس" - -#: admin/partials/ssbhesabix-admin-setting.php:186 -msgid "Enable or Disable Advanced Log" -msgstr "تب لاگ پیشرفته" - -#: admin/partials/ssbhesabix-admin-setting.php:1455 -msgid "Start ID" -msgstr "از شناسه (کد کالای ووکامرس)" -#: admin/partials/ssbhesabix-admin-setting.php:1456 -msgid "End ID" -msgstr "تا شناسه (کد کالای ووکامرس)" -#: admin/partials/ssbhesabix-admin-setting.php:1456 -msgid "Update Products in Hesabix based on store with filter" -msgstr "بروزرسانی محصولات در حسابیکس بر اساس فروشگاه در بازه ID مشخص شده" - -#: admin/partials/ssbhesabix-admin-setting.php:189 -msgid "Performance Optimization Settings" -msgstr "تنظیمات بهینه سازی عملکرد" - -#: admin/partials/ssbhesabix-admin-setting.php:189 -msgid "Disable The Advanced Log" -msgstr "غیرفعال کردن تب لاگ پیشرفته" - -#: admin/partials/ssbhesabix-admin-setting.php:190 -msgid "Enable The Advanced Log" -msgstr "فعال کردن تب لاگ پیشرفته" - -#: admin/partials/ssbhesabix-admin-setting.php:45 -msgid "" -"This module helps connect your (online) store to Hesabix online accounting " -"software. By using this module, saving products, contacts, and orders in your " -"store will also save them automatically in your Hesabix account. Besides that, " -"just after a client pays a bill, the receipt document will be stored in " -"Hesabix as well. Of course, you have to register your account in Hesabix " -"first. To do so, visit Hesabix at the link here hesabix.ir and sign up " -"for free. After you signed up and entered your account, choose your business, " -"then in the settings menu/API, you can find the API keys for the business and " -"import them to the plugin’s settings. Now your module is ready to use." -msgstr "" -"این ماژول فروشگاه شما را به نرم افزار حسابداری آنلاین حسابیکس متصل می کند. به " -"وسیله ی این ماژول کالاها، مشتریان و سفارشات شما به محض ثبت در سیستم فروشگاه، " -"در حسابیکس نیز بصورت خودکار ثبت و ذخیره می شوند. همچنین با پرداخت مشتری، سند " -"دریافت وجه از مشتری نیز در حسابیکس ثبت می شود. بدیهی است برای استفاده از این " -"افزونه باید ابتدا یک حساب کاربری در حسابیکس داشته باشید. برای این کار می توانید " -"به وب سایت حسابیکس به آدرس hesabix.ir سر بزنید و به رایگان ثبت نام کنید. " -"پس از ثبت نام در حسابیکس و ورود به حساب خود، و سپس ورود به یک کسب و کار، در " -"قسمت تنظیمات / API می توانید کلید API مربوط به کسب و کار خود را دریافت و در " -"قسمت تنظیمات این ماژول وارد نمایید. پس از آن ماژول شما آماده استفاده است." - -#: admin/partials/ssbhesabix-admin-setting.php:46 -msgid "" -"For more information and a full guide to how to use Hesabix and WooCommerce " -"Plugin, visit Hesabix’s website and go to the “Guides and Tutorials” menu." -msgstr "" -"برای کسب اطلاعات بیشتر و راهنمای استفاده از حسابیکس و افزونه ووکامرس به وب سایت " -"حسابیکس، قسمت راهنما ها و خودآموز ها مراجعه کنید." - -#: admin/partials/ssbhesabix-admin-setting.php:53 -msgid "Catalog Settings" -msgstr "تنظیمات محصولات" - -#: admin/partials/ssbhesabix-admin-setting.php:56 -msgid "Update Price" -msgstr "به‌روزرسانی قیمت" - -#: admin/partials/ssbhesabix-admin-setting.php:57 -msgid "Update Price after change in Hesabix" -msgstr "به‌روزرسانی قیمت بعد از تغییر در حسابیکس" - -#: admin/partials/ssbhesabix-admin-setting.php:64 -msgid "Update Quantity" -msgstr "به‌روزرسانی موجودی" - -#: admin/partials/ssbhesabix-admin-setting.php:65 -msgid "Update Quantity after change in Hesabix" -msgstr "به‌روزرسانی موجودی بعد از تغییر در حسابیکس" - -#: admin/partials/ssbhesabix-admin-setting.php:240 -msgid "Show Hesabix ID in Products Page" -msgstr "نمایش کد حسابیکس در صفحه همه محصولات" - -#: admin/partials/ssbhesabix-admin-setting.php:679 -msgid "Default Payment Gateway By Using this Option, all Invoices Will Have this Payment Gateway as Their Payment Gateway" -msgstr "درگاه پرداخت پیش فرض" - -#: admin/partials/ssbhesabix-admin-setting.php:695 -msgid "Default Bank Code" -msgstr "کد بانک پیش فرض" - -#: admin/partials/ssbhesabix-admin-setting.php:689 -msgid "Default Bank Name" -msgstr "نام بانک پیش فرض" - -#: admin/partials/ssbhesabix-admin-setting.php:683 -msgid "Save Default Bank as the Payment Gateway" -msgstr "بانک پیش فرض به عنوان درگاه پرداخت ذخیره شود" - -#: admin/partials/ssbhesabix-admin-setting.php:684 -msgid "Save Other Payment Methods as the Payment Gateway" -msgstr "روش های دیگر پرداخت به عنوان درگاه پرداخت ذخیره شود" - -#: admin/partials/ssbhesabix-admin-setting.php:246 -msgid "Set Special Sale as Discount in invoice" -msgstr "ثبت فروش ویژه به عنوان تخفیف در فاکتور" - -#: admin/partials/ssbhesabix-admin-setting.php:693 -msgid "Enter Bank Code" -msgstr "کد بانک را وارد نمایید" - -#: admin/partials/ssbhesabix-admin-setting.php:700 -msgid "Enter Bank Name" -msgstr "نام بانک را وارد نمایید" - -#: admin/partials/ssbhesabix-admin-setting.php:700 -msgid "Enter Freight Code" -msgstr "کد هزینه حمل و نقل را وارد نمایید" - -#: admin/partials/ssbhesabix-admin-setting.php:1642 -msgid "Delete Logs Between These Tow Dates" -msgstr "حذف لاگ ها در بازه مشخص شده" - -#: admin/partials/ssbhesabix-admin-setting.php:1633 -msgid "Log History" -msgstr "تاریخچه لاگ ها" -#: admin/partials/ssbhesabix-admin-setting.php:1648 -#: admin/partials/ssbhesabix-admin-setting.php:1680 -msgid "Delete All Log Files" -msgstr "پاک کردن کل لاگ ها" -#: admin/partials/ssbhesabix-admin-setting.php:1613 -msgid "Find Log File" -msgstr "جستجوی فایل لاگ براساس تاریخ" - -#: admin/partials/ssbhesabix-admin-setting.php:84 -#: admin/partials/ssbhesabix-admin-setting.php:130 -#: admin/partials/ssbhesabix-admin-setting.php:191 -#: admin/partials/ssbhesabix-admin-setting.php:250 -#: admin/partials/ssbhesabix-admin-setting.php:301 -msgid "Save changes" -msgstr "ذخیره تغییرات" - -#: admin/partials/ssbhesabix-admin-setting.php:99 -msgid "Customers Settings" -msgstr "تنظیمات مشتری" - -#: admin/partials/ssbhesabix-admin-setting.php:102 -msgid "Update Customer Address" -msgstr "به روزرسانی آدرس مشتریان" - -#: admin/partials/ssbhesabix-admin-setting.php:103 -msgid "Choose when update Customer address in Hesabix." -msgstr "انتخاب کنید که در چه حالتی آدرس مشتری در حسابیکس به‌روزرسانی شود" - -#: admin/partials/ssbhesabix-admin-setting.php:106 -msgid "Use first customer address" -msgstr "اولین آدرس مشتری" - -#: admin/partials/ssbhesabix-admin-setting.php:106 -msgid "update address with Invoice address" -msgstr "به روزرسانی با آدرس فاکتور سفارش" - -#: admin/partials/ssbhesabix-admin-setting.php:106 -msgid "update address with Delivery address" -msgstr "به‌روزرسانی با آدرس ارسال سفارش" - -#: admin/partials/ssbhesabix-admin-setting.php:110 -msgid "Customer's Group" -msgstr "دسته‌بندی مشتریان" - -#: admin/partials/ssbhesabix-admin-setting.php:111 -msgid "Enter a Customer's Group in Hesabix" -msgstr "نام دسته‌بندی مشتریان در حسابیکس را وارد کنید" - - - -#: admin/partials/ssbhesabix-admin-setting.php:110 -msgid "Save Customer's group" -msgstr "ذخیره دسته بندی مشتریان" - - -#: admin/partials/ssbhesabix-admin-setting.php:110 -msgid "Automatically save Customer's group in hesabix" -msgstr "به صورت خودکار دسته بندی مشتریان را در حسابیکس ذخیره کن" - - -#: admin/partials/ssbhesabix-admin-setting.php:111 -msgid "Customer's detail auto save and update" -msgstr "ذخیره خودکار مشتریان" - - -#: admin/partials/ssbhesabix-admin-setting.php:111 -msgid "Save and update Customer's detail automatically in hesabix" -msgstr "ثبت و ذخیره خودکار اطلاعات مشتریان در حسابیکس" - -msgid "Add additional fields to checkout page" -msgstr "افزودن فیلد های دلخواه به صفحه پرداخت" - - -msgid "Customer add field to checkout by hesabix" -msgstr "افزودن فیلد ها توسط افزونه حسابیکس" - - -msgid "Customer add field to checkout by postmeta" -msgstr "استفاده از فیلد های موجود در جدول متا (که توسط افزونه های دیگر اضافه شده است)" - - -msgid "Show" -msgstr "نمایش" - -msgid "Title" -msgstr "عنوان" - -msgid "Meta code in Postmeta" -msgstr "کد متا در جدول پست متا" - -msgid "National code" -msgstr "کد ملی" - -msgid "Economic code" -msgstr "کد اقتصادی" - -msgid "Registration number" -msgstr "شماره ثبت" - -msgid "Website" -msgstr "وب سایت" - -msgid "Required" -msgstr "اجباری" - -msgid "please enter your National code" -msgstr "لطفا کد ملی خود را وارد کتید" - -msgid "please enter a valid national code" -msgstr "لطفا کد ملی معتبر وارد نمایید" - -msgid "please enter your Economic code" -msgstr "لطفا کد اقتصادی خود را وارد کتید" - -msgid "please enter your Registration number" -msgstr "لطفا شماره ثبت خود را وارد کتید" - -msgid "please enter your Website address" -msgstr "لطفا آدرس سایت خود را وارد کنید" - -msgid "please enter a valid Website URL" -msgstr "لطفا آدرس سایت معتبر وارد نمایید" - -#: admin/partials/ssbhesabix-admin-setting.php:144 -msgid "Invoice Settings" -msgstr "تنظیمات فاکتور" - -#: admin/partials/ssbhesabix-admin-setting.php:147 -msgid "Add invoice in which status" -msgstr "افزودن فاکتور در وضعیت:" - -#: admin/partials/ssbhesabix-admin-setting.php:380 -msgid "Save invoice in draft mode in Hesabix" -msgstr "ثبت فاکتور بصورت پیش نویس در حسابیکس" - -#: admin/partials/ssbhesabix-admin-setting.php:557 -msgid "Save Freight" -msgstr "ذخیره هزینه حمل و نقل" - -#: admin/partials/ssbhesabix-admin-setting.php:561 -msgid "Save as Freight" -msgstr "ذخیره به عنوان هزینه" - -#: admin/partials/ssbhesabix-admin-setting.php:562 -msgid "Save as a Service" -msgstr "ذخیره به عنوان یک خدمت" - -#: admin/partials/ssbhesabix-admin-setting.php:562 -msgid "Service Code For Freight" -msgstr "کد خدمت حمل و نقل ذخیره شده در حسابیکس" - -#: admin/partials/ssbhesabix-admin-setting.php:151 -#: admin/partials/ssbhesabix-admin-setting.php:167 -#: admin/partials/ssbhesabix-admin-setting.php:217 -msgid "Pending payment" -msgstr "در انتظار پرداخت" - -#: admin/partials/ssbhesabix-admin-setting.php:152 -#: admin/partials/ssbhesabix-admin-setting.php:168 -#: admin/partials/ssbhesabix-admin-setting.php:218 -msgid "Processing" -msgstr "در حال انجام" - -#: admin/partials/ssbhesabix-admin-setting.php:153 -#: admin/partials/ssbhesabix-admin-setting.php:169 -#: admin/partials/ssbhesabix-admin-setting.php:219 -msgid "On hold" -msgstr "در انتظار بررسی" - -#: admin/partials/ssbhesabix-admin-setting.php:154 -#: admin/partials/ssbhesabix-admin-setting.php:170 -#: admin/partials/ssbhesabix-admin-setting.php:220 -msgid "Completed" -msgstr "تکمیل شده" - -#: admin/partials/ssbhesabix-admin-setting.php:155 -#: admin/partials/ssbhesabix-admin-setting.php:171 -#: admin/partials/ssbhesabix-admin-setting.php:221 -msgid "Cancelled" -msgstr "لغو شده" - -#: admin/partials/ssbhesabix-admin-setting.php:156 -#: admin/partials/ssbhesabix-admin-setting.php:172 -#: admin/partials/ssbhesabix-admin-setting.php:222 -msgid "Refunded" -msgstr "مسترد شده" - -#: admin/partials/ssbhesabix-admin-setting.php:157 -#: admin/partials/ssbhesabix-admin-setting.php:173 -#: admin/partials/ssbhesabix-admin-setting.php:223 -msgid "Failed" -msgstr "ناموفق" - -#: admin/partials/ssbhesabix-admin-setting.php:158 -#: admin/partials/ssbhesabix-admin-setting.php:174 -#: admin/partials/ssbhesabix-admin-setting.php:224 -msgid "Draft" -msgstr "پیش‌نویس" - -#: admin/partials/ssbhesabix-admin-setting.php:163 -msgid "Return sale invoice status" -msgstr "ثبت فاکتور برگشت از فروش در وضعیت" - -#: admin/partials/ssbhesabix-admin-setting.php:210 -msgid "Payment methods Settings" -msgstr "تنظیمات روش پرداخت" - -#: admin/partials/ssbhesabix-admin-setting.php:213 -msgid "Add payment in which status" -msgstr "افزودن پرداخت در وضعیت:" - -#: admin/partials/ssbhesabix-admin-setting.php:265 -msgid "API Settings" -msgstr "تنظیمات API" - -#: admin/partials/ssbhesabix-admin-setting.php:268 -msgid "Email" -msgstr "آدرس ایمیل" - -#: admin/partials/ssbhesabix-admin-setting.php:269 -msgid "Enter a Hesabix email account" -msgstr "آدرس ایمیل اکانت حسابیکس را وارد کنید" - -#: admin/partials/ssbhesabix-admin-setting.php:275 -msgid "Password" -msgstr "رمزعبور" - -#: admin/partials/ssbhesabix-admin-setting.php:276 -msgid "Enter a Hesabix password" -msgstr "رمزعبور حسابیکس را وارد کنید" - -#: admin/partials/ssbhesabix-admin-setting.php:282 -msgid "API Key" -msgstr "کلید API" - -msgid "Login token" -msgstr "توکن ورود" - -#: admin/partials/ssbhesabix-admin-setting.php:283 -msgid "Find API key in Setting->Financial Settings->API Menu" -msgstr "کلید API را در حسابیکس از منوی تنظیمات->تنظیمات مالی->API پیدا کنید" - -msgid "Find Login token in Setting->Financial Settings->API Menu" -msgstr "توکن ورود را در حسابیکس از منوی تنظیمات->تنظیمات مالی->API پیدا کنید" - -#: admin/partials/ssbhesabix-admin-setting.php:323 -msgid "" -"No products were exported, All products were exported or there are no product" -msgstr "" -"هیچ محصولی استخراج نشد، تمامی محصولات قبلا استخراج شده‌اند یا محصولی وجود ندارد." - -msgid "" -"No products were imported, All products were imported or there are no product" -msgstr "" -"هیچ محصولی وارد نشد، تمامی محصولات قبلا وارد شده‌اند یا محصولی وجود ندارد." - - -#: admin/partials/ssbhesabix-admin-setting.php:327 -#, php-format -msgid "Export products completed. %s products added/updated." -msgstr "استخراج محصولات به اتمام رسید. ‪‬%s محصول استخراج شد." - -msgid "Import products completed. %s products added/updated." -msgstr "ورود محصولات به اتمام رسید. ‪‬%s محصول وارد شد." - -#: admin/partials/ssbhesabix-admin-setting.php:335 -msgid "Export products fail. Hesabix has already contained products." -msgstr "خروجی محصولات با خطا مواجه شد. حسابیکس از قبل حاوی محصولاتی است." - -#: admin/partials/ssbhesabix-admin-setting.php:339 -msgid "Export products fail. Please check the log file." -msgstr "خروجی محصولات با خطا مواجه شد. لطفا لاگ را بررسی کنید." - -msgid "Import products fail. Please check the log file." -msgstr "ورود محصولات با خطا مواجه شد. لطفا لاگ را بررسی کنید." - -#: admin/partials/ssbhesabix-admin-setting.php:340 -msgid "Export product opening quantity completed." -msgstr "استخراج موجودی اول دوره با موفقیت به پایان رسید." - -#: admin/partials/ssbhesabix-admin-setting.php:347 -msgid "" -"Export product opening quantity fail. No Shareholder exists, Please define " -"Shareholder in Hesabix" -msgstr "" -"استخراج موجودی اول دوره با خطا مواجه شد. سهامدار تعریف نشده است، لطفا ابتدا " -"سهامداران را در حسابیکس تعریف کنید." - -#: admin/partials/ssbhesabix-admin-setting.php:351 -msgid "No product available for Export product opening quantity." -msgstr "محصولی جهت استخراج موجودی اول دوره در دسترس نمی‌باشد." - -#: admin/partials/ssbhesabix-admin-setting.php:355 -msgid "Export product opening quantity fail. Please check the log file." -msgstr "استخراج موجودی اول دوره با خطا مواجه شد. لطفا لاگ را بررسی کنید." - -#: admin/partials/ssbhesabix-admin-setting.php:366 -msgid "" -"No customers were exported, All customers were exported or there are no " -"customer" -msgstr "" -"هیچ مشتری استخراج نشد، تمامی مشتریان قبلا استخراج شده‌اند یا مشتری وجود ندارد." - -#: admin/partials/ssbhesabix-admin-setting.php:370 -#, php-format -msgid "Export customers completed. %s customers added." -msgstr "استخراج مشتریان به اتمام رسید. %s مشتری استخراج شد." - -#: admin/partials/ssbhesabix-admin-setting.php:375 -msgid "Export customers fail. Please check the log file." -msgstr "استخراج مشتریان با خطا مواجه شد. لطفا لاگ را بررسی کنید." - -#: admin/partials/ssbhesabix-admin-setting.php:381 -msgid "Export can take several minutes." -msgstr "استخراج ممکن است چند دقیقه زمان ببرد." - -msgid "Export customers fail. Hesabix has already contained customers." -msgstr "خروجی مشتریان با خطا مواجه شد. حسابیکس از قبل حاوی مشتریان است." - -#: admin/partials/ssbhesabix-admin-setting.php:392 -msgid "Export Products" -msgstr "خروجی محصولات" - -msgid "Import Products" -msgstr "ورود محصولات" - -#: admin/partials/ssbhesabix-admin-setting.php:395 -msgid "Export and add all online store products to Hesabix" -msgstr "افزودن تمامی محصولات فروشگاه آنلاین در حسابیکس" - -msgid "Import and add all products from Hesabix to online store" -msgstr "افزودن تمامی محصولات حسابیکس به فروشگاه آنلاین" - -#: admin/partials/ssbhesabix-admin-setting.php:407 -msgid "Export Products opening quantity" -msgstr "استخراج موجودی اول دوره" - -#: admin/partials/ssbhesabix-admin-setting.php:410 -msgid "" -"Export the products quantity and record the 'products opening quantity' in the " -"Hesabix" -msgstr "استخراج موجودی محصولات و ثبت موجودی اول دوره در حسابیکس" - -#: admin/partials/ssbhesabix-admin-setting.php:422 -msgid "Export Customers" -msgstr "خروجی مشتریان" - -#: admin/partials/ssbhesabix-admin-setting.php:425 -msgid "Export and add all online store customers to Hesabix." -msgstr "افزودن تمامی مشتریان فروشگاه آنلاین در حسابیکس" - -#: admin/partials/ssbhesabix-admin-setting.php:437 -msgid "Sync completed, All hesabix changes synced successfully." -msgstr "همسان‌سازی پایان یافت. تمامی تغییرات با حسابیکس همسان شد." - -#: admin/partials/ssbhesabix-admin-setting.php:445 -msgid "Sync completed, All products price/quantity synced successfully." -msgstr "همسان سازی پایان یافت. قیمت/موجودی تمامی محصولات به روز شدند." - -#: admin/partials/ssbhesabix-admin-setting.php:449 -msgid "Sync products fail. Please check the log file." -msgstr "همسان‌سازی محصولات با خطا مواجه شد. لطفا لاگ را بررسی کنید." - -#: admin/partials/ssbhesabix-admin-setting.php:459 -#, php-format -msgid "Order sync completed. %s order added." -msgstr "همسان‌سازی پایان یافت. %s فاکتور به‌روزرسانی/افزوده شد." - -#: admin/partials/ssbhesabix-admin-setting.php:467 -msgid "The date entered is not within the fiscal year." -msgstr "تاریخ وارد شده در محدوده سال مالی نمی‌باشد." - -#: admin/partials/ssbhesabix-admin-setting.php:471 -msgid "Invoices are not synced before installing the plugin." -msgstr "" -"فاکتورهایی که قبل از زمان نصب این پلاگین صادر شده‌اند، امکان همسان‌سازی ندارند." - -#: admin/partials/ssbhesabix-admin-setting.php:475 -msgid "Cannot sync orders. Please enter valid Date format." -msgstr "امکان همسان سازی سفارشات نیست. لطفا تاریخ معتبری وارد نمایید." - -#: admin/partials/ssbhesabix-admin-setting.php:482 -msgid "Sync can take several minutes." -msgstr "همسان‌سازی ممکن است چند دقیقه زمان ببرد." - -#: admin/partials/ssbhesabix-admin-setting.php:183 -msgid "Enable or Disable Debug Mode" -msgstr "فعال کردن دیباگ مود" - -#: admin/partials/ssbhesabix-admin-setting.php:246 -msgid "Set request amount per batch for sync products based on woocommerce in Hesabix" -msgstr "تعداد درخواست ها در هر پارت برای همسان سازی محصولات در حسابیکس بر اساس فروشگاه آنلاین" - -#: admin/partials/ssbhesabix-admin-setting.php:263 -msgid "Set request amount per batch for sync products based on Hesabix in Woocommerce" -msgstr "تعداد درخواست ها در هر پارت برای همسان سازی محصولات در فروشگاه آنلاین بر اساس حسابیکس" - -#: admin/partials/ssbhesabix-admin-setting.php:280 -msgid "Set request amount per batch for import products" -msgstr "تعداد درخواست ها در هر پارت برای ورود محصولات" - -#: admin/partials/ssbhesabix-admin-setting.php:297 -msgid "Set request amount per batch for export products" -msgstr "تعداد درخواست ها در هر پارت برای استخراج محصولات" - -#: admin/partials/ssbhesabix-admin-setting.php:308 -msgid "select" -msgstr "انتخاب کنید" - -#: admin/partials/ssbhesabix-admin-setting.php:317 -msgid "Plugin Default" -msgstr "مقدار پیش فرض افزونه" - -#: admin/partials/ssbhesabix-admin-setting.php:314 -msgid "Set request amount per batch for export opening quantity of products" -msgstr "تعداد درخواست ها در هر پارت برای استخراج موجودی اول دوره کالا ها" - -#: admin/partials/ssbhesabix-admin-setting.php:494 -msgid "Sync Changes" -msgstr "همسان‌سازی تغییرات" - -#: admin/partials/ssbhesabix-admin-setting.php:497 -msgid "Sync all Hesabix changes with Online Store." -msgstr "همسان‌سازی تمامی تعییرات حسابیکس با فروشگاه آن‌لاین" - -#: admin/partials/ssbhesabix-admin-setting.php:509 -msgid "Sync Products Quantity and Price" -msgstr "همسان‌سازی قیمت و موجودی محصولات" - -#: admin/partials/ssbhesabix-admin-setting.php:512 -msgid "Sync quantity and price of products in hesabix with online store." -msgstr "همسان‌سازی قیمت و موجودی محصولات حسابیکس با فروشگاه آن‌لاین" - -#: admin/partials/ssbhesabix-admin-setting.php:525 -msgid "Sync Orders" -msgstr "همسان‌سازی سفارشات" - -#: admin/partials/ssbhesabix-admin-setting.php:528 -msgid "Sync/Add orders in online store with hesabix from above date." -msgstr "همسان‌سازی سفارشات فروشگاه آن‌لاین با حسابیکس از تاریخ فوق" - -#: admin/partials/ssbhesabix-admin-setting.php:557 -msgid "Cannot check the last change ID. Error Message: " -msgstr "امکان بررسی آخرین تغییرات وجود ندارد. شرح خطا:" - -#: admin/partials/ssbhesabix-admin-setting.php:567 -msgid "" -"The fiscal year has passed or not arrived. Please check the fiscal year " -"settings in Hesabix." -msgstr "" -"سال مالی گذشته است یا هنوز فرا نرسیده است، لطفا تنظیمات سال مالی در حسابیکس را " -"بررسی کنید." - -#: admin/partials/ssbhesabix-admin-setting.php:585 -msgid "Hesabix and WooCommerce default currency must be same." -msgstr "واحد پول پیش‌فرض حسابیکس و ووکامرس باید یکی باشد." - -#: admin/partials/ssbhesabix-admin-setting.php:590 -msgid "Cannot check the Hesabix default currency. Error Message: " -msgstr "امکان دریافت واحد پول پیش‌فرض حسابیکس وجود ندارد. شرح خطا:" - -#: admin/partials/ssbhesabix-admin-setting.php:598 -msgid "API Setting updated. Test Successfully" -msgstr "تنظیمات API به روزرسانی شد، اتصال موفقیت آمیز بود." - -#: admin/partials/ssbhesabix-admin-setting.php:605 -msgid "Cannot set Hesabix webHook. Error Message:" -msgstr "امکان تنظیم وب‌هوک در حسابیکس وجود ندارد. شرح خطا:" - -msgid "Cannot connect to Hesabix. Business expired." -msgstr "امکان اتصال به حسابیکس وجود ندارد، کسب و کار منقضی شده است." - -#: admin/partials/ssbhesabix-admin-setting.php:614 -msgid "Cannot connect to Hesabix servers. Please check your Internet connection" -msgstr "اتصال به حسابیکس برقرار نیست، لطفا اتصال اینترنت را بررسی نمایید." - -#: admin/partials/ssbhesabix-admin-setting.php:630 -msgid "No need to set!" -msgstr "عدم نیاز به تعریف!" - -#: admin/partials/ssbhesabix-admin-setting.php:630 -msgid "Choose" -msgstr "انتخاب کنید" - -#: admin/partials/ssbhesabix-admin-setting.php:638 -msgid "Define at least one bank in Hesabix" -msgstr "حداقل یک حساب بانکی در حسابیکس تعریف کنید." - -#: admin/partials/ssbhesabix-admin-setting.php:646 -#: admin/partials/ssbhesabix-admin-setting.php:650 -msgid "Cannot get Banks detail." -msgstr "امکان دریافت اطلاعات بانک‌ها نیست." - -#: admin/partials/ssbhesabix-html-output.php:288 -msgid "Select a page…" -msgstr "انتخاب ‫دسته‌بندی" - -#: admin/partials/ssbhesabix-html-output.php:379 -msgid "Settings were saved successfully." -msgstr "تنظیمات به‌روزرسانی شد." - -#. Plugin URI of the plugin/theme -msgid "https://hesabix.ir/" -msgstr "‏https://hesabix.ir/" - -#. Description of the plugin/theme -msgid "Connect Hesabix Online Accounting to WooCommerce." -msgstr "\tاتصال نرم‌افزار حسابداری ابری حسابیکس به ووکامرس" - -#. Author of the plugin/theme -msgid "Saeed Sattar Beglou" -msgstr "سعید ستاربگلو" - -msgid "Log" -msgstr "لاگ" - -msgid "Events and bugs log" -msgstr "لاگ رویدادها و خطاها" - -msgid "Clean current log" -msgstr "پاک کردن لاگ جاری" - -msgid "Download log file" -msgstr "دانلود فایل لاگ" - -msgid "The log file was cleared." -msgstr "فایل لاگ پاک شد." - -msgid "Log file not found." -msgstr "فایل لاگ پیدا نشد." - -msgid "Update Products in Hesabix based on store" -msgstr "به روزرسانی محصولات در حسابیکس بر اساس فروشگاه" - -msgid "Update products in hesabix based on products definition in store." -msgstr "به روزرسانی محصولات در حسابیکس بر اساس مشخصات آنها در فروشگاه. محصولات جدید به حسابیکس اضافه می شوند و محصولات قبلی ویرایش می شوند." - -msgid "Update completed successfully." -msgstr "به روزرسانی با موفقیت انجام شد." - -msgid "Update failed. Please check the log file." -msgstr "به روزرسانی ناموفق بود. لطفاً لاگ را بررسی کنید." - -msgid "Number of products in store:" -msgstr "تعداد محصولات در فروشگاه:" - -msgid "Number of products in hesabix:" -msgstr "تعداد محصولات در حسابیکس:" - -msgid "Number of linked products:" -msgstr "تعداد محصولات لینک شده:" - -msgid "Save and next page" -msgstr "ذخیره و صفحه بعد" - -msgid "Invoice in Hesabix" -msgstr "فاکتور حسابیکس" - -msgid "Submit Invoice" -msgstr "ثبت فاکتور" - -msgid "Submit Invoice in Hesabix" -msgstr "ثبت فاکتور در حسابیکس" - -msgid "Submit Product in Hesabix" -msgstr "ثبت محصول در حسابیکس" - -msgid "Do not submit product in Hesabix automatically by saving product in woocommerce" -msgstr "با ذخیره محصول در ووکامرس، محصول را بصورت اتوماتیک در حسابیکس ثبت نکن" - -msgid "Submit Price in Hesabix" -msgstr "ثبت قیمت در حسابیکس" - -msgid "Do not update product price in Hesabix by editing product in woocommerce" -msgstr "با ویرایش محصول در ووکامرس، قیمت محصول را در حسابیکس بروز نکن" - -msgid "Barcode in Hesabix" -msgstr "بارکد در حسابیکس" - -msgid "Do not update product barcode in Hesabix by saving product in woocommerce" -msgstr "با ذخیره محصول در ووکامرس، بارکد محصول را در حسابیکس بروز نکن" - -msgid "Do not update product category in Hesabix by saving product in woocommerce" -msgstr "با ذخیره محصول در ووکامرس، دسته بندی محصول را در حسابیکس بروز نکن" - -msgid "Do not update product code in Hesabix by saving product in woocommerce" -msgstr "با ذخیره محصول در ووکامرس، کد محصول را در حسابیکس بروز نکن" - -msgid "Shipping method" -msgstr "روش حمل و نقل" - -msgid "Invoice's Salesman" -msgstr "فروشنده فاکتور" - -msgid "Invoice Salesman Percentage" -msgstr "درصد پورسانت فروشنده فاکتور" - -msgid "Invoice's Project" -msgstr "پروژه فاکتور" - -msgid "Submit Cash in Transit" -msgstr "ثبت در وجوه در راه" - -msgid "Submit Invoice Receipt Cash in Transit" -msgstr "ثبت رسید دریافت فاکتور در وجوه در راه" - -msgid "Invoice Transaction Fee Percentage" -msgstr "درصد کارمزد تراکنش" - -msgid "Plugin Tutorial Video" -msgstr "ویدیوی خودآموز افزونه" - -msgid "Titles" -msgstr "عناوین" - -msgid "Accounting quantity (Total inventory)" -msgstr "موجودی حسابداری (موجودی کل)" - -msgid "Cannot get warehouses." -msgstr "امکان دریافت اطلاعات انبارها نیست." - -msgid "Update product's quantity based on" -msgstr "بروزرسانی موجودی کالا بر اساس" - -msgid "Warehouse system is not active in Hesabix." -msgstr "سیستم انبارداری در حسابیکس فعال نیست." - -msgid "API Address" -msgstr "آدرس API" - -msgid "Contact Code in Hesabix" -msgstr "کد شخص در حسابیکس" - -msgid "" -"The contact code of this user in Hesabix, if you want to map this user " -"to a contact in Hesabix, enter the Contact code." -msgstr "" -"این فیلد کد شخص در حسابیکس است، اگر می‌خواهید این کاربر را به شخصی " -"در حسابیکس ارتباط دهید، کد شخص را وارد نمایید." - -msgid "Error: Select maximum 10 orders. Due to some limitations in Hesabix API, sending too many requests in one minute is not possible." -msgstr "خطا: حداکثر ۱۰ سفارش را انتخاب کنید. بدلیل محدودیت رابط برنامه نویسی حسابیکس، ارسال درخواست های زیاد در یک دقیقه امکان پذیر نیست." - -msgid "Selected orders invoices have been saved. Number of saved invoices: " -msgstr "فاکتور سفارش های انتخاب شده ثبت شد. تعداد فاکتور های ثبت شده: " - -msgid "Update sale price" -msgstr "بروزرسانی قیمت فروش ویژه" - -msgid "The Sale price does not change" -msgstr "قیمت فروش ویژه تغییر نکند" - -msgid "The Sale price gets removed" -msgstr "قیمت فروش ویژه حذف گردد" - -msgid "The sale price get changes in proportion to the regular price" -msgstr "قیمت فروش ویژه به تناسب قیمت اصلی تغییر یابد" - -msgid "Submit invoice base on Dokan orders" -msgstr "ثبت فاکتور بر اساس سفارشات افزونه دکان" - -msgid "Submit parent order" -msgstr "ثبت سفارش مادر" - -msgid "Submit children orders" -msgstr "ثبت زیر سفارش ها" - -msgid "Inactive" -msgstr "غیر فعال" - -#~ msgid "Sync completed, All products added/updated." -#~ msgstr "همسان‌سازی پایان یافت. تمامی محصولات به‌روزرسانی/افزوده شدند." - -#~ msgid "Sync completed, No product added/updated." -#~ msgstr "همسان‌سازی پایان یافت. هیچ محصولی به‌روزرسانی/افزوده شدند." - -#~ msgid "Sync completed; All hesabix changes synced successfully." -#~ msgstr "همسان‌سازی پایان یافت. تمامی تغییرات با حسابیکس همسان شد." - -#~ msgid "Sync completed; All products added/updated." -#~ msgstr "همسان‌سازی پایان یافت. تمامی محصولات به‌روزرسانی/افزوده شدند." - -#~ msgid "Sync completed; No product added/updated." -#~ msgstr "همسان‌سازی پایان یافت. هیچ محصولی به‌روزرسانی/افزوده شدند." - -#~ msgid "Export product completed. %s product added/updated." -#~ msgstr "استخراج پایان یافت. %s محصول به‌روزرسانی/افزوده شد." - -#~ msgid "Export customers completed. %s product added/updated." +msgid "" +msgstr "" +"Project-Id-Version: Hesabix Accounting\n" +"POT-Creation-Date: 2021-01-08 14:20+0330\n" +"PO-Revision-Date: 2021-01-08 14:20+0330\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: fa_IR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.2\n" +"X-Poedit-Basepath: ..\n" +"X-Poedit-WPHeader: ssbhesabix.php\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;" +"esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;" +"_nx_noop:3c,1,2;__ngettext_noop:1,2\n" +"X-Poedit-SearchPath-0: .\n" +"X-Poedit-SearchPathExcluded-0: *.js\n" + +#: admin/class-ssbhesabix-admin.php:137 +#, php-format +msgid "Hesabix Plugin requires the %s to work!" +msgstr "افزونه حسابیکس نیازمند %s است!" + +#: admin/class-ssbhesabix-admin.php:137 +msgid "WooCommerce" +msgstr "ووکامرس" + +#: admin/class-ssbhesabix-admin.php:146 +msgid "" +"Hesabix Plugin need to connect to Hesabix Accounting, Please check the API " +"credential!" +msgstr "" +"افزونه حسابیکس نیازمند\t اتصال به نرم‌افزار حسابداری حسابیکس است، لطفا اطلاعات " +"دسترسی به API حسابیکس را بررسی کنید!" + +#: admin/class-ssbhesabix-admin.php:155 +msgid "" +"Hesabix Plugin cannot works! because WooCommerce currency in not match with " +"Hesabix." +msgstr "" +"افزونه حسابیکس نمی‌تواند به درستی عمل کند! واحد پول پیش‌فرض ووکامرس با واحد پول " +"پیش‌فرض حسابیکس همخوانی ندارد." + +#: admin/class-ssbhesabix-admin.php:410 admin/class-ssbhesabix-admin.php:502 +msgid "The new Item code already used for another Item" +msgstr "این کد قبلا برای کالایی دیگر استفاده شده است." + +#: admin/class-ssbhesabix-admin.php:483 +msgid "Hesabix base item code" +msgstr "کد کالای پایه در حسابیکس" + +#: admin/class-ssbhesabix-admin.php:485 +msgid "" +"The base Item code of this product in Hesabix, if you want to map this product " +"to another item in Hesabix, enter the new Item code." +msgstr "" +"این فیلد کد کالای پایه در حسابیکس است، اگر می‌خواهید این کالا را به کالای دیگری " +"در حسابیکس ارتباط دهید، کد کالای جدید را وارد نمایید." + +#: admin/class-ssbhesabix-admin.php:521 +msgid "Hesabix variable item code" +msgstr "کد کالای متغیر در حسابیکس" + +#: admin/class-ssbhesabix-admin.php:523 +msgid "" +"The variable Item code of this product variable in Hesabix, if you want to map " +"this product to another item in Hesabix, enter the new Item code." +msgstr "" +"این فیلد کد کالای متغییر در حسابیکس است، اگر می‌خواهید این کالا را به کالای " +"دیگری در حسابیکس ارتباط دهید، کد کالای جدید را وارد نمایید." + +#: admin/partials/ssbhesabix-admin-display.php:305 +msgid "Extra Settings" +msgstr "تنظیمات پیشرفته" + +#: admin/partials/ssbhesabix-admin-display.php:338 +msgid "Sync Last Change ID" +msgstr "بروزرسانی ID آخرین تغییر" + +#: admin/partials/ssbhesabix-admin-display.php:28 +msgid "Hesabix Options" +msgstr "تنظیمات افزونه حسابیکس" + +#: admin/partials/ssbhesabix-admin-display.php:28 +msgid "Hesabix" +msgstr "حسابیکس" + +#: admin/partials/ssbhesabix-admin-display.php:38 +msgid "Home" +msgstr "خانه" + +#: admin/partials/ssbhesabix-admin-display.php:39 +msgid "API" +msgstr "‏API" + +#: admin/partials/ssbhesabix-admin-display.php:40 +msgid "Catalog" +msgstr "محصولات" + +#: admin/partials/ssbhesabix-admin-display.php:41 +msgid "Customers" +msgstr "مشتریان" + +#: admin/partials/ssbhesabix-admin-display.php:42 +msgid "Invoice" +msgstr "فاکتور" + +#: admin/partials/ssbhesabix-admin-display.php:43 +msgid "Payment Methods" +msgstr "روش‌های پرداخت" + +#: admin/partials/ssbhesabix-admin-display.php:44 +msgid "Export" +msgstr "خروجی" + +msgid "Import and export data" +msgstr "ورود و خروج اطلاعات" + +#: admin/partials/ssbhesabix-admin-display.php:45 +msgid "Sync" +msgstr "همسان‌سازی" + +#: admin/partials/ssbhesabix-admin-display.php:65 +msgid "" +"Hesabix Plugin requires the WooCommerce to work!, Please install/activate " +"woocommerce and try again" +msgstr "" +"افزونه حسابیکس جهت راه‌اندازی نیاز به ووکامرس دارد! لطفا ووکامرس را نصب/فعال " +"کنید و مجدد سعی کنید." + +#: admin/partials/ssbhesabix-admin-functions.php:269 +#: admin/partials/ssbhesabix-admin-functions.php:964 +msgid "Not Defined" +msgstr "وارد نشده" + +#: admin/partials/ssbhesabix-admin-functions.php:290 +#: admin/partials/ssbhesabix-admin-functions.php:311 +#: admin/partials/ssbhesabix-admin-functions.php:332 +#: admin/partials/ssbhesabix-admin-functions.php:981 +msgid "Customer ID in OnlineStore: " +msgstr "شناسه مشتری در فروشگاه آن‌لاین:" + +#: admin/partials/ssbhesabix-admin-functions.php:383 +msgid "Guest Customer" +msgstr "مشتری مهمان" + +#: admin/partials/ssbhesabix-admin-functions.php:402 +msgid "Customer registered as a GuestCustomer." +msgstr "مشتری به عنوان مهمان ثبت‌نام کرده است." + +#. Plugin Name of the plugin/theme +#: admin/partials/ssbhesabix-admin-setting.php:44 +msgid "Hesabix Accounting" +msgstr "نرم‌افزار حسابداری آنلاین حسابیکس" + +#: admin/partials/ssbhesabix-admin-setting.php:186 +msgid "Enable or Disable Advanced Log" +msgstr "تب لاگ پیشرفته" + +#: admin/partials/ssbhesabix-admin-setting.php:1455 +msgid "Start ID" +msgstr "از شناسه (کد کالای ووکامرس)" +#: admin/partials/ssbhesabix-admin-setting.php:1456 +msgid "End ID" +msgstr "تا شناسه (کد کالای ووکامرس)" +#: admin/partials/ssbhesabix-admin-setting.php:1456 +msgid "Update Products in Hesabix based on store with filter" +msgstr "بروزرسانی محصولات در حسابیکس بر اساس فروشگاه در بازه ID مشخص شده" + +#: admin/partials/ssbhesabix-admin-setting.php:189 +msgid "Performance Optimization Settings" +msgstr "تنظیمات بهینه سازی عملکرد" + +#: admin/partials/ssbhesabix-admin-setting.php:189 +msgid "Disable The Advanced Log" +msgstr "غیرفعال کردن تب لاگ پیشرفته" + +#: admin/partials/ssbhesabix-admin-setting.php:190 +msgid "Enable The Advanced Log" +msgstr "فعال کردن تب لاگ پیشرفته" + +#: admin/partials/ssbhesabix-admin-setting.php:45 +msgid "" +"This module helps connect your (online) store to Hesabix online accounting " +"software. By using this module, saving products, contacts, and orders in your " +"store will also save them automatically in your Hesabix account. Besides that, " +"just after a client pays a bill, the receipt document will be stored in " +"Hesabix as well. Of course, you have to register your account in Hesabix " +"first. To do so, visit Hesabix at the link here www.hesabix.com and sign up " +"for free. After you signed up and entered your account, choose your business, " +"then in the settings menu/API, you can find the API keys for the business and " +"import them to the plugin’s settings. Now your module is ready to use." +msgstr "" +"این ماژول فروشگاه شما را به نرم افزار حسابداری آنلاین حسابیکس متصل می کند. به " +"وسیله ی این ماژول کالاها، مشتریان و سفارشات شما به محض ثبت در سیستم فروشگاه، " +"در حسابیکس نیز بصورت خودکار ثبت و ذخیره می شوند. همچنین با پرداخت مشتری، سند " +"دریافت وجه از مشتری نیز در حسابیکس ثبت می شود. بدیهی است برای استفاده از این " +"افزونه باید ابتدا یک حساب کاربری در حسابیکس داشته باشید. برای این کار می توانید " +"به وب سایت حسابیکس به آدرس www.hesabix.com سر بزنید و به رایگان ثبت نام کنید. " +"پس از ثبت نام در حسابیکس و ورود به حساب خود، و سپس ورود به یک کسب و کار، در " +"قسمت تنظیمات / API می توانید کلید API مربوط به کسب و کار خود را دریافت و در " +"قسمت تنظیمات این ماژول وارد نمایید. پس از آن ماژول شما آماده استفاده است." + +#: admin/partials/ssbhesabix-admin-setting.php:46 +msgid "" +"For more information and a full guide to how to use Hesabix and WooCommerce " +"Plugin, visit Hesabix’s website and go to the “Guides and Tutorials” menu." +msgstr "" +"برای کسب اطلاعات بیشتر و راهنمای استفاده از حسابیکس و افزونه ووکامرس به وب سایت " +"حسابیکس، قسمت راهنما ها و خودآموز ها مراجعه کنید." + +#: admin/partials/ssbhesabix-admin-setting.php:53 +msgid "Catalog Settings" +msgstr "تنظیمات محصولات" + +#: admin/partials/ssbhesabix-admin-setting.php:56 +msgid "Update Price" +msgstr "به‌روزرسانی قیمت" + +#: admin/partials/ssbhesabix-admin-setting.php:57 +msgid "Update Price after change in Hesabix" +msgstr "به‌روزرسانی قیمت بعد از تغییر در حسابیکس" + +#: admin/partials/ssbhesabix-admin-setting.php:64 +msgid "Update Quantity" +msgstr "به‌روزرسانی موجودی" + +#: admin/partials/ssbhesabix-admin-setting.php:65 +msgid "Update Quantity after change in Hesabix" +msgstr "به‌روزرسانی موجودی بعد از تغییر در حسابیکس" + +#: admin/partials/ssbhesabix-admin-setting.php:240 +msgid "Show Hesabix ID in Products Page" +msgstr "نمایش کد حسابیکس در صفحه همه محصولات" + +#: admin/partials/ssbhesabix-admin-setting.php:240 +msgid "Show Hesabix Code in Woocommerce Excel Export" +msgstr "نمایش کد حسابیکس در خروجی اکسل ووکامرس" + +#: admin/partials/ssbhesabix-admin-setting.php:679 +msgid "Default Payment Gateway By Using this Option, all Invoices Will Have this Payment Gateway as Their Payment Gateway" +msgstr "درگاه پرداخت پیش فرض" + +#: admin/partials/ssbhesabix-admin-setting.php:695 +msgid "Default Bank Code" +msgstr "کد بانک پیش فرض" + +#: admin/partials/ssbhesabix-admin-setting.php:689 +msgid "Default Bank Name" +msgstr "نام بانک پیش فرض" + +#: admin/partials/ssbhesabix-admin-setting.php:683 +msgid "Save Default Bank as the Payment Gateway" +msgstr "بانک پیش فرض به عنوان درگاه پرداخت ذخیره شود" + +#: admin/partials/ssbhesabix-admin-setting.php:684 +msgid "Save Other Payment Methods as the Payment Gateway" +msgstr "روش های دیگر پرداخت به عنوان درگاه پرداخت ذخیره شود" + +#: admin/partials/ssbhesabix-admin-setting.php:246 +msgid "Set Special Sale as Discount in invoice" +msgstr "ثبت فروش ویژه به عنوان تخفیف در فاکتور" + +#: admin/partials/ssbhesabix-admin-setting.php:693 +msgid "Enter Bank Code" +msgstr "کد بانک را وارد نمایید" + +#: admin/partials/ssbhesabix-admin-setting.php:700 +msgid "Enter Bank Name" +msgstr "نام بانک را وارد نمایید" + +#: admin/partials/ssbhesabix-admin-setting.php:700 +msgid "Enter Freight Code" +msgstr "کد هزینه حمل و نقل را وارد نمایید" + +#: admin/partials/ssbhesabix-admin-setting.php:1642 +msgid "Delete Logs Between These Tow Dates" +msgstr "حذف لاگ ها در بازه مشخص شده" + +#: admin/partials/ssbhesabix-admin-setting.php:1633 +msgid "Log History" +msgstr "تاریخچه لاگ ها" +#: admin/partials/ssbhesabix-admin-setting.php:1648 +#: admin/partials/ssbhesabix-admin-setting.php:1680 +msgid "Delete All Log Files" +msgstr "پاک کردن کل لاگ ها" +#: admin/partials/ssbhesabix-admin-setting.php:1613 +msgid "Find Log File" +msgstr "جستجوی فایل لاگ براساس تاریخ" + +#: admin/partials/ssbhesabix-admin-setting.php:84 +#: admin/partials/ssbhesabix-admin-setting.php:130 +#: admin/partials/ssbhesabix-admin-setting.php:191 +#: admin/partials/ssbhesabix-admin-setting.php:250 +#: admin/partials/ssbhesabix-admin-setting.php:301 +msgid "Save changes" +msgstr "ذخیره تغییرات" + +msgid "Save" +msgstr "ذخیره" + +#: admin/partials/ssbhesabix-admin-setting.php:99 +msgid "Customers Settings" +msgstr "تنظیمات مشتری" + +#: admin/partials/ssbhesabix-admin-setting.php:102 +msgid "Update Customer Address" +msgstr "به روزرسانی آدرس مشتریان" + +#: admin/partials/ssbhesabix-admin-setting.php:103 +msgid "Choose when update Customer address in Hesabix." +msgstr "انتخاب کنید که در چه حالتی آدرس مشتری در حسابیکس به‌روزرسانی شود" + +#: admin/partials/ssbhesabix-admin-setting.php:106 +msgid "Use first customer address" +msgstr "اولین آدرس مشتری" + +#: admin/partials/ssbhesabix-admin-setting.php:106 +msgid "update address with Invoice address" +msgstr "به روزرسانی با آدرس فاکتور سفارش" + +#: admin/partials/ssbhesabix-admin-setting.php:106 +msgid "update address with Delivery address" +msgstr "به‌روزرسانی با آدرس ارسال سفارش" + +#: admin/partials/ssbhesabix-admin-setting.php:110 +msgid "Customer's Group" +msgstr "دسته‌بندی مشتریان" + +#: admin/partials/ssbhesabix-admin-setting.php:111 +msgid "Enter a Customer's Group in Hesabix" +msgstr "نام دسته‌بندی مشتریان در حسابیکس را وارد کنید" + + + +#: admin/partials/ssbhesabix-admin-setting.php:110 +msgid "Save Customer's group" +msgstr "ذخیره دسته بندی مشتریان" + + +#: admin/partials/ssbhesabix-admin-setting.php:110 +msgid "Automatically save Customer's group in hesabix" +msgstr "به صورت خودکار دسته بندی مشتریان را در حسابیکس ذخیره کن" + + +#: admin/partials/ssbhesabix-admin-setting.php:111 +msgid "Customer's detail auto save and update" +msgstr "ذخیره خودکار مشتریان" + +#: admin/partials/ssbhesabix-admin-setting.php:111 +msgid "Check customer's phone with national code in user edit page" +msgstr "بررسی تطابق شماره صورتحساب کاربر با کدملی" + +#: admin/partials/ssbhesabix-admin-setting.php:111 +msgid Check customer's phone with national code in user edit page and don't allow to save in hesabix" +msgstr "بررسی تطابق شماره صورتحساب کاربر با کدملی توسط سامانه استعلام در صفحه ویرایش کاربر" + +#: admin/partials/ssbhesabix-admin-setting.php:111 +msgid "Save and update Customer's detail automatically in hesabix" +msgstr "ثبت و ذخیره خودکار اطلاعات مشتریان در حسابیکس" + +msgid "Add additional fields to checkout page" +msgstr "افزودن فیلد های دلخواه به صفحه پرداخت" + + +msgid "Customer add field to checkout by hesabix" +msgstr "افزودن فیلد ها توسط افزونه حسابیکس" + + +msgid "Customer add field to checkout by postmeta" +msgstr "استفاده از فیلد های موجود در جدول متا (که توسط افزونه های دیگر اضافه شده است)" + + +msgid "Show" +msgstr "نمایش" + +msgid "Title" +msgstr "عنوان" + +msgid "Meta code in Postmeta" +msgstr "کد متا در جدول پست متا" + +msgid "National code" +msgstr "کد ملی" + +msgid "Economic code" +msgstr "کد اقتصادی" + +msgid "Registration number" +msgstr "شماره ثبت" + +msgid "Website" +msgstr "وب سایت" + +msgid "Required" +msgstr "اجباری" + +msgid "please enter your National code" +msgstr "لطفا کد ملی خود را وارد کتید" + +msgid "please enter a valid national code" +msgstr "لطفا کد ملی معتبر وارد نمایید" + +msgid "please enter your Economic code" +msgstr "لطفا کد اقتصادی خود را وارد کتید" + +msgid "please enter your Registration number" +msgstr "لطفا شماره ثبت خود را وارد کتید" + +msgid "please enter your Website address" +msgstr "لطفا آدرس سایت خود را وارد کنید" + +msgid "please enter a valid Website URL" +msgstr "لطفا آدرس سایت معتبر وارد نمایید" + +#: admin/partials/ssbhesabix-admin-setting.php:144 +msgid "Invoice Settings" +msgstr "تنظیمات فاکتور" + +#: admin/partials/ssbhesabix-admin-setting.php:147 +msgid "Add invoice in which status" +msgstr "افزودن فاکتور در وضعیت:" + +#: admin/partials/ssbhesabix-admin-setting.php:380 +msgid "Save invoice in draft mode in Hesabix" +msgstr "ثبت فاکتور بصورت پیش نویس در حسابیکس" + +#: admin/partials/ssbhesabix-admin-setting.php:557 +msgid "Save Freight" +msgstr "ذخیره هزینه حمل و نقل" + +#: admin/partials/ssbhesabix-admin-setting.php:561 +msgid "Save as Freight" +msgstr "ذخیره به عنوان هزینه" + +#: admin/partials/ssbhesabix-admin-setting.php:562 +msgid "Save as a Service" +msgstr "ذخیره به عنوان یک خدمت" + +#: admin/partials/ssbhesabix-admin-setting.php:562 +msgid "Service Code For Freight" +msgstr "کد خدمت حمل و نقل ذخیره شده در حسابیکس" + +#: admin/partials/ssbhesabix-admin-setting.php:151 +#: admin/partials/ssbhesabix-admin-setting.php:167 +#: admin/partials/ssbhesabix-admin-setting.php:217 +msgid "Pending payment" +msgstr "در انتظار پرداخت" + +#: admin/partials/ssbhesabix-admin-setting.php:152 +#: admin/partials/ssbhesabix-admin-setting.php:168 +#: admin/partials/ssbhesabix-admin-setting.php:218 +msgid "Processing" +msgstr "در حال انجام" + +#: admin/partials/ssbhesabix-admin-setting.php:153 +#: admin/partials/ssbhesabix-admin-setting.php:169 +#: admin/partials/ssbhesabix-admin-setting.php:219 +msgid "On hold" +msgstr "در انتظار بررسی" + +#: admin/partials/ssbhesabix-admin-setting.php:154 +#: admin/partials/ssbhesabix-admin-setting.php:170 +#: admin/partials/ssbhesabix-admin-setting.php:220 +msgid "Completed" +msgstr "تکمیل شده" + +#: admin/partials/ssbhesabix-admin-setting.php:155 +#: admin/partials/ssbhesabix-admin-setting.php:171 +#: admin/partials/ssbhesabix-admin-setting.php:221 +msgid "Cancelled" +msgstr "لغو شده" + +#: admin/partials/ssbhesabix-admin-setting.php:156 +#: admin/partials/ssbhesabix-admin-setting.php:172 +#: admin/partials/ssbhesabix-admin-setting.php:222 +msgid "Refunded" +msgstr "مسترد شده" + +#: admin/partials/ssbhesabix-admin-setting.php:157 +#: admin/partials/ssbhesabix-admin-setting.php:173 +#: admin/partials/ssbhesabix-admin-setting.php:223 +msgid "Failed" +msgstr "ناموفق" + +#: admin/partials/ssbhesabix-admin-setting.php:158 +#: admin/partials/ssbhesabix-admin-setting.php:174 +#: admin/partials/ssbhesabix-admin-setting.php:224 +msgid "Draft" +msgstr "پیش‌نویس" + +#: admin/partials/ssbhesabix-admin-setting.php:163 +msgid "Return sale invoice status" +msgstr "ثبت فاکتور برگشت از فروش در وضعیت" + +#: admin/partials/ssbhesabix-admin-setting.php:210 +msgid "Payment methods Settings" +msgstr "تنظیمات روش پرداخت" + +#: admin/partials/ssbhesabix-admin-setting.php:213 +msgid "Add payment in which status" +msgstr "افزودن پرداخت در وضعیت:" + +#: admin/partials/ssbhesabix-admin-setting.php:265 +msgid "API Settings" +msgstr "تنظیمات API" + +#: admin/partials/ssbhesabix-admin-setting.php:268 +msgid "Email" +msgstr "آدرس ایمیل" + +#: admin/partials/ssbhesabix-admin-setting.php:269 +msgid "Enter a Hesabix email account" +msgstr "آدرس ایمیل اکانت حسابیکس را وارد کنید" + +#: admin/partials/ssbhesabix-admin-setting.php:275 +msgid "Password" +msgstr "رمزعبور" + +#: admin/partials/ssbhesabix-admin-setting.php:276 +msgid "Enter a Hesabix password" +msgstr "رمزعبور حسابیکس را وارد کنید" + +#: admin/partials/ssbhesabix-admin-setting.php:282 +msgid "API Key" +msgstr "کلید API" + +msgid "Login token" +msgstr "توکن ورود" + +#: admin/partials/ssbhesabix-admin-setting.php:283 +msgid "Find API key in Setting->Financial Settings->API Menu" +msgstr "کلید API را در حسابیکس از منوی تنظیمات->تنظیمات مالی->API پیدا کنید" + +msgid "Find Login token in Setting->Financial Settings->API Menu" +msgstr "توکن ورود را در حسابیکس از منوی تنظیمات->تنظیمات مالی->API پیدا کنید" + +#: admin/partials/ssbhesabix-admin-setting.php:323 +msgid "" +"No products were exported, All products were exported or there are no product" +msgstr "" +"هیچ محصولی استخراج نشد، تمامی محصولات قبلا استخراج شده‌اند یا محصولی وجود ندارد." + +msgid "" +"No products were imported, All products were imported or there are no product" +msgstr "" +"هیچ محصولی وارد نشد، تمامی محصولات قبلا وارد شده‌اند یا محصولی وجود ندارد." + + +#: admin/partials/ssbhesabix-admin-setting.php:327 +#, php-format +msgid "Export products completed. %s products added/updated." +msgstr "استخراج محصولات به اتمام رسید. ‪‬%s محصول استخراج شد." + +msgid "Import products completed. %s products added/updated." +msgstr "ورود محصولات به اتمام رسید. ‪‬%s محصول وارد شد." + +#: admin/partials/ssbhesabix-admin-setting.php:335 +msgid "Export products fail. Hesabix has already contained products." +msgstr "خروجی محصولات با خطا مواجه شد. حسابیکس از قبل حاوی محصولاتی است." + +#: admin/partials/ssbhesabix-admin-setting.php:339 +msgid "Export products fail. Please check the log file." +msgstr "خروجی محصولات با خطا مواجه شد. لطفا لاگ را بررسی کنید." + +msgid "Import products fail. Please check the log file." +msgstr "ورود محصولات با خطا مواجه شد. لطفا لاگ را بررسی کنید." + +#: admin/partials/ssbhesabix-admin-setting.php:340 +msgid "Export product opening quantity completed." +msgstr "استخراج موجودی اول دوره با موفقیت به پایان رسید." + +#: admin/partials/ssbhesabix-admin-setting.php:347 +msgid "" +"Export product opening quantity fail. No Shareholder exists, Please define " +"Shareholder in Hesabix" +msgstr "" +"استخراج موجودی اول دوره با خطا مواجه شد. سهامدار تعریف نشده است، لطفا ابتدا " +"سهامداران را در حسابیکس تعریف کنید." + +#: admin/partials/ssbhesabix-admin-setting.php:351 +msgid "No product available for Export product opening quantity." +msgstr "محصولی جهت استخراج موجودی اول دوره در دسترس نمی‌باشد." + +#: admin/partials/ssbhesabix-admin-setting.php:355 +msgid "Export product opening quantity fail. Please check the log file." +msgstr "استخراج موجودی اول دوره با خطا مواجه شد. لطفا لاگ را بررسی کنید." + +#: admin/partials/ssbhesabix-admin-setting.php:366 +msgid "" +"No customers were exported, All customers were exported or there are no " +"customer" +msgstr "" +"هیچ مشتری استخراج نشد، تمامی مشتریان قبلا استخراج شده‌اند یا مشتری وجود ندارد." + +#: admin/partials/ssbhesabix-admin-setting.php:370 +#, php-format +msgid "Export customers completed. %s customers added." +msgstr "استخراج مشتریان به اتمام رسید. %s مشتری استخراج شد." + +#: admin/partials/ssbhesabix-admin-setting.php:375 +msgid "Export customers fail. Please check the log file." +msgstr "استخراج مشتریان با خطا مواجه شد. لطفا لاگ را بررسی کنید." + +#: admin/partials/ssbhesabix-admin-setting.php:381 +msgid "Export can take several minutes." +msgstr "استخراج ممکن است چند دقیقه زمان ببرد." + +msgid "Export customers fail. Hesabix has already contained customers." +msgstr "خروجی مشتریان با خطا مواجه شد. حسابیکس از قبل حاوی مشتریان است." + +#: admin/partials/ssbhesabix-admin-setting.php:392 +msgid "Export Products" +msgstr "خروجی محصولات" + +msgid "Import Products" +msgstr "ورود محصولات" + +#: admin/partials/ssbhesabix-admin-setting.php:395 +msgid "Export and add all online store products to Hesabix" +msgstr "افزودن تمامی محصولات فروشگاه آنلاین در حسابیکس" + +msgid "Import and add all products from Hesabix to online store" +msgstr "افزودن تمامی محصولات حسابیکس به فروشگاه آنلاین" + +#: admin/partials/ssbhesabix-admin-setting.php:407 +msgid "Export Products opening quantity" +msgstr "استخراج موجودی اول دوره" + +#: admin/partials/ssbhesabix-admin-setting.php:410 +msgid "" +"Export the products quantity and record the 'products opening quantity' in the " +"Hesabix" +msgstr "استخراج موجودی محصولات و ثبت موجودی اول دوره در حسابیکس" + +#: admin/partials/ssbhesabix-admin-setting.php:422 +msgid "Export Customers" +msgstr "خروجی مشتریان" + +#: admin/partials/ssbhesabix-admin-setting.php:425 +msgid "Export and add all online store customers to Hesabix." +msgstr "افزودن تمامی مشتریان فروشگاه آنلاین در حسابیکس" + +#: admin/partials/ssbhesabix-admin-setting.php:437 +msgid "Sync completed, All hesabix changes synced successfully." +msgstr "همسان‌سازی پایان یافت. تمامی تغییرات با حسابیکس همسان شد." + +#: admin/partials/ssbhesabix-admin-setting.php:445 +msgid "Sync completed, All products price/quantity synced successfully." +msgstr "همسان سازی پایان یافت. قیمت/موجودی تمامی محصولات به روز شدند." + +#: admin/partials/ssbhesabix-admin-setting.php:449 +msgid "Sync products fail. Please check the log file." +msgstr "همسان‌سازی محصولات با خطا مواجه شد. لطفا لاگ را بررسی کنید." + +#: admin/partials/ssbhesabix-admin-setting.php:459 +#, php-format +msgid "Order sync completed. %s order added." +msgstr "همسان‌سازی پایان یافت. %s فاکتور به‌روزرسانی/افزوده شد." + +#: admin/partials/ssbhesabix-admin-setting.php:467 +msgid "The date entered is not within the fiscal year." +msgstr "تاریخ وارد شده در محدوده سال مالی نمی‌باشد." + +#: admin/partials/ssbhesabix-admin-setting.php:471 +msgid "Invoices are not synced before installing the plugin." +msgstr "" +"فاکتورهایی که قبل از زمان نصب این پلاگین صادر شده‌اند، امکان همسان‌سازی ندارند." + +#: admin/partials/ssbhesabix-admin-setting.php:475 +msgid "Cannot sync orders. Please enter valid Date format." +msgstr "امکان همسان سازی سفارشات نیست. لطفا تاریخ معتبری وارد نمایید." + +#: admin/partials/ssbhesabix-admin-setting.php:482 +msgid "Sync can take several minutes." +msgstr "همسان‌سازی ممکن است چند دقیقه زمان ببرد." + +#: admin/partials/ssbhesabix-admin-setting.php:183 +msgid "Enable or Disable Debug Mode" +msgstr "فعال کردن دیباگ مود" + +#: admin/partials/ssbhesabix-admin-setting.php:246 +msgid "Set request amount per batch for sync products based on woocommerce in Hesabix" +msgstr "تعداد درخواست ها در هر پارت برای همسان سازی محصولات در حسابیکس بر اساس فروشگاه آنلاین" + +#: admin/partials/ssbhesabix-admin-setting.php:263 +msgid "Set request amount per batch for sync products based on Hesabix in Woocommerce" +msgstr "تعداد درخواست ها در هر پارت برای همسان سازی محصولات در فروشگاه آنلاین بر اساس حسابیکس" + +#: admin/partials/ssbhesabix-admin-setting.php:280 +msgid "Set request amount per batch for import products" +msgstr "تعداد درخواست ها در هر پارت برای ورود محصولات" + +#: admin/partials/ssbhesabix-admin-setting.php:297 +msgid "Set request amount per batch for export products" +msgstr "تعداد درخواست ها در هر پارت برای استخراج محصولات" + +#: admin/partials/ssbhesabix-admin-setting.php:308 +msgid "select" +msgstr "انتخاب کنید" + +#: admin/partials/ssbhesabix-admin-setting.php:317 +msgid "Plugin Default" +msgstr "مقدار پیش فرض افزونه" + +#: admin/partials/ssbhesabix-admin-setting.php:314 +msgid "Set request amount per batch for export opening quantity of products" +msgstr "تعداد درخواست ها در هر پارت برای استخراج موجودی اول دوره کالا ها" + +#: admin/partials/ssbhesabix-admin-setting.php:494 +msgid "Sync Changes" +msgstr "همسان‌سازی تغییرات" + +#: admin/partials/ssbhesabix-admin-setting.php:497 +msgid "Sync all Hesabix changes with Online Store." +msgstr "همسان‌سازی تمامی تعییرات حسابیکس با فروشگاه آن‌لاین" + +#: admin/partials/ssbhesabix-admin-setting.php:509 +msgid "Sync Products Quantity and Price" +msgstr "همسان‌سازی قیمت و موجودی محصولات" + +#: admin/partials/ssbhesabix-admin-setting.php:512 +msgid "Sync quantity and price of products in hesabix with online store." +msgstr "همسان‌سازی قیمت و موجودی محصولات حسابیکس با فروشگاه آن‌لاین" + +#: admin/partials/ssbhesabix-admin-setting.php:525 +msgid "Sync Orders" +msgstr "همسان‌سازی سفارشات" + +#: admin/partials/ssbhesabix-admin-setting.php:528 +msgid "Sync/Add orders in online store with hesabix from above date." +msgstr "همسان‌سازی سفارشات فروشگاه آن‌لاین با حسابیکس از تاریخ فوق" + +#: admin/partials/ssbhesabix-admin-setting.php:557 +msgid "Cannot check the last change ID. Error Message: " +msgstr "امکان بررسی آخرین تغییرات وجود ندارد. شرح خطا:" + +#: admin/partials/ssbhesabix-admin-setting.php:567 +msgid "" +"The fiscal year has passed or not arrived. Please check the fiscal year " +"settings in Hesabix." +msgstr "" +"سال مالی گذشته است یا هنوز فرا نرسیده است، لطفا تنظیمات سال مالی در حسابیکس را " +"بررسی کنید." + +#: admin/partials/ssbhesabix-admin-setting.php:585 +msgid "Hesabix and WooCommerce default currency must be same." +msgstr "واحد پول پیش‌فرض حسابیکس و ووکامرس باید یکی باشد." + +#: admin/partials/ssbhesabix-admin-setting.php:590 +msgid "Cannot check the Hesabix default currency. Error Message: " +msgstr "امکان دریافت واحد پول پیش‌فرض حسابیکس وجود ندارد. شرح خطا:" + +#: admin/partials/ssbhesabix-admin-setting.php:598 +msgid "API Setting updated. Test Successfully" +msgstr "تنظیمات API به روزرسانی شد، اتصال موفقیت آمیز بود." + +#: admin/partials/ssbhesabix-admin-setting.php:605 +msgid "Cannot set Hesabix webHook. Error Message:" +msgstr "امکان تنظیم وب‌هوک در حسابیکس وجود ندارد. شرح خطا:" + +msgid "Cannot connect to Hesabix. Business expired." +msgstr "امکان اتصال به حسابیکس وجود ندارد، کسب و کار منقضی شده است." + +#: admin/partials/ssbhesabix-admin-setting.php:614 +msgid "Cannot connect to Hesabix servers. Please check your Internet connection" +msgstr "اتصال به حسابیکس برقرار نیست، لطفا اتصال اینترنت را بررسی نمایید." + +#: admin/partials/ssbhesabix-admin-setting.php:630 +msgid "No need to set!" +msgstr "عدم نیاز به تعریف!" + +#: admin/partials/ssbhesabix-admin-setting.php:630 +msgid "Choose" +msgstr "انتخاب کنید" + +#: admin/partials/ssbhesabix-admin-setting.php:638 +msgid "Define at least one bank in Hesabix" +msgstr "حداقل یک حساب بانکی در حسابیکس تعریف کنید." + +#: admin/partials/ssbhesabix-admin-setting.php:646 +#: admin/partials/ssbhesabix-admin-setting.php:650 +msgid "Cannot get Banks detail." +msgstr "امکان دریافت اطلاعات بانک‌ها نیست." + +#: admin/partials/ssbhesabix-html-output.php:288 +msgid "Select a page…" +msgstr "انتخاب ‫دسته‌بندی" + +#: admin/partials/ssbhesabix-html-output.php:379 +msgid "Settings were saved successfully." +msgstr "تنظیمات به‌روزرسانی شد." + +#. Plugin URI of the plugin/theme +msgid "https://www.hesabix.com/" +msgstr "‏https://www.hesabix.com/" + +#. Description of the plugin/theme +msgid "Connect Hesabix Online Accounting to WooCommerce." +msgstr "\tاتصال نرم‌افزار حسابداری ابری حسابیکس به ووکامرس" + +#. Author of the plugin/theme +msgid "Saeed Sattar Beglou" +msgstr "سعید ستاربگلو" + +msgid "Log" +msgstr "لاگ" + +msgid "Events and bugs log" +msgstr "لاگ رویدادها و خطاها" + +msgid "Clean current log" +msgstr "پاک کردن لاگ جاری" + +msgid "Download log file" +msgstr "دانلود فایل لاگ" + +msgid "The log file was cleared." +msgstr "فایل لاگ پاک شد." + +msgid "Log file not found." +msgstr "فایل لاگ پیدا نشد." + +msgid "Update Products in Hesabix based on store" +msgstr "به روزرسانی محصولات در حسابیکس بر اساس فروشگاه" + +msgid "Update products in hesabix based on products definition in store." +msgstr "به روزرسانی محصولات در حسابیکس بر اساس مشخصات آنها در فروشگاه. محصولات جدید به حسابیکس اضافه می شوند و محصولات قبلی ویرایش می شوند." + +msgid "Update completed successfully." +msgstr "به روزرسانی با موفقیت انجام شد." + +msgid "Update completed successfully." +msgstr "به روزرسانی با موفقیت انجام شد." + +msgid "Update failed. Please check the log file." +msgstr "به روزرسانی ناموفق بود. لطفاً لاگ را بررسی کنید." + +msgid "Number of products in store:" +msgstr "تعداد محصولات در فروشگاه:" + +msgid "Number of products in hesabix:" +msgstr "تعداد محصولات در حسابیکس:" + +msgid "Number of linked products:" +msgstr "تعداد محصولات لینک شده:" + +msgid "Save and next page" +msgstr "ذخیره و صفحه بعد" + +msgid "Invoice in Hesabix" +msgstr "فاکتور حسابیکس" + +msgid "Submit Invoice" +msgstr "ثبت فاکتور" + +msgid "Submit Invoice in Hesabix" +msgstr "ثبت فاکتور در حسابیکس" + +msgid "Submit Product in Hesabix" +msgstr "ثبت محصول در حسابیکس" + +msgid "Do not submit product in Hesabix automatically by saving product in woocommerce" +msgstr "با ذخیره محصول در ووکامرس، محصول را بصورت اتوماتیک در حسابیکس ثبت نکن" + +msgid "Remove The Titles for Attributes When Saving Product To Hesabix" +msgstr "عنوان متغیر های یک محصول را با ذخیره/بروزرسانی در نام محصول حذف کن" + +msgid "Submit Price in Hesabix" +msgstr "ثبت قیمت در حسابیکس" + +msgid "Do not update product price in Hesabix by editing product in woocommerce" +msgstr "با ویرایش محصول در ووکامرس، قیمت محصول را در حسابیکس بروز نکن" + +msgid "Barcode in Hesabix" +msgstr "بارکد در حسابیکس" + +msgid "National Code in Hesabix" +msgstr "کد ملی در حسابیکس" + +msgid "Do not update product barcode in Hesabix by saving product in woocommerce" +msgstr "با ذخیره محصول در ووکامرس، بارکد محصول را در حسابیکس بروز نکن" + +msgid "Do not update product category in Hesabix by saving product in woocommerce" +msgstr "با ذخیره محصول در ووکامرس، دسته بندی محصول را در حسابیکس بروز نکن" + +msgid "Do not update product code in Hesabix by saving product in woocommerce" +msgstr "با ذخیره محصول در ووکامرس، کد محصول را در حسابیکس بروز نکن" + +msgid "Shipping method" +msgstr "روش حمل و نقل" + +msgid "Invoice's Salesman" +msgstr "فروشنده فاکتور" + +msgid "Invoice Salesman Percentage" +msgstr "درصد پورسانت فروشنده فاکتور" + +msgid "Invoice's Project" +msgstr "پروژه فاکتور" + +msgid "Submit Cash in Transit" +msgstr "ثبت در وجوه در راه" + +msgid "Submit Invoice Receipt Cash in Transit" +msgstr "ثبت رسید دریافت فاکتور در وجوه در راه" + +msgid "Default Invoice Transaction Fee Percentage" +msgstr "درصد کارمزد تراکنش به صورت پیش فرض" + +msgid "Plugin Tutorial Video" +msgstr "ویدیوی خودآموز افزونه" + +msgid "Titles" +msgstr "عناوین" + +msgid "Accounting quantity (Total inventory)" +msgstr "موجودی حسابداری (موجودی کل)" + +msgid "Cannot get warehouses." +msgstr "امکان دریافت اطلاعات انبارها نیست." + +msgid "Update product's quantity based on" +msgstr "بروزرسانی موجودی کالا بر اساس" + +msgid "Do not update purchase and sales titles in hesabix" +msgstr "توضیحات (عنوان های) خرید و فروش را در حسابیکس بروز نکن" + +msgid "Warehouse system is not active in Hesabix." +msgstr "سیستم انبارداری در حسابیکس فعال نیست." + +msgid "API Address" +msgstr "آدرس API" + +msgid "Contact Code in Hesabix" +msgstr "کد شخص در حسابیکس" + +msgid "" +"The contact code of this user in Hesabix, if you want to map this user " +"to a contact in Hesabix, enter the Contact code." +msgstr "" +"این فیلد کد شخص در حسابیکس است، اگر می‌خواهید این کاربر را به شخصی " +"در حسابیکس ارتباط دهید، کد شخص را وارد نمایید." + +msgid "" +"To check the phone with national code, " +"you need to enter both billing phone correctly." +msgstr "" +"این فیلد کد ملی شخص در حسابیکس است، اگر می‌خواهید شماره تماس با کد ملی چک شود " +"باید شماره تماس صورتحساب را به درستی وارد نمایید." + +msgid "Error: Select maximum 10 orders. Due to some limitations in Hesabix API, sending too many requests in one minute is not possible." +msgstr "خطا: حداکثر ۱۰ سفارش را انتخاب کنید. بدلیل محدودیت رابط برنامه نویسی حسابیکس، ارسال درخواست های زیاد در یک دقیقه امکان پذیر نیست." + +msgid "Selected orders invoices have been saved. Number of saved invoices: " +msgstr "فاکتور سفارش های انتخاب شده ثبت شد. تعداد فاکتور های ثبت شده: " + +msgid "Update sale price" +msgstr "بروزرسانی قیمت فروش ویژه" + +msgid "The Sale price does not change" +msgstr "قیمت فروش ویژه تغییر نکند" + +msgid "The Sale price gets removed" +msgstr "قیمت فروش ویژه حذف گردد" + +msgid "The sale price get changes in proportion to the regular price" +msgstr "قیمت فروش ویژه به تناسب قیمت اصلی تغییر یابد" + +msgid "Submit invoice base on Dokan orders" +msgstr "ثبت فاکتور بر اساس سفارشات افزونه دکان" + +msgid "Submit parent order" +msgstr "ثبت سفارش مادر" + +msgid "Submit children orders" +msgstr "ثبت زیر سفارش ها" + +msgid "Inactive" +msgstr "غیر فعال" + +#~ msgid "Sync completed, All products added/updated." +#~ msgstr "همسان‌سازی پایان یافت. تمامی محصولات به‌روزرسانی/افزوده شدند." + +#~ msgid "Sync completed, No product added/updated." +#~ msgstr "همسان‌سازی پایان یافت. هیچ محصولی به‌روزرسانی/افزوده شدند." + +#~ msgid "Sync completed; All hesabix changes synced successfully." +#~ msgstr "همسان‌سازی پایان یافت. تمامی تغییرات با حسابیکس همسان شد." + +#~ msgid "Sync completed; All products added/updated." +#~ msgstr "همسان‌سازی پایان یافت. تمامی محصولات به‌روزرسانی/افزوده شدند." + +#~ msgid "Sync completed; No product added/updated." +#~ msgstr "همسان‌سازی پایان یافت. هیچ محصولی به‌روزرسانی/افزوده شدند." + +#~ msgid "Export product completed. %s product added/updated." +#~ msgstr "استخراج پایان یافت. %s محصول به‌روزرسانی/افزوده شد." + +#~ msgid "Export customers completed. %s product added/updated." #~ msgstr "استخراج مشتریان پایان یافت. %s مشتری به‌روزرسانی/افزوده شد." \ No newline at end of file diff --git a/ssbhesabix.php b/ssbhesabix.php index 6bf68df..80aa705 100644 --- a/ssbhesabix.php +++ b/ssbhesabix.php @@ -1,73 +1,72 @@ -run(); -} - -run_ssbhesabix(); +run(); +} + +run_ssbhesabix(); diff --git a/uninstall.php b/uninstall.php index f9f4a2d..ee1d5f1 100644 --- a/uninstall.php +++ b/uninstall.php @@ -1,34 +1,33 @@ - - * @author HamidReza Gharahzadeh - * @author Sepehr Najafi - * @author Babak Alizadeh - * @since 1.0.0 - * - * @package ssbhesabix - */ - -// If uninstall not called from WordPress, then exit. -if (!defined( 'WP_UNINSTALL_PLUGIN')) { - exit; -} - -include_once(plugin_dir_path(__DIR__) . 'admin/services/HesabixLogService.php'); -require 'includes/class-ssbhesabix-api.php'; - -// delete tags in hesabix -$hesabixApi = new Ssbhesabix_Api(); -$result = $hesabixApi->fixClearTags(); -if (!$result->Success) { - HesabixLogService::log(array("ssbhesabix - Cannot clear tags. Error Message: " . (string)$result->ErrorMessage . ". Error Code: " . (string)$result->ErrorCode)); -} - -global $wpdb; -$options = $wpdb->get_results("SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '%ssbhesabix%'"); -foreach ($options as $option) { - delete_option($option->option_name); -} - -$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}ssbhesabix"); + + * @author HamidReza Gharahzadeh + * @author Sepehr Najafi + * @since 1.0.0 + * + * @package ssbhesabix + */ + +// If uninstall not called from WordPress, then exit. +if (!defined( 'WP_UNINSTALL_PLUGIN')) { + exit; +} + +include_once(plugin_dir_path(__DIR__) . 'admin/services/hesabixLogService.php'); +require 'includes/class-ssbhesabix-api.php'; + +// delete tags in hesabix +$hesabixApi = new Ssbhesabix_Api(); +$result = $hesabixApi->fixClearTags(); +if (!$result->Success) { + hesabixLogService::log(array("ssbhesabix - Cannot clear tags. Error Message: " . (string)$result->ErrorMessage . ". Error Code: " . (string)$result->ErrorCode)); +} + +global $wpdb; +$options = $wpdb->get_results("SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '%ssbhesabix%'"); +foreach ($options as $option) { + delete_option($option->option_name); +} + +$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}ssbhesabix");