diff --git a/django/attachments/templatetags/attachments_tags.py b/django/attachments/templatetags/attachments_tags.py
index b4baaa7..e5a8633 100644
--- a/django/attachments/templatetags/attachments_tags.py
+++ b/django/attachments/templatetags/attachments_tags.py
@@ -7,6 +7,12 @@ from ..views import add_url_for_obj
register = Library()
+@register.filter(name='endswith')
+def endswith(value, arg):
+ """Checks if the value ends with a certain string."""
+ if isinstance(value, str):
+ return value.endswith(arg)
+ return False
@register.inclusion_tag("attachments/add_form.html", takes_context=True)
def attachment_form(context, obj, **kwargs):
@@ -20,7 +26,7 @@ def attachment_form(context, obj, **kwargs):
return {
"form": AttachmentForm(),
"form_url": add_url_for_obj(obj),
- "next": kwargs.get("next", context.request.build_absolute_uri()),
+ "next": context.request.path,
}
else:
return {"form": None}
@@ -42,7 +48,7 @@ def attachment_delete_link(context, attachment, **kwargs):
and context["user"].has_perm("attachments.delete_attachment")
):
return {
- "next": kwargs.get("next", context.request.build_absolute_uri()),
+ "next": context.request.path,
"delete_url": reverse(
"attachments:delete", kwargs={"attachment_pk": attachment.pk}
),
diff --git a/django/labelbase/static/js/pdfobject.min.js b/django/labelbase/static/js/pdfobject.min.js
new file mode 100644
index 0000000..65cb28b
--- /dev/null
+++ b/django/labelbase/static/js/pdfobject.min.js
@@ -0,0 +1,9 @@
+/**
+ * PDFObject v2.3.0
+ * https://github.com/pipwerks/PDFObject
+ * @license
+ * Copyright (c) 2008-2024 Philip Hutchison
+ * MIT-style license: http://pipwerks.mit-license.org/
+ * UMD module pattern from https://github.com/umdjs/umd/blob/master/templates/returnExports.js
+ */
+!function(root,factory){"function"==typeof define&&define.amd?define([],factory):"object"==typeof module&&module.exports?module.exports=factory():root.PDFObject=factory()}(this,function(){"use strict";if("undefined"==typeof window||void 0===window.navigator||void 0===window.navigator.userAgent)return!1;let win=window,nav=win.navigator,ua=nav.userAgent,suppressConsole=!1,validateAX=function(type){var ax=null;try{ax=new ActiveXObject(type)}catch(e){ax=null}return!!ax},supportsPDFs=function(){if(void 0!==nav.platform&&"MacIntel"===nav.platform&&void 0!==nav.maxTouchPoints&&nav.maxTouchPoints>1||/Mobi|Tablet|Android|iPad|iPhone/.test(ua))return!1;let supportsPDFVE="boolean"==typeof nav.pdfViewerEnabled;return!(supportsPDFVE&&!nav.pdfViewerEnabled)&&(supportsPDFVE&&nav.pdfViewerEnabled||function(){let isChromium=void 0!==win.chrome,isSafari=void 0!==win.safari||void 0!==nav.vendor&&/Apple/.test(nav.vendor)&&/Safari/.test(ua),isFirefox=void 0!==win.Mozilla||/irefox/.test(ua);return isChromium||isSafari||isFirefox}()||"ActiveXObject"in win&&(validateAX("AcroPDF.PDF")||validateAX("PDF.PdfCtrl")))}(),embedError=function(msg){return suppressConsole||console.log("[PDFObject]",msg),!1},generatePDFObjectMarkup=function(embedType,targetNode,url,pdfOpenFragment,width,height,id,title,omitInlineStyles,customAttribute,PDFJS_URL){!function(node){for(;node.firstChild;)node.removeChild(node.firstChild)}(targetNode);let source=url;if("pdfjs"===embedType){source=PDFJS_URL+(-1!==PDFJS_URL.indexOf("?")?"&":"?")+"file="+encodeURIComponent(url)+pdfOpenFragment}else source+=pdfOpenFragment;let el=document.createElement("iframe");if(el.className="pdfobject",el.type="application/pdf",el.title=title,el.src=source,el.allow="fullscreen",el.frameborder="0",id&&(el.id=id),!omitInlineStyles){let style="border: none;";targetNode!==document.body?style+="width: "+width+"; height: "+height+";":style+="position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%;",el.style.cssText=style}return customAttribute&&customAttribute.key&&-1===["className","type","title","src","style","id","allow","frameborder"].indexOf(customAttribute.key)&&el.setAttribute(customAttribute.key,void 0!==customAttribute.value?customAttribute.value:""),targetNode.classList.add("pdfobject-container"),targetNode.appendChild(el),targetNode.getElementsByTagName("iframe")[0]},embed=function(url,targetSelector,options){let selector=targetSelector||!1,opt=options||{};suppressConsole="boolean"==typeof opt.suppressConsole&&opt.suppressConsole;let id="string"==typeof opt.id?opt.id:"",page=opt.page||!1,pdfOpenParams=opt.pdfOpenParams||{},fallbackLink="string"!=typeof opt.fallbackLink&&"boolean"!=typeof opt.fallbackLink||opt.fallbackLink,width=opt.width||"100%",height=opt.height||"100%",title=opt.title||"Embedded PDF",forcePDFJS="boolean"==typeof opt.forcePDFJS&&opt.forcePDFJS,omitInlineStyles="boolean"==typeof opt.omitInlineStyles&&opt.omitInlineStyles,PDFJS_URL=opt.PDFJS_URL||!1,targetNode=function(targetSelector){let targetNode=document.body;return"string"==typeof targetSelector?targetNode=document.querySelector(targetSelector):void 0!==win.jQuery&&targetSelector instanceof jQuery&&targetSelector.length?targetNode=targetSelector.get(0):void 0!==targetSelector.nodeType&&1===targetSelector.nodeType&&(targetNode=targetSelector),targetNode}(selector),pdfOpenFragment="",customAttribute=opt.customAttribute||{},fallbackHTML_default="
This browser does not support inline PDFs. Please download the PDF to view it: [pdflink]
";if("string"!=typeof url)return embedError("URL is not valid");if(!targetNode)return embedError("Target element cannot be determined");if(page&&(pdfOpenParams.page=page),pdfOpenFragment=function(pdfParams){let prop,string="",paramArray=[],fdf="";if((pdfParams.comment||pdfParams.viewrect||pdfParams.highlight)&&(pdfParams.page||(pdfParams.page=1,embedError("The comment, viewrect, and highlight parameters require a page parameter, but none was specified. Defaulting to page 1."))),pdfParams.page&&(paramArray.push("page="+encodeURIComponent(pdfParams.page)),delete pdfParams.page),pdfParams.fdf&&(fdf=pdfParams.fdf,delete pdfParams.fdf),pdfParams){for(prop in pdfParams)pdfParams.hasOwnProperty(prop)&¶mArray.push(encodeURIComponent(prop)+"="+encodeURIComponent(pdfParams[prop]));fdf&¶mArray.push("fdf="+encodeURIComponent(fdf)),(string=paramArray.join("&"))&&(string="#"+string)}return string}(pdfOpenParams),forcePDFJS&&PDFJS_URL)return generatePDFObjectMarkup("pdfjs",targetNode,url,pdfOpenFragment,width,height,id,title,omitInlineStyles,customAttribute,PDFJS_URL);if(supportsPDFs)return generatePDFObjectMarkup("iframe",targetNode,url,pdfOpenFragment,width,height,id,title,omitInlineStyles,customAttribute);if(PDFJS_URL)return generatePDFObjectMarkup("pdfjs",targetNode,url,pdfOpenFragment,width,height,id,title,omitInlineStyles,customAttribute,PDFJS_URL);if(fallbackLink)if("string"==typeof fallbackLink)targetNode.innerHTML=fallbackLink.replace(/\[url\]/g,url);else if(-1!==url.indexOf("data:application/pdf;base64"))!function(b64,filename,targetNode,fallbackHTML){if(window.Blob&&window.URL&&window.URL.createObjectURL){var xhr=new XMLHttpRequest;xhr.open("GET",b64,!0),xhr.responseType="blob",xhr.onload=function(){if(200===xhr.status){var blob=xhr.response,link=document.createElement("a");link.innerText="Download PDF",link.href=URL.createObjectURL(blob),link.setAttribute("download",filename),targetNode.innerHTML=fallbackHTML.replace(/\[pdflink\]/g,link.outerHTML)}},xhr.send()}}(url,"file.pdf",targetNode,fallbackHTML_default);else{let link="Download PDF";targetNode.innerHTML=fallbackHTML_default.replace(/\[pdflink\]/g,link)}return embedError("This browser does not support embedded PDFs")};return{embed:function(a,b,c){return embed(a,b,c)},pdfobjectversion:"2.3.0",supportsPDFs:supportsPDFs}});
\ No newline at end of file
diff --git a/django/labelbase/static/lightbox/css/lightbox.css b/django/labelbase/static/lightbox/css/lightbox.css
new file mode 100644
index 0000000..b3b0beb
--- /dev/null
+++ b/django/labelbase/static/lightbox/css/lightbox.css
@@ -0,0 +1,204 @@
+body.lb-disable-scrolling {
+ overflow: hidden;
+}
+
+.lightboxOverlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 9999;
+ background-color: black;
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
+ opacity: 0.8;
+ display: none;
+}
+
+.lightbox {
+ position: absolute;
+ left: 0;
+ width: 100%;
+ z-index: 10000;
+ text-align: center;
+ line-height: 0;
+ font-weight: normal;
+ outline: none;
+}
+
+.lightbox .lb-image {
+ display: block;
+ height: auto;
+ max-width: inherit;
+ max-height: none;
+ border-radius: 3px;
+
+ /* Image border */
+ border: 4px solid white;
+}
+
+.lightbox a img {
+ border: none;
+}
+
+.lb-outerContainer {
+ position: relative;
+ *zoom: 1;
+ width: 250px;
+ height: 250px;
+ margin: 0 auto;
+ border-radius: 4px;
+
+ /* Background color behind image.
+ This is visible during transitions. */
+ background-color: white;
+}
+
+.lb-outerContainer:after {
+ content: "";
+ display: table;
+ clear: both;
+}
+
+.lb-loader {
+ position: absolute;
+ top: 43%;
+ left: 0;
+ height: 25%;
+ width: 100%;
+ text-align: center;
+ line-height: 0;
+}
+
+.lb-cancel {
+ display: block;
+ width: 32px;
+ height: 32px;
+ margin: 0 auto;
+ background: url(../images/loading.gif) no-repeat;
+}
+
+.lb-nav {
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 100%;
+ width: 100%;
+ z-index: 10;
+}
+
+.lb-container > .nav {
+ left: 0;
+}
+
+.lb-nav a {
+ outline: none;
+ background-image: url('data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==');
+}
+
+.lb-prev, .lb-next {
+ height: 100%;
+ cursor: pointer;
+ display: block;
+}
+
+.lb-nav a.lb-prev {
+ width: 34%;
+ left: 0;
+ float: left;
+ background: url(../images/prev.png) left 48% no-repeat;
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
+ opacity: 0;
+ -webkit-transition: opacity 0.6s;
+ -moz-transition: opacity 0.6s;
+ -o-transition: opacity 0.6s;
+ transition: opacity 0.6s;
+}
+
+.lb-nav a.lb-prev:hover {
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
+ opacity: 1;
+}
+
+.lb-nav a.lb-next {
+ width: 64%;
+ right: 0;
+ float: right;
+ background: url(../images/next.png) right 48% no-repeat;
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
+ opacity: 0;
+ -webkit-transition: opacity 0.6s;
+ -moz-transition: opacity 0.6s;
+ -o-transition: opacity 0.6s;
+ transition: opacity 0.6s;
+}
+
+.lb-nav a.lb-next:hover {
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
+ opacity: 1;
+}
+
+.lb-dataContainer {
+ margin: 0 auto;
+ padding-top: 5px;
+ *zoom: 1;
+ width: 100%;
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+}
+
+.lb-dataContainer:after {
+ content: "";
+ display: table;
+ clear: both;
+}
+
+.lb-data {
+ padding: 0 4px;
+ color: #ccc;
+}
+
+.lb-data .lb-details {
+ width: 85%;
+ float: left;
+ text-align: left;
+ line-height: 1.1em;
+}
+
+.lb-data .lb-caption {
+ font-size: 13px;
+ font-weight: bold;
+ line-height: 1em;
+}
+
+.lb-data .lb-caption a {
+ color: #4ae;
+}
+
+.lb-data .lb-number {
+ display: block;
+ clear: left;
+ padding-bottom: 1em;
+ font-size: 12px;
+ color: #999999;
+}
+
+.lb-data .lb-close {
+ display: block;
+ float: right;
+ width: 30px;
+ height: 30px;
+ background: url(../images/close.png) top right no-repeat;
+ text-align: right;
+ outline: none;
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70);
+ opacity: 0.7;
+ -webkit-transition: opacity 0.2s;
+ -moz-transition: opacity 0.2s;
+ -o-transition: opacity 0.2s;
+ transition: opacity 0.2s;
+}
+
+.lb-data .lb-close:hover {
+ cursor: pointer;
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
+ opacity: 1;
+}
diff --git a/django/labelbase/static/lightbox/css/lightbox.min.css b/django/labelbase/static/lightbox/css/lightbox.min.css
new file mode 100644
index 0000000..adbaa83
--- /dev/null
+++ b/django/labelbase/static/lightbox/css/lightbox.min.css
@@ -0,0 +1 @@
+.lb-loader,.lightbox{text-align:center;line-height:0;position:absolute;left:0}body.lb-disable-scrolling{overflow:hidden}.lightboxOverlay{position:absolute;top:0;left:0;z-index:9999;background-color:#000;filter:alpha(Opacity=80);opacity:.8;display:none}.lightbox{width:100%;z-index:10000;font-weight:400;outline:0}.lightbox .lb-image{display:block;height:auto;max-width:inherit;max-height:none;border-radius:3px;border:4px solid #fff}.lightbox a img{border:none}.lb-outerContainer{position:relative;width:250px;height:250px;margin:0 auto;border-radius:4px;background-color:#fff}.lb-outerContainer:after{content:"";display:table;clear:both}.lb-loader{top:43%;height:25%;width:100%}.lb-cancel{display:block;width:32px;height:32px;margin:0 auto;background:url(../images/loading.gif) no-repeat}.lb-nav{position:absolute;top:0;left:0;height:100%;width:100%;z-index:10}.lb-container>.nav{left:0}.lb-nav a{outline:0;background-image:url(data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==)}.lb-next,.lb-prev{height:100%;cursor:pointer;display:block}.lb-nav a.lb-prev{width:34%;left:0;float:left;background:url(../images/prev.png) left 48% no-repeat;filter:alpha(Opacity=0);opacity:0;-webkit-transition:opacity .6s;-moz-transition:opacity .6s;-o-transition:opacity .6s;transition:opacity .6s}.lb-nav a.lb-prev:hover{filter:alpha(Opacity=100);opacity:1}.lb-nav a.lb-next{width:64%;right:0;float:right;background:url(../images/next.png) right 48% no-repeat;filter:alpha(Opacity=0);opacity:0;-webkit-transition:opacity .6s;-moz-transition:opacity .6s;-o-transition:opacity .6s;transition:opacity .6s}.lb-nav a.lb-next:hover{filter:alpha(Opacity=100);opacity:1}.lb-dataContainer{margin:0 auto;padding-top:5px;width:100%;border-bottom-left-radius:4px;border-bottom-right-radius:4px}.lb-dataContainer:after{content:"";display:table;clear:both}.lb-data{padding:0 4px;color:#ccc}.lb-data .lb-details{width:85%;float:left;text-align:left;line-height:1.1em}.lb-data .lb-caption{font-size:13px;font-weight:700;line-height:1em}.lb-data .lb-caption a{color:#4ae}.lb-data .lb-number{display:block;clear:left;padding-bottom:1em;font-size:12px;color:#999}.lb-data .lb-close{display:block;float:right;width:30px;height:30px;background:url(../images/close.png) top right no-repeat;text-align:right;outline:0;filter:alpha(Opacity=70);opacity:.7;-webkit-transition:opacity .2s;-moz-transition:opacity .2s;-o-transition:opacity .2s;transition:opacity .2s}.lb-data .lb-close:hover{cursor:pointer;filter:alpha(Opacity=100);opacity:1}
\ No newline at end of file
diff --git a/django/labelbase/static/lightbox/images/close.png b/django/labelbase/static/lightbox/images/close.png
new file mode 100644
index 0000000..20baa1d
Binary files /dev/null and b/django/labelbase/static/lightbox/images/close.png differ
diff --git a/django/labelbase/static/lightbox/images/loading.gif b/django/labelbase/static/lightbox/images/loading.gif
new file mode 100644
index 0000000..5087c2a
Binary files /dev/null and b/django/labelbase/static/lightbox/images/loading.gif differ
diff --git a/django/labelbase/static/lightbox/images/next.png b/django/labelbase/static/lightbox/images/next.png
new file mode 100644
index 0000000..08365ac
Binary files /dev/null and b/django/labelbase/static/lightbox/images/next.png differ
diff --git a/django/labelbase/static/lightbox/images/prev.png b/django/labelbase/static/lightbox/images/prev.png
new file mode 100644
index 0000000..329fa98
Binary files /dev/null and b/django/labelbase/static/lightbox/images/prev.png differ
diff --git a/django/labelbase/static/lightbox/js/lightbox-plus-jquery.js b/django/labelbase/static/lightbox/js/lightbox-plus-jquery.js
new file mode 100644
index 0000000..077520b
--- /dev/null
+++ b/django/labelbase/static/lightbox/js/lightbox-plus-jquery.js
@@ -0,0 +1,11565 @@
+/*!
+ * jQuery JavaScript Library v3.6.3
+ * https://jquery.com/
+ *
+ * Includes Sizzle.js
+ * https://sizzlejs.com/
+ *
+ * Copyright OpenJS Foundation and other contributors
+ * Released under the MIT license
+ * https://jquery.org/license
+ *
+ * Date: 2022-12-20T21:28Z
+ */
+( function( global, factory ) {
+
+ "use strict";
+
+ if ( typeof module === "object" && typeof module.exports === "object" ) {
+
+ // For CommonJS and CommonJS-like environments where a proper `window`
+ // is present, execute the factory and get jQuery.
+ // For environments that do not have a `window` with a `document`
+ // (such as Node.js), expose a factory as module.exports.
+ // This accentuates the need for the creation of a real `window`.
+ // e.g. var jQuery = require("jquery")(window);
+ // See ticket trac-14549 for more info.
+ module.exports = global.document ?
+ factory( global, true ) :
+ function( w ) {
+ if ( !w.document ) {
+ throw new Error( "jQuery requires a window with a document" );
+ }
+ return factory( w );
+ };
+ } else {
+ factory( global );
+ }
+
+// Pass this if window is not defined yet
+} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+
+// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
+// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
+// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
+// enough that all such attempts are guarded in a try block.
+"use strict";
+
+var arr = [];
+
+var getProto = Object.getPrototypeOf;
+
+var slice = arr.slice;
+
+var flat = arr.flat ? function( array ) {
+ return arr.flat.call( array );
+} : function( array ) {
+ return arr.concat.apply( [], array );
+};
+
+
+var push = arr.push;
+
+var indexOf = arr.indexOf;
+
+var class2type = {};
+
+var toString = class2type.toString;
+
+var hasOwn = class2type.hasOwnProperty;
+
+var fnToString = hasOwn.toString;
+
+var ObjectFunctionString = fnToString.call( Object );
+
+var support = {};
+
+var isFunction = function isFunction( obj ) {
+
+ // Support: Chrome <=57, Firefox <=52
+ // In some browsers, typeof returns "function" for HTML