udata 6.1.6.dev25761__py2.py3-none-any.whl → 6.1.7__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of udata might be problematic. Click here for more details.

Files changed (64) hide show
  1. udata/__init__.py +1 -1
  2. udata/core/dataset/api_fields.py +20 -2
  3. udata/core/dataset/apiv2.py +8 -2
  4. udata/core/dataset/csv.py +1 -0
  5. udata/core/dataset/models.py +14 -0
  6. udata/core/dataset/rdf.py +3 -3
  7. udata/core/dataset/search.py +6 -2
  8. udata/core/discussions/api.py +4 -1
  9. udata/core/discussions/tasks.py +2 -2
  10. udata/core/organization/api_fields.py +1 -0
  11. udata/core/organization/forms.py +28 -0
  12. udata/core/organization/models.py +3 -0
  13. udata/core/topic/api.py +1 -0
  14. udata/core/topic/forms.py +1 -0
  15. udata/core/topic/models.py +20 -0
  16. udata/harvest/backends/dcat.py +10 -1
  17. udata/harvest/tests/test_dcat_backend.py +26 -1
  18. udata/models/slug_fields.py +4 -0
  19. udata/search/commands.py +8 -2
  20. udata/settings.py +7 -0
  21. udata/static/admin.js +19 -19
  22. udata/static/admin.js.map +1 -1
  23. udata/static/chunks/{1.01e4e2be1923d2ac99ae.js → 1.2a80f2805f0ad61574e4.js} +2 -2
  24. udata/static/chunks/1.2a80f2805f0ad61574e4.js.map +1 -0
  25. udata/static/chunks/{29.8a0027454d42f6c5ed8b.js → 29.7b551c87d15f96f30b57.js} +2 -2
  26. udata/static/chunks/29.7b551c87d15f96f30b57.js.map +1 -0
  27. udata/static/common.js +1 -1
  28. udata/static/common.js.map +1 -1
  29. udata/templates/macros/metadata.html +3 -0
  30. udata/templates/mail/badge_added_certified.html +1 -1
  31. udata/templates/mail/badge_added_public_service.html +1 -1
  32. udata/templates/mail/discussion_closed.html +1 -1
  33. udata/templates/mail/membership_request.html +1 -1
  34. udata/templates/mail/new_discussion.html +1 -1
  35. udata/templates/mail/new_discussion_comment.html +1 -1
  36. udata/templates/mail/user_mail_card.html +1 -1
  37. udata/tests/api/test_datasets_api.py +9 -1
  38. udata/tests/api/test_organizations_api.py +36 -2
  39. udata/tests/api/test_topics_api.py +1 -0
  40. udata/tests/frontend/test_markdown.py +15 -0
  41. udata/tests/test_discussions.py +80 -1
  42. udata/tests/test_model.py +18 -0
  43. udata/tests/test_topics.py +34 -0
  44. udata/translations/ar/LC_MESSAGES/udata.mo +0 -0
  45. udata/translations/ar/LC_MESSAGES/udata.po +37 -14
  46. udata/translations/es/LC_MESSAGES/udata.mo +0 -0
  47. udata/translations/es/LC_MESSAGES/udata.po +37 -14
  48. udata/translations/fr/LC_MESSAGES/udata.mo +0 -0
  49. udata/translations/fr/LC_MESSAGES/udata.po +37 -14
  50. udata/translations/it/LC_MESSAGES/udata.mo +0 -0
  51. udata/translations/it/LC_MESSAGES/udata.po +37 -14
  52. udata/translations/pt/LC_MESSAGES/udata.mo +0 -0
  53. udata/translations/pt/LC_MESSAGES/udata.po +37 -14
  54. udata/translations/sr/LC_MESSAGES/udata.mo +0 -0
  55. udata/translations/sr/LC_MESSAGES/udata.po +37 -14
  56. udata/translations/udata.pot +38 -15
  57. {udata-6.1.6.dev25761.dist-info → udata-6.1.7.dist-info}/METADATA +108 -95
  58. {udata-6.1.6.dev25761.dist-info → udata-6.1.7.dist-info}/RECORD +62 -61
  59. {udata-6.1.6.dev25761.dist-info → udata-6.1.7.dist-info}/WHEEL +1 -1
  60. udata/static/chunks/1.01e4e2be1923d2ac99ae.js.map +0 -1
  61. udata/static/chunks/29.8a0027454d42f6c5ed8b.js.map +0 -1
  62. {udata-6.1.6.dev25761.dist-info → udata-6.1.7.dist-info}/LICENSE +0 -0
  63. {udata-6.1.6.dev25761.dist-info → udata-6.1.7.dist-info}/entry_points.txt +0 -0
  64. {udata-6.1.6.dev25761.dist-info → udata-6.1.7.dist-info}/top_level.txt +0 -0
udata/static/common.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(e){function __webpack_require__(a){if(c[a])return c[a].exports;var f=c[a]={exports:{},id:a,loaded:!1};return e[a].call(f.exports,f,f.exports,__webpack_require__),f.loaded=!0,f.exports}var a=window.webpackJsonp;window.webpackJsonp=function(d,r){for(var b,t,_=0,n=[];_<d.length;_++)t=d[_],f[t]&&n.push.apply(n,f[t]),f[t]=0;for(b in r){var i=r[b];switch(typeof i){case"object":e[b]=function(a){var c=a.slice(1),f=a[0];return function(a,d,r){e[f].apply(this,[a,d,r].concat(c))}}(i);break;case"function":e[b]=i;break;default:e[b]=e[i]}}for(a&&a(d,r);n.length;)n.shift().call(null,__webpack_require__);if(r[0])return c[0]=0,__webpack_require__(0)};var c={},f={31:0};__webpack_require__.e=function(e,a){if(0===f[e])return a.call(null,__webpack_require__);if(void 0!==f[e])f[e].push(a);else{f[e]=[a];var c=document.getElementsByTagName("head")[0],d=document.createElement("script");d.type="text/javascript",d.charset="utf-8",d.async=!0,d.src=__webpack_require__.p+"chunks/"+e+"."+{0:"8eba31c7f8a4ba12d4f0",1:"01e4e2be1923d2ac99ae",2:"59edbaad3880b6989c03",3:"6b5640aaff12ceffed87",4:"ed0dea34413819390369",5:"39b82edb6afe71dfedda",6:"ac8a1d796320ea629a59",7:"fb1459b24b9370665f21",8:"ec9a022a808be725e418",9:"0ef49ae8d4cf283485fe",10:"f926dfd3ae7bf509ed4d",11:"1bab5dc273b4da2698da",12:"c9594fbeb5ec5f229448",13:"38196494b8fb921ef789",14:"f0598bceb83dddc07533",15:"e0e4d618ade824e9a054",16:"b6fdeda4b76dee9ff900",17:"ce9c798872e477e8d4da",18:"d1b82d6f8b5b291756cd",19:"ef0f0973698915a3b177",20:"23546befdf1e2f39820a",21:"c1564e20eb7fe23c3281",22:"13afd6a9ea6860e80603",23:"0e676fbff05e4c36acfc",24:"2a6267d518280dc5b69c",25:"ae4d92b7f22c0664a733",26:"074d8c1b6c13e9884fd9",27:"67c3fd17c23014c44845",28:"f2744e598de4330d8956",29:"8a0027454d42f6c5ed8b",30:"e446df9cf9dff85de9b8",32:"ad76e5c4345dd9d4dbfd",33:"b8bc582459a84b047503"}[e]+".js",c.appendChild(d)}},__webpack_require__.m=e,__webpack_require__.c=c,__webpack_require__.p="/static/"}(function(e){for(var a in e)if(Object.prototype.hasOwnProperty.call(e,a))switch(typeof e[a]){case"function":break;case"object":e[a]=function(a){var c=a.slice(1),f=e[a[0]];return function(e,a,d){f.apply(this,[e,a,d].concat(c))}}(e[a]);break;default:e[a]=e[e[a]]}return e}([]));
1
+ !function(e){function __webpack_require__(a){if(c[a])return c[a].exports;var f=c[a]={exports:{},id:a,loaded:!1};return e[a].call(f.exports,f,f.exports,__webpack_require__),f.loaded=!0,f.exports}var a=window.webpackJsonp;window.webpackJsonp=function(r,d){for(var b,t,_=0,n=[];_<r.length;_++)t=r[_],f[t]&&n.push.apply(n,f[t]),f[t]=0;for(b in d){var i=d[b];switch(typeof i){case"object":e[b]=function(a){var c=a.slice(1),f=a[0];return function(a,r,d){e[f].apply(this,[a,r,d].concat(c))}}(i);break;case"function":e[b]=i;break;default:e[b]=e[i]}}for(a&&a(r,d);n.length;)n.shift().call(null,__webpack_require__);if(d[0])return c[0]=0,__webpack_require__(0)};var c={},f={31:0};__webpack_require__.e=function(e,a){if(0===f[e])return a.call(null,__webpack_require__);if(void 0!==f[e])f[e].push(a);else{f[e]=[a];var c=document.getElementsByTagName("head")[0],r=document.createElement("script");r.type="text/javascript",r.charset="utf-8",r.async=!0,r.src=__webpack_require__.p+"chunks/"+e+"."+{0:"8eba31c7f8a4ba12d4f0",1:"2a80f2805f0ad61574e4",2:"59edbaad3880b6989c03",3:"6b5640aaff12ceffed87",4:"ed0dea34413819390369",5:"39b82edb6afe71dfedda",6:"ac8a1d796320ea629a59",7:"fb1459b24b9370665f21",8:"ec9a022a808be725e418",9:"0ef49ae8d4cf283485fe",10:"f926dfd3ae7bf509ed4d",11:"1bab5dc273b4da2698da",12:"c9594fbeb5ec5f229448",13:"38196494b8fb921ef789",14:"f0598bceb83dddc07533",15:"e0e4d618ade824e9a054",16:"b6fdeda4b76dee9ff900",17:"ce9c798872e477e8d4da",18:"d1b82d6f8b5b291756cd",19:"ef0f0973698915a3b177",20:"23546befdf1e2f39820a",21:"c1564e20eb7fe23c3281",22:"13afd6a9ea6860e80603",23:"0e676fbff05e4c36acfc",24:"2a6267d518280dc5b69c",25:"ae4d92b7f22c0664a733",26:"074d8c1b6c13e9884fd9",27:"67c3fd17c23014c44845",28:"f2744e598de4330d8956",29:"7b551c87d15f96f30b57",30:"e446df9cf9dff85de9b8",32:"1055ccb8662c0b6827f8",33:"b8bc582459a84b047503"}[e]+".js",c.appendChild(r)}},__webpack_require__.m=e,__webpack_require__.c=c,__webpack_require__.p="/static/"}(function(e){for(var a in e)if(Object.prototype.hasOwnProperty.call(e,a))switch(typeof e[a]){case"function":break;case"object":e[a]=function(a){var c=a.slice(1),f=e[a[0]];return function(e,a,r){f.apply(this,[e,a,r].concat(c))}}(e[a]);break;default:e[a]=e[e[a]]}return e}([]));
2
2
  //# sourceMappingURL=common.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["webpack:///common.js","webpack:///webpack/bootstrap bbb8502dfe673c668795"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","id","loaded","call","parentJsonpFunction","window","chunkIds","moreModules","chunkId","i","callbacks","length","installedChunks","push","apply","_m","args","slice","templateId","a","b","c","this","concat","shift","31","e","callback","undefined","head","document","getElementsByTagName","script","createElement","type","charset","async","src","p","0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","32","33","appendChild","m","Object","prototype","hasOwnProperty","fn"],"mappings":"CAAS,SAAUA,GCwDnB,QAAAC,qBAAAC,GAGA,GAAAC,EAAAD,GACA,MAAAC,GAAAD,GAAAE,OAGA,IAAAC,GAAAF,EAAAD,IACAE,WACAE,GAAAJ,EACAK,QAAA,EAUA,OANAP,GAAAE,GAAAM,KAAAH,EAAAD,QAAAC,IAAAD,QAAAH,qBAGAI,EAAAE,QAAA,EAGAF,EAAAD,QA3EA,GAAAK,GAAAC,OAAA,YACAA,QAAA,sBAAAC,EAAAC,GAIA,IADA,GAAAV,GAAAW,EAAAC,EAAA,EAAAC,KACQD,EAAAH,EAAAK,OAAoBF,IAC5BD,EAAAF,EAAAG,GACAG,EAAAJ,IACAE,EAAAG,KAAAC,MAAAJ,EAAAE,EAAAJ,IACAI,EAAAJ,GAAA,CAEA,KAAAX,IAAAU,GAAA,CACA,GAAAQ,GAAAR,EAAAV,EAGA,cAAAkB,IACA,aAEApB,EAAAE,GAAA,SAAAkB,GACA,GAAAC,GAAAD,EAAAE,MAAA,GAAAC,EAAAH,EAAA,EACA,iBAAAI,EAAAC,EAAAC,GACA1B,EAAAuB,GAAAJ,MAAAQ,MAAAH,EAAAC,EAAAC,GAAAE,OAAAP,MAEMD,EACN,MACA,gBAEApB,EAAAE,GAAAkB,CACA,MACA,SAEApB,EAAAE,GAAAF,EAAAoB,IAKA,IADAX,KAAAE,EAAAC,GACAG,EAAAC,QACAD,EAAAc,QAAArB,KAAA,KAAAP,oBACA,IAAAW,EAAA,GAEA,MADAT,GAAA,KACAF,oBAAA,GAKA,IAAAE,MAKAc,GACAa,GAAA,EA6BA7B,qBAAA8B,EAAA,SAAAlB,EAAAmB,GAEA,OAAAf,EAAAJ,GACA,MAAAmB,GAAAxB,KAAA,KAAAP,oBAGA,IAAAgC,SAAAhB,EAAAJ,GACAI,EAAAJ,GAAAK,KAAAc,OACI,CAEJf,EAAAJ,IAAAmB,EACA,IAAAE,GAAAC,SAAAC,qBAAA,WACAC,EAAAF,SAAAG,cAAA,SACAD,GAAAE,KAAA,kBACAF,EAAAG,QAAA,QACAH,EAAAI,OAAA,EAEAJ,EAAAK,IAAAzC,oBAAA0C,EAAA,UAAA9B,EAAA,KAAsE+B,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,wBAAk5B/D,GAAA,MACx9BqB,EAAA2C,YAAAxC,KAKApC,oBAAA6E,EAAA9E,EAGAC,oBAAAyB,EAAAvB,EAGAF,oBAAA0C,EAAA,YDIW,SAAS3C,GAEnB,IAAI,GAAIc,KAAKd,GACZ,GAAG+E,OAAOC,UAAUC,eAAezE,KAAKR,EAASc,GAChD,aAAcd,GAAQc,IACtB,IAAK,WAAY,KACjB,KAAK,SAEJd,EAAQc,GAAM,SAASM,GACtB,GAAIC,GAAOD,EAAGE,MAAM,GAAI4D,EAAKlF,EAAQoB,EAAG,GACxC,OAAO,UAAUI,EAAEC,EAAEC,GACpBwD,EAAG/D,MAAMQ,MAAOH,EAAEC,EAAEC,GAAGE,OAAOP,MAE9BrB,EAAQc,GACV,MACD,SAECd,EAAQc,GAAKd,EAAQA,EAAQc,IAKhC,MAAOd","file":"common.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// install a JSONP callback for chunk loading\n/******/ \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n/******/ \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules) {\n/******/ \t\t// add \"moreModules\" to the modules object,\n/******/ \t\t// then flag all \"chunkIds\" as loaded and fire callback\n/******/ \t\tvar moduleId, chunkId, i = 0, callbacks = [];\n/******/ \t\tfor(;i < chunkIds.length; i++) {\n/******/ \t\t\tchunkId = chunkIds[i];\n/******/ \t\t\tif(installedChunks[chunkId])\n/******/ \t\t\t\tcallbacks.push.apply(callbacks, installedChunks[chunkId]);\n/******/ \t\t\tinstalledChunks[chunkId] = 0;\n/******/ \t\t}\n/******/ \t\tfor(moduleId in moreModules) {\n/******/ \t\t\tvar _m = moreModules[moduleId];\n/******/\n/******/ \t\t\t// Check if module is deduplicated\n/******/ \t\t\tswitch(typeof _m) {\n/******/ \t\t\tcase \"object\":\n/******/ \t\t\t\t// Module can be created from a template\n/******/ \t\t\t\tmodules[moduleId] = (function(_m) {\n/******/ \t\t\t\t\tvar args = _m.slice(1), templateId = _m[0];\n/******/ \t\t\t\t\treturn function (a,b,c) {\n/******/ \t\t\t\t\t\tmodules[templateId].apply(this, [a,b,c].concat(args));\n/******/ \t\t\t\t\t};\n/******/ \t\t\t\t}(_m));\n/******/ \t\t\t\tbreak;\n/******/ \t\t\tcase \"function\":\n/******/ \t\t\t\t// Normal module\n/******/ \t\t\t\tmodules[moduleId] = _m;\n/******/ \t\t\t\tbreak;\n/******/ \t\t\tdefault:\n/******/ \t\t\t\t// Module is a copy of another module\n/******/ \t\t\t\tmodules[moduleId] = modules[_m];\n/******/ \t\t\t\tbreak;\n/******/ \t\t\t}\n/******/ \t\t}\n/******/ \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);\n/******/ \t\twhile(callbacks.length)\n/******/ \t\t\tcallbacks.shift().call(null, __webpack_require__);\n/******/ \t\tif(moreModules[0]) {\n/******/ \t\t\tinstalledModules[0] = 0;\n/******/ \t\t\treturn __webpack_require__(0);\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// object to store loaded and loading chunks\n/******/ \t// \"0\" means \"already loaded\"\n/******/ \t// Array means \"loading\", array contains callbacks\n/******/ \tvar installedChunks = {\n/******/ \t\t31:0\n/******/ \t};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/ \t// This file contains only the entry chunk.\n/******/ \t// The chunk loading function for additional chunks\n/******/ \t__webpack_require__.e = function requireEnsure(chunkId, callback) {\n/******/ \t\t// \"0\" is the signal for \"already loaded\"\n/******/ \t\tif(installedChunks[chunkId] === 0)\n/******/ \t\t\treturn callback.call(null, __webpack_require__);\n/******/\n/******/ \t\t// an array means \"currently loading\".\n/******/ \t\tif(installedChunks[chunkId] !== undefined) {\n/******/ \t\t\tinstalledChunks[chunkId].push(callback);\n/******/ \t\t} else {\n/******/ \t\t\t// start chunk loading\n/******/ \t\t\tinstalledChunks[chunkId] = [callback];\n/******/ \t\t\tvar head = document.getElementsByTagName('head')[0];\n/******/ \t\t\tvar script = document.createElement('script');\n/******/ \t\t\tscript.type = 'text/javascript';\n/******/ \t\t\tscript.charset = 'utf-8';\n/******/ \t\t\tscript.async = true;\n/******/\n/******/ \t\t\tscript.src = __webpack_require__.p + \"chunks/\" + chunkId + \".\" + {\"0\":\"8eba31c7f8a4ba12d4f0\",\"1\":\"01e4e2be1923d2ac99ae\",\"2\":\"59edbaad3880b6989c03\",\"3\":\"6b5640aaff12ceffed87\",\"4\":\"ed0dea34413819390369\",\"5\":\"39b82edb6afe71dfedda\",\"6\":\"ac8a1d796320ea629a59\",\"7\":\"fb1459b24b9370665f21\",\"8\":\"ec9a022a808be725e418\",\"9\":\"0ef49ae8d4cf283485fe\",\"10\":\"f926dfd3ae7bf509ed4d\",\"11\":\"1bab5dc273b4da2698da\",\"12\":\"c9594fbeb5ec5f229448\",\"13\":\"38196494b8fb921ef789\",\"14\":\"f0598bceb83dddc07533\",\"15\":\"e0e4d618ade824e9a054\",\"16\":\"b6fdeda4b76dee9ff900\",\"17\":\"ce9c798872e477e8d4da\",\"18\":\"d1b82d6f8b5b291756cd\",\"19\":\"ef0f0973698915a3b177\",\"20\":\"23546befdf1e2f39820a\",\"21\":\"c1564e20eb7fe23c3281\",\"22\":\"13afd6a9ea6860e80603\",\"23\":\"0e676fbff05e4c36acfc\",\"24\":\"2a6267d518280dc5b69c\",\"25\":\"ae4d92b7f22c0664a733\",\"26\":\"074d8c1b6c13e9884fd9\",\"27\":\"67c3fd17c23014c44845\",\"28\":\"f2744e598de4330d8956\",\"29\":\"8a0027454d42f6c5ed8b\",\"30\":\"e446df9cf9dff85de9b8\",\"32\":\"ad76e5c4345dd9d4dbfd\",\"33\":\"b8bc582459a84b047503\"}[chunkId] + \".js\";\n/******/ \t\t\thead.appendChild(script);\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"/static/\";\n/******/ })\n/************************************************************************/\n/******/ ((function(modules) {\n\t// Check all modules for deduplicated modules\n\tfor(var i in modules) {\n\t\tif(Object.prototype.hasOwnProperty.call(modules, i)) {\n\t\t\tswitch(typeof modules[i]) {\n\t\t\tcase \"function\": break;\n\t\t\tcase \"object\":\n\t\t\t\t// Module can be created from a template\n\t\t\t\tmodules[i] = (function(_m) {\n\t\t\t\t\tvar args = _m.slice(1), fn = modules[_m[0]];\n\t\t\t\t\treturn function (a,b,c) {\n\t\t\t\t\t\tfn.apply(this, [a,b,c].concat(args));\n\t\t\t\t\t};\n\t\t\t\t}(modules[i]));\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// Module is a copy of another module\n\t\t\t\tmodules[i] = modules[modules[i]];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn modules;\n}([])));\n\n\n/** WEBPACK FOOTER **\n ** common.js\n **/"," \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, callbacks = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId])\n \t\t\t\tcallbacks.push.apply(callbacks, installedChunks[chunkId]);\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tvar _m = moreModules[moduleId];\n\n \t\t\t// Check if module is deduplicated\n \t\t\tswitch(typeof _m) {\n \t\t\tcase \"object\":\n \t\t\t\t// Module can be created from a template\n \t\t\t\tmodules[moduleId] = (function(_m) {\n \t\t\t\t\tvar args = _m.slice(1), templateId = _m[0];\n \t\t\t\t\treturn function (a,b,c) {\n \t\t\t\t\t\tmodules[templateId].apply(this, [a,b,c].concat(args));\n \t\t\t\t\t};\n \t\t\t\t}(_m));\n \t\t\t\tbreak;\n \t\t\tcase \"function\":\n \t\t\t\t// Normal module\n \t\t\t\tmodules[moduleId] = _m;\n \t\t\t\tbreak;\n \t\t\tdefault:\n \t\t\t\t// Module is a copy of another module\n \t\t\t\tmodules[moduleId] = modules[_m];\n \t\t\t\tbreak;\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);\n \t\twhile(callbacks.length)\n \t\t\tcallbacks.shift().call(null, __webpack_require__);\n \t\tif(moreModules[0]) {\n \t\t\tinstalledModules[0] = 0;\n \t\t\treturn __webpack_require__(0);\n \t\t}\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// \"0\" means \"already loaded\"\n \t// Array means \"loading\", array contains callbacks\n \tvar installedChunks = {\n \t\t31:0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId, callback) {\n \t\t// \"0\" is the signal for \"already loaded\"\n \t\tif(installedChunks[chunkId] === 0)\n \t\t\treturn callback.call(null, __webpack_require__);\n\n \t\t// an array means \"currently loading\".\n \t\tif(installedChunks[chunkId] !== undefined) {\n \t\t\tinstalledChunks[chunkId].push(callback);\n \t\t} else {\n \t\t\t// start chunk loading\n \t\t\tinstalledChunks[chunkId] = [callback];\n \t\t\tvar head = document.getElementsByTagName('head')[0];\n \t\t\tvar script = document.createElement('script');\n \t\t\tscript.type = 'text/javascript';\n \t\t\tscript.charset = 'utf-8';\n \t\t\tscript.async = true;\n\n \t\t\tscript.src = __webpack_require__.p + \"chunks/\" + chunkId + \".\" + {\"0\":\"8eba31c7f8a4ba12d4f0\",\"1\":\"01e4e2be1923d2ac99ae\",\"2\":\"59edbaad3880b6989c03\",\"3\":\"6b5640aaff12ceffed87\",\"4\":\"ed0dea34413819390369\",\"5\":\"39b82edb6afe71dfedda\",\"6\":\"ac8a1d796320ea629a59\",\"7\":\"fb1459b24b9370665f21\",\"8\":\"ec9a022a808be725e418\",\"9\":\"0ef49ae8d4cf283485fe\",\"10\":\"f926dfd3ae7bf509ed4d\",\"11\":\"1bab5dc273b4da2698da\",\"12\":\"c9594fbeb5ec5f229448\",\"13\":\"38196494b8fb921ef789\",\"14\":\"f0598bceb83dddc07533\",\"15\":\"e0e4d618ade824e9a054\",\"16\":\"b6fdeda4b76dee9ff900\",\"17\":\"ce9c798872e477e8d4da\",\"18\":\"d1b82d6f8b5b291756cd\",\"19\":\"ef0f0973698915a3b177\",\"20\":\"23546befdf1e2f39820a\",\"21\":\"c1564e20eb7fe23c3281\",\"22\":\"13afd6a9ea6860e80603\",\"23\":\"0e676fbff05e4c36acfc\",\"24\":\"2a6267d518280dc5b69c\",\"25\":\"ae4d92b7f22c0664a733\",\"26\":\"074d8c1b6c13e9884fd9\",\"27\":\"67c3fd17c23014c44845\",\"28\":\"f2744e598de4330d8956\",\"29\":\"8a0027454d42f6c5ed8b\",\"30\":\"e446df9cf9dff85de9b8\",\"32\":\"ad76e5c4345dd9d4dbfd\",\"33\":\"b8bc582459a84b047503\"}[chunkId] + \".js\";\n \t\t\thead.appendChild(script);\n \t\t}\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/static/\";\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap bbb8502dfe673c668795\n **/"],"sourceRoot":""}
1
+ {"version":3,"sources":["webpack:///common.js","webpack:///webpack/bootstrap 3ed3ae50839df38675d6"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","id","loaded","call","parentJsonpFunction","window","chunkIds","moreModules","chunkId","i","callbacks","length","installedChunks","push","apply","_m","args","slice","templateId","a","b","c","this","concat","shift","31","e","callback","undefined","head","document","getElementsByTagName","script","createElement","type","charset","async","src","p","0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","32","33","appendChild","m","Object","prototype","hasOwnProperty","fn"],"mappings":"CAAS,SAAUA,GCwDnB,QAAAC,qBAAAC,GAGA,GAAAC,EAAAD,GACA,MAAAC,GAAAD,GAAAE,OAGA,IAAAC,GAAAF,EAAAD,IACAE,WACAE,GAAAJ,EACAK,QAAA,EAUA,OANAP,GAAAE,GAAAM,KAAAH,EAAAD,QAAAC,IAAAD,QAAAH,qBAGAI,EAAAE,QAAA,EAGAF,EAAAD,QA3EA,GAAAK,GAAAC,OAAA,YACAA,QAAA,sBAAAC,EAAAC,GAIA,IADA,GAAAV,GAAAW,EAAAC,EAAA,EAAAC,KACQD,EAAAH,EAAAK,OAAoBF,IAC5BD,EAAAF,EAAAG,GACAG,EAAAJ,IACAE,EAAAG,KAAAC,MAAAJ,EAAAE,EAAAJ,IACAI,EAAAJ,GAAA,CAEA,KAAAX,IAAAU,GAAA,CACA,GAAAQ,GAAAR,EAAAV,EAGA,cAAAkB,IACA,aAEApB,EAAAE,GAAA,SAAAkB,GACA,GAAAC,GAAAD,EAAAE,MAAA,GAAAC,EAAAH,EAAA,EACA,iBAAAI,EAAAC,EAAAC,GACA1B,EAAAuB,GAAAJ,MAAAQ,MAAAH,EAAAC,EAAAC,GAAAE,OAAAP,MAEMD,EACN,MACA,gBAEApB,EAAAE,GAAAkB,CACA,MACA,SAEApB,EAAAE,GAAAF,EAAAoB,IAKA,IADAX,KAAAE,EAAAC,GACAG,EAAAC,QACAD,EAAAc,QAAArB,KAAA,KAAAP,oBACA,IAAAW,EAAA,GAEA,MADAT,GAAA,KACAF,oBAAA,GAKA,IAAAE,MAKAc,GACAa,GAAA,EA6BA7B,qBAAA8B,EAAA,SAAAlB,EAAAmB,GAEA,OAAAf,EAAAJ,GACA,MAAAmB,GAAAxB,KAAA,KAAAP,oBAGA,IAAAgC,SAAAhB,EAAAJ,GACAI,EAAAJ,GAAAK,KAAAc,OACI,CAEJf,EAAAJ,IAAAmB,EACA,IAAAE,GAAAC,SAAAC,qBAAA,WACAC,EAAAF,SAAAG,cAAA,SACAD,GAAAE,KAAA,kBACAF,EAAAG,QAAA,QACAH,EAAAI,OAAA,EAEAJ,EAAAK,IAAAzC,oBAAA0C,EAAA,UAAA9B,EAAA,KAAsE+B,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,wBAAk5B/D,GAAA,MACx9BqB,EAAA2C,YAAAxC,KAKApC,oBAAA6E,EAAA9E,EAGAC,oBAAAyB,EAAAvB,EAGAF,oBAAA0C,EAAA,YDIW,SAAS3C,GAEnB,IAAI,GAAIc,KAAKd,GACZ,GAAG+E,OAAOC,UAAUC,eAAezE,KAAKR,EAASc,GAChD,aAAcd,GAAQc,IACtB,IAAK,WAAY,KACjB,KAAK,SAEJd,EAAQc,GAAM,SAASM,GACtB,GAAIC,GAAOD,EAAGE,MAAM,GAAI4D,EAAKlF,EAAQoB,EAAG,GACxC,OAAO,UAAUI,EAAEC,EAAEC,GACpBwD,EAAG/D,MAAMQ,MAAOH,EAAEC,EAAEC,GAAGE,OAAOP,MAE9BrB,EAAQc,GACV,MACD,SAECd,EAAQc,GAAKd,EAAQA,EAAQc,IAKhC,MAAOd","file":"common.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// install a JSONP callback for chunk loading\n/******/ \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n/******/ \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules) {\n/******/ \t\t// add \"moreModules\" to the modules object,\n/******/ \t\t// then flag all \"chunkIds\" as loaded and fire callback\n/******/ \t\tvar moduleId, chunkId, i = 0, callbacks = [];\n/******/ \t\tfor(;i < chunkIds.length; i++) {\n/******/ \t\t\tchunkId = chunkIds[i];\n/******/ \t\t\tif(installedChunks[chunkId])\n/******/ \t\t\t\tcallbacks.push.apply(callbacks, installedChunks[chunkId]);\n/******/ \t\t\tinstalledChunks[chunkId] = 0;\n/******/ \t\t}\n/******/ \t\tfor(moduleId in moreModules) {\n/******/ \t\t\tvar _m = moreModules[moduleId];\n/******/\n/******/ \t\t\t// Check if module is deduplicated\n/******/ \t\t\tswitch(typeof _m) {\n/******/ \t\t\tcase \"object\":\n/******/ \t\t\t\t// Module can be created from a template\n/******/ \t\t\t\tmodules[moduleId] = (function(_m) {\n/******/ \t\t\t\t\tvar args = _m.slice(1), templateId = _m[0];\n/******/ \t\t\t\t\treturn function (a,b,c) {\n/******/ \t\t\t\t\t\tmodules[templateId].apply(this, [a,b,c].concat(args));\n/******/ \t\t\t\t\t};\n/******/ \t\t\t\t}(_m));\n/******/ \t\t\t\tbreak;\n/******/ \t\t\tcase \"function\":\n/******/ \t\t\t\t// Normal module\n/******/ \t\t\t\tmodules[moduleId] = _m;\n/******/ \t\t\t\tbreak;\n/******/ \t\t\tdefault:\n/******/ \t\t\t\t// Module is a copy of another module\n/******/ \t\t\t\tmodules[moduleId] = modules[_m];\n/******/ \t\t\t\tbreak;\n/******/ \t\t\t}\n/******/ \t\t}\n/******/ \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);\n/******/ \t\twhile(callbacks.length)\n/******/ \t\t\tcallbacks.shift().call(null, __webpack_require__);\n/******/ \t\tif(moreModules[0]) {\n/******/ \t\t\tinstalledModules[0] = 0;\n/******/ \t\t\treturn __webpack_require__(0);\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// object to store loaded and loading chunks\n/******/ \t// \"0\" means \"already loaded\"\n/******/ \t// Array means \"loading\", array contains callbacks\n/******/ \tvar installedChunks = {\n/******/ \t\t31:0\n/******/ \t};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/ \t// This file contains only the entry chunk.\n/******/ \t// The chunk loading function for additional chunks\n/******/ \t__webpack_require__.e = function requireEnsure(chunkId, callback) {\n/******/ \t\t// \"0\" is the signal for \"already loaded\"\n/******/ \t\tif(installedChunks[chunkId] === 0)\n/******/ \t\t\treturn callback.call(null, __webpack_require__);\n/******/\n/******/ \t\t// an array means \"currently loading\".\n/******/ \t\tif(installedChunks[chunkId] !== undefined) {\n/******/ \t\t\tinstalledChunks[chunkId].push(callback);\n/******/ \t\t} else {\n/******/ \t\t\t// start chunk loading\n/******/ \t\t\tinstalledChunks[chunkId] = [callback];\n/******/ \t\t\tvar head = document.getElementsByTagName('head')[0];\n/******/ \t\t\tvar script = document.createElement('script');\n/******/ \t\t\tscript.type = 'text/javascript';\n/******/ \t\t\tscript.charset = 'utf-8';\n/******/ \t\t\tscript.async = true;\n/******/\n/******/ \t\t\tscript.src = __webpack_require__.p + \"chunks/\" + chunkId + \".\" + {\"0\":\"8eba31c7f8a4ba12d4f0\",\"1\":\"2a80f2805f0ad61574e4\",\"2\":\"59edbaad3880b6989c03\",\"3\":\"6b5640aaff12ceffed87\",\"4\":\"ed0dea34413819390369\",\"5\":\"39b82edb6afe71dfedda\",\"6\":\"ac8a1d796320ea629a59\",\"7\":\"fb1459b24b9370665f21\",\"8\":\"ec9a022a808be725e418\",\"9\":\"0ef49ae8d4cf283485fe\",\"10\":\"f926dfd3ae7bf509ed4d\",\"11\":\"1bab5dc273b4da2698da\",\"12\":\"c9594fbeb5ec5f229448\",\"13\":\"38196494b8fb921ef789\",\"14\":\"f0598bceb83dddc07533\",\"15\":\"e0e4d618ade824e9a054\",\"16\":\"b6fdeda4b76dee9ff900\",\"17\":\"ce9c798872e477e8d4da\",\"18\":\"d1b82d6f8b5b291756cd\",\"19\":\"ef0f0973698915a3b177\",\"20\":\"23546befdf1e2f39820a\",\"21\":\"c1564e20eb7fe23c3281\",\"22\":\"13afd6a9ea6860e80603\",\"23\":\"0e676fbff05e4c36acfc\",\"24\":\"2a6267d518280dc5b69c\",\"25\":\"ae4d92b7f22c0664a733\",\"26\":\"074d8c1b6c13e9884fd9\",\"27\":\"67c3fd17c23014c44845\",\"28\":\"f2744e598de4330d8956\",\"29\":\"7b551c87d15f96f30b57\",\"30\":\"e446df9cf9dff85de9b8\",\"32\":\"1055ccb8662c0b6827f8\",\"33\":\"b8bc582459a84b047503\"}[chunkId] + \".js\";\n/******/ \t\t\thead.appendChild(script);\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"/static/\";\n/******/ })\n/************************************************************************/\n/******/ ((function(modules) {\n\t// Check all modules for deduplicated modules\n\tfor(var i in modules) {\n\t\tif(Object.prototype.hasOwnProperty.call(modules, i)) {\n\t\t\tswitch(typeof modules[i]) {\n\t\t\tcase \"function\": break;\n\t\t\tcase \"object\":\n\t\t\t\t// Module can be created from a template\n\t\t\t\tmodules[i] = (function(_m) {\n\t\t\t\t\tvar args = _m.slice(1), fn = modules[_m[0]];\n\t\t\t\t\treturn function (a,b,c) {\n\t\t\t\t\t\tfn.apply(this, [a,b,c].concat(args));\n\t\t\t\t\t};\n\t\t\t\t}(modules[i]));\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// Module is a copy of another module\n\t\t\t\tmodules[i] = modules[modules[i]];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn modules;\n}([])));\n\n\n/** WEBPACK FOOTER **\n ** common.js\n **/"," \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, callbacks = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId])\n \t\t\t\tcallbacks.push.apply(callbacks, installedChunks[chunkId]);\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tvar _m = moreModules[moduleId];\n\n \t\t\t// Check if module is deduplicated\n \t\t\tswitch(typeof _m) {\n \t\t\tcase \"object\":\n \t\t\t\t// Module can be created from a template\n \t\t\t\tmodules[moduleId] = (function(_m) {\n \t\t\t\t\tvar args = _m.slice(1), templateId = _m[0];\n \t\t\t\t\treturn function (a,b,c) {\n \t\t\t\t\t\tmodules[templateId].apply(this, [a,b,c].concat(args));\n \t\t\t\t\t};\n \t\t\t\t}(_m));\n \t\t\t\tbreak;\n \t\t\tcase \"function\":\n \t\t\t\t// Normal module\n \t\t\t\tmodules[moduleId] = _m;\n \t\t\t\tbreak;\n \t\t\tdefault:\n \t\t\t\t// Module is a copy of another module\n \t\t\t\tmodules[moduleId] = modules[_m];\n \t\t\t\tbreak;\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);\n \t\twhile(callbacks.length)\n \t\t\tcallbacks.shift().call(null, __webpack_require__);\n \t\tif(moreModules[0]) {\n \t\t\tinstalledModules[0] = 0;\n \t\t\treturn __webpack_require__(0);\n \t\t}\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// \"0\" means \"already loaded\"\n \t// Array means \"loading\", array contains callbacks\n \tvar installedChunks = {\n \t\t31:0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId, callback) {\n \t\t// \"0\" is the signal for \"already loaded\"\n \t\tif(installedChunks[chunkId] === 0)\n \t\t\treturn callback.call(null, __webpack_require__);\n\n \t\t// an array means \"currently loading\".\n \t\tif(installedChunks[chunkId] !== undefined) {\n \t\t\tinstalledChunks[chunkId].push(callback);\n \t\t} else {\n \t\t\t// start chunk loading\n \t\t\tinstalledChunks[chunkId] = [callback];\n \t\t\tvar head = document.getElementsByTagName('head')[0];\n \t\t\tvar script = document.createElement('script');\n \t\t\tscript.type = 'text/javascript';\n \t\t\tscript.charset = 'utf-8';\n \t\t\tscript.async = true;\n\n \t\t\tscript.src = __webpack_require__.p + \"chunks/\" + chunkId + \".\" + {\"0\":\"8eba31c7f8a4ba12d4f0\",\"1\":\"2a80f2805f0ad61574e4\",\"2\":\"59edbaad3880b6989c03\",\"3\":\"6b5640aaff12ceffed87\",\"4\":\"ed0dea34413819390369\",\"5\":\"39b82edb6afe71dfedda\",\"6\":\"ac8a1d796320ea629a59\",\"7\":\"fb1459b24b9370665f21\",\"8\":\"ec9a022a808be725e418\",\"9\":\"0ef49ae8d4cf283485fe\",\"10\":\"f926dfd3ae7bf509ed4d\",\"11\":\"1bab5dc273b4da2698da\",\"12\":\"c9594fbeb5ec5f229448\",\"13\":\"38196494b8fb921ef789\",\"14\":\"f0598bceb83dddc07533\",\"15\":\"e0e4d618ade824e9a054\",\"16\":\"b6fdeda4b76dee9ff900\",\"17\":\"ce9c798872e477e8d4da\",\"18\":\"d1b82d6f8b5b291756cd\",\"19\":\"ef0f0973698915a3b177\",\"20\":\"23546befdf1e2f39820a\",\"21\":\"c1564e20eb7fe23c3281\",\"22\":\"13afd6a9ea6860e80603\",\"23\":\"0e676fbff05e4c36acfc\",\"24\":\"2a6267d518280dc5b69c\",\"25\":\"ae4d92b7f22c0664a733\",\"26\":\"074d8c1b6c13e9884fd9\",\"27\":\"67c3fd17c23014c44845\",\"28\":\"f2744e598de4330d8956\",\"29\":\"7b551c87d15f96f30b57\",\"30\":\"e446df9cf9dff85de9b8\",\"32\":\"1055ccb8662c0b6827f8\",\"33\":\"b8bc582459a84b047503\"}[chunkId] + \".js\";\n \t\t\thead.appendChild(script);\n \t\t}\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/static/\";\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 3ed3ae50839df38675d6\n **/"],"sourceRoot":""}
@@ -48,6 +48,9 @@
48
48
  <meta name="search-autocomplete-enabled" content="{{ 'true' if config.SEARCH_AUTOCOMPLETE_ENABLED else 'false' }}">
49
49
  <meta name="search-autocomplete-debounce" content="{{ config.SEARCH_AUTOCOMPLETE_DEBOUNCE }}">
50
50
  <meta name="dataset-max-resources-uncollapsed" content="{{ config.DATASET_MAX_RESOURCES_UNCOLLAPSED }}">
51
+ {% if config.ORG_BID_FORMAT %}
52
+ <meta name="org-bid-format" content="{{ config.ORG_BID_FORMAT }}">
53
+ {% endif %}
51
54
  <meta name="markdown-config" content="{{ {
52
55
  'tags': config.MD_ALLOWED_TAGS,
53
56
  'attributes': config.MD_ALLOWED_ATTRIBUTES,
@@ -6,7 +6,7 @@
6
6
  _('%(user)s has certified your organization "%(name)s"',
7
7
  user=(
8
8
  '<a href="'|safe
9
- + url_for('users.show', user=badge.created_by, _external=True)
9
+ + url_for('api.user', user=badge.created_by, _external=True)
10
10
  + '">'|safe
11
11
  + badge.created_by.fullname
12
12
  + '</a>'|safe
@@ -6,7 +6,7 @@
6
6
  _('%(user)s has identified your organization "%(name)s" as public service',
7
7
  user=(
8
8
  '<a href="'|safe
9
- + url_for('users.show', user=badge.created_by, _external=True)
9
+ + url_for('api.user', user=badge.created_by, _external=True)
10
10
  + '">'|safe
11
11
  + badge.created_by.fullname
12
12
  + '</a>'|safe
@@ -7,7 +7,7 @@
7
7
  type=discussion.subject.verbose_name,
8
8
  user=(
9
9
  '<a href="'|safe
10
- + url_for('users.show', user=message.posted_by, _external=True)
10
+ + url_for('api.user', user=message.posted_by, _external=True)
11
11
  + '">'|safe
12
12
  + message.posted_by.fullname
13
13
  + '</a>'|safe
@@ -8,7 +8,7 @@
8
8
  {{ _('As an administrator of "%(org)s" you are being informed than a new membership request from %(user)s is pending for validation',
9
9
  user=(
10
10
  '<a href="'|safe
11
- + url_for('users.show', user=request.user, _external=True)
11
+ + url_for('api.user', user=request.user, _external=True)
12
12
  + '">'|safe
13
13
  + request.user.fullname
14
14
  + '</a>'|safe
@@ -7,7 +7,7 @@
7
7
  type=discussion.subject.verbose_name,
8
8
  user=(
9
9
  '<a href="'|safe
10
- + url_for('users.show', user=discussion.user, _external=True)
10
+ + url_for('api.user', user=discussion.user, _external=True)
11
11
  + '">'|safe
12
12
  + discussion.user.fullname
13
13
  + '</a>'|safe
@@ -7,7 +7,7 @@
7
7
  type=discussion.subject.verbose_name,
8
8
  user=(
9
9
  '<a href="'|safe
10
- + url_for('users.show', user=message.posted_by, _external=True)
10
+ + url_for('api.user', user=message.posted_by, _external=True)
11
11
  + '">'|safe
12
12
  + message.posted_by.fullname
13
13
  + '</a>'|safe
@@ -1,5 +1,5 @@
1
1
  {% macro user_mail_card(user, msg=None) %}
2
- <a href="{{ url_for('users.show', user=user.id, _external=True) }}"
2
+ <a href="{{ url_for('api.user', user=user.id, _external=True) }}"
3
3
  style="margin: 0;padding: 0;width:100%;">
4
4
  <table height="60" cellpadding="0" cellspacing="0" style="margin: 0;padding: 0;border:1px solid #eee;width:100%;">
5
5
  <tr style="margin: 0;padding: 0;">
@@ -229,12 +229,20 @@ class DatasetAPITest(APITestCase):
229
229
  '''It should fetch a dataset from the API'''
230
230
  resources = [ResourceFactory() for _ in range(2)]
231
231
  dataset = DatasetFactory(resources=resources)
232
-
233
232
  response = self.get(url_for('api.dataset', dataset=dataset))
234
233
  self.assert200(response)
235
234
  data = json.loads(response.data)
236
235
  self.assertEqual(len(data['resources']), len(resources))
237
236
  self.assertTrue('quality' in data)
237
+ self.assertTrue('internal' in data)
238
+ # Reloads dataset from mongoDB to get mongoDB's date's milliseconds reset.
239
+ dataset.reload()
240
+ self.assertEqual(data['internal']['created_at_internal'], fields.ISODateTime().format(dataset.created_at_internal))
241
+ self.assertEqual(data['internal']['last_modified_internal'], fields.ISODateTime().format(dataset.last_modified_internal))
242
+
243
+ self.assertTrue('internal' in data['resources'][0])
244
+ self.assertEqual(data['resources'][0]['internal']['created_at_internal'], fields.ISODateTime().format(dataset.resources[0].created_at_internal))
245
+ self.assertEqual(data['resources'][0]['internal']['last_modified_internal'], fields.ISODateTime().format(dataset.resources[0].last_modified_internal))
238
246
 
239
247
  def test_dataset_api_get_deleted(self):
240
248
  '''It should not fetch a deleted dataset from the API and raise 410'''
@@ -15,11 +15,12 @@ from udata.core.organization.factories import OrganizationFactory
15
15
  from udata.core.user.factories import UserFactory, AdminFactory
16
16
  from udata.core.dataset.factories import DatasetFactory
17
17
  from udata.core.reuse.factories import ReuseFactory
18
+ from udata.i18n import _
18
19
 
19
20
  from udata.tests.helpers import (
20
21
  assert_emit, assert_not_emit,
21
- assert200, assert201, assert204, assert403, assert404, assert410,
22
- assert_status
22
+ assert200, assert201, assert204, assert403, assert400, assert404,
23
+ assert410, assert_status
23
24
  )
24
25
 
25
26
  pytestmark = [
@@ -90,6 +91,39 @@ class OrganizationAPITest:
90
91
  assert Organization.objects.count() is 1
91
92
  assert Organization.objects.first().description == 'new description'
92
93
 
94
+ def test_organization_api_update_business_number_id(self, api):
95
+ '''It should update an organization from the API by adding a business number id'''
96
+ user = api.login()
97
+ member = Member(user=user, role='admin')
98
+ org = OrganizationFactory(members=[member])
99
+ data = org.to_dict()
100
+ data['business_number_id'] = '13002526500013'
101
+ response = api.put(url_for('api.organization', org=org), data)
102
+ assert200(response)
103
+ assert Organization.objects.count() is 1
104
+ assert Organization.objects.first().business_number_id == '13002526500013'
105
+
106
+ def test_organization_api_update_business_number_id_failing(self, api):
107
+ '''It should update an organization from the API by adding a business number id'''
108
+ user = api.login()
109
+ member = Member(user=user, role='admin')
110
+ org = OrganizationFactory(members=[member])
111
+ data = org.to_dict()
112
+ data['business_number_id'] = '110014016'
113
+ response = api.put(url_for('api.organization', org=org), data)
114
+ assert400(response)
115
+ assert response.json['errors']['business_number_id'][0] == _('A siret number is made of 14 digits')
116
+
117
+ data['business_number_id'] = '12345678901234'
118
+ response = api.put(url_for('api.organization', org=org), data)
119
+ assert400(response)
120
+ assert response.json['errors']['business_number_id'][0] == _('Invalid Siret number')
121
+
122
+ data['business_number_id'] = 'tttttttttttttt'
123
+ response = api.put(url_for('api.organization', org=org), data)
124
+ assert400(response)
125
+ assert response.json['errors']['business_number_id'][0] == _('A siret number is only made of digits')
126
+
93
127
  def test_organization_api_update_deleted(self, api):
94
128
  '''It should not update a deleted organization from the API'''
95
129
  org = OrganizationFactory(deleted=datetime.utcnow())
@@ -3,6 +3,7 @@ from flask import url_for
3
3
  from udata.core.topic.models import Topic
4
4
  from udata.core.topic.factories import TopicFactory
5
5
  from udata.core.user.factories import AdminFactory
6
+ from udata.core.dataset.factories import DatasetFactory
6
7
 
7
8
  from . import APITestCase
8
9
 
@@ -219,6 +219,21 @@ class MarkdownTest:
219
219
  ))
220
220
  assert_md(text, expected)
221
221
 
222
+ def test_collapsible(self, assert_md):
223
+ '''It should not escape the collabsible HTML elem'''
224
+ text = '\n'.join((
225
+ '<details>',
226
+ '<summary>TITLE</summary>',
227
+ 'BODY CONTENT',
228
+ '</details>',
229
+ ))
230
+ expected = '\n'.join((
231
+ '<details>',
232
+ '<summary>TITLE</summary>',
233
+ 'BODY CONTENT',
234
+ '</details>',
235
+ ))
236
+ assert_md(text, expected)
222
237
 
223
238
  @pytest.mark.frontend
224
239
  class MdStripTest:
@@ -4,7 +4,7 @@ from flask import url_for
4
4
 
5
5
  from udata.models import Dataset, Member
6
6
  from udata.core.discussions.models import Message, Discussion
7
- from udata.core.discussions.metrics import update_discussions_metric
7
+ from udata.core.discussions.metrics import update_discussions_metric # noqa
8
8
  from udata.core.discussions.notifications import discussions_notifications
9
9
  from udata.core.discussions.signals import (
10
10
  on_new_discussion, on_new_discussion_comment,
@@ -17,6 +17,7 @@ from udata.core.discussions.tasks import (
17
17
  from udata.core.dataset.factories import DatasetFactory
18
18
  from udata.core.organization.factories import OrganizationFactory
19
19
  from udata.core.user.factories import UserFactory, AdminFactory
20
+ from udata.tests.helpers import capture_mails
20
21
  from udata.utils import faker
21
22
 
22
23
  from . import TestCase, DBTestMixin
@@ -351,6 +352,11 @@ class DiscussionsTest(APITestCase):
351
352
  data['discussion'][1]['posted_by']['id'], str(owner.id))
352
353
  self.assertIsNotNone(data['discussion'][1]['posted_on'])
353
354
 
355
+ # Can't add anymore comments
356
+ response = self.post(url_for('api.discussion', id=discussion.id),
357
+ {'comment': "can't comment"})
358
+ self.assert403(response)
359
+
354
360
  def test_close_discussion_permissions(self):
355
361
  dataset = Dataset.objects.create(title='Test dataset')
356
362
  user = UserFactory()
@@ -545,3 +551,76 @@ class DiscussionsNotificationsTest(TestCase, DBTestMixin):
545
551
  self.assertEqual(details['title'], discussion.title)
546
552
  self.assertEqual(details['subject']['id'], discussion.subject.id)
547
553
  self.assertEqual(details['subject']['type'], 'dataset')
554
+
555
+
556
+ class DiscussionsMailsTest(APITestCase):
557
+ modules = []
558
+
559
+ def test_new_discussion_mail(self):
560
+ user = UserFactory()
561
+ owner = UserFactory()
562
+ message = Message(content=faker.sentence(), posted_by=user)
563
+ discussion = Discussion.objects.create(
564
+ subject=DatasetFactory(owner=owner),
565
+ user=user,
566
+ title=faker.sentence(),
567
+ discussion=[message]
568
+ )
569
+
570
+ with capture_mails() as mails:
571
+ notify_new_discussion(discussion.id)
572
+
573
+ # Should have sent one mail to the owner
574
+ self.assertEqual(len(mails), 1)
575
+ self.assertEqual(mails[0].recipients[0], owner.email)
576
+
577
+ def test_new_discussion_comment_mail(self):
578
+ owner = UserFactory()
579
+ poster = UserFactory()
580
+ commenter = UserFactory()
581
+ message = Message(content=faker.sentence(), posted_by=poster)
582
+ second_message = Message(content=faker.sentence(), posted_by=owner)
583
+ new_message = Message(content=faker.sentence(), posted_by=commenter)
584
+ discussion = Discussion.objects.create(
585
+ subject=DatasetFactory(owner=owner),
586
+ user=poster,
587
+ title=faker.sentence(),
588
+ discussion=[message, second_message, new_message]
589
+ )
590
+
591
+ with capture_mails() as mails:
592
+ notify_new_discussion_comment(discussion.id, message=len(discussion.discussion) - 1)
593
+
594
+ # Should have sent one mail to the owner and the other participants
595
+ # and no mail to the commenter. The owner should appear only once in the recipients
596
+ # even if he is in both the discussion and the owner of the dataset.
597
+ expected_recipients = (owner.email, poster.email)
598
+ self.assertEqual(len(mails), len(expected_recipients))
599
+ for mail in mails:
600
+ self.assertIn(mail.recipients[0], expected_recipients)
601
+ self.assertNotIn(commenter.email, mail.recipients)
602
+
603
+ def test_closed_discussion_mail(self):
604
+ owner = UserFactory()
605
+ poster = UserFactory()
606
+ commenter = UserFactory()
607
+ message = Message(content=faker.sentence(), posted_by=poster)
608
+ second_message = Message(content=faker.sentence(), posted_by=commenter)
609
+ closing_message = Message(content=faker.sentence(), posted_by=owner)
610
+ discussion = Discussion.objects.create(
611
+ subject=DatasetFactory(owner=owner),
612
+ user=poster,
613
+ title=faker.sentence(),
614
+ discussion=[message, second_message, closing_message]
615
+ )
616
+
617
+ with capture_mails() as mails:
618
+ notify_discussion_closed(discussion.id, message=len(discussion.discussion) - 1)
619
+
620
+ # Should have sent one mail to each participant
621
+ # and no mail to the closer
622
+ expected_recipients = (poster.email, commenter.email)
623
+ self.assertEqual(len(mails), len(expected_recipients))
624
+ for mail in mails:
625
+ self.assertIn(mail.recipients[0], expected_recipients)
626
+ self.assertNotIn(owner.email, mail.recipients)
udata/tests/test_model.py CHANGED
@@ -200,6 +200,24 @@ class SlugFieldTest:
200
200
  assert len(obj.title) == SlugTester.slug.max_length + 1
201
201
  assert len(obj.slug) == SlugTester.slug.max_length
202
202
 
203
+ def test_crop_with_index(self):
204
+ '''SlugField should truncate itself to keep room for index suffix if not unique'''
205
+ first_obj = SlugTester(title='x' * (SlugTester.slug.max_length + 1))
206
+ first_obj.save()
207
+ assert len(first_obj.slug) == SlugTester.slug.max_length
208
+ assert first_obj.slug.endswith('x')
209
+ # Try adding a second obj with same title with a slug already at max_length
210
+ second_obj = SlugTester(title='x' * (SlugTester.slug.max_length + 1))
211
+ second_obj.save()
212
+ assert len(second_obj.slug) == SlugTester.slug.max_length
213
+ assert second_obj.slug.endswith('-1')
214
+ # We could even have 10+ obj with the same title that needs index suffix
215
+ [SlugTester(title='x' * (SlugTester.slug.max_length + 1)).save() for i in range(8)]
216
+ last_obj = SlugTester(title='x' * (SlugTester.slug.max_length + 1))
217
+ last_obj.save()
218
+ assert len(last_obj.slug) == SlugTester.slug.max_length
219
+ assert last_obj.slug.endswith('-10')
220
+
203
221
  def test_multiple_spaces(self):
204
222
  field = db.SlugField()
205
223
  assert field.slugify('a b') == 'a-b'
@@ -0,0 +1,34 @@
1
+ import pytest
2
+
3
+ from udata.search import reindex
4
+ from udata.core.topic.factories import TopicFactory
5
+ from udata.core.dataset.factories import DatasetFactory
6
+
7
+
8
+ @pytest.fixture
9
+ def job_reindex(mocker):
10
+ return mocker.patch.object(reindex, 'delay')
11
+
12
+
13
+ pytestmark = pytest.mark.usefixtures('clean_db')
14
+
15
+
16
+ class TopicModelTest:
17
+
18
+ def test_pre_save(self, job_reindex):
19
+ topic = TopicFactory(datasets=[])
20
+ dataset = DatasetFactory()
21
+
22
+ topic.name = 'new_name'
23
+ topic.save()
24
+ job_reindex.assert_not_called()
25
+
26
+ topic.datasets = [dataset]
27
+ topic.save()
28
+ job_reindex.assert_called()
29
+
30
+ topic.datasets = []
31
+ topic.save()
32
+ job_reindex.assert_called()
33
+
34
+
Binary file
@@ -2,8 +2,8 @@ msgid ""
2
2
  msgstr ""
3
3
  "Project-Id-Version: udata\n"
4
4
  "Report-Msgid-Bugs-To: i18n@opendata.team\n"
5
- "POT-Creation-Date: 2023-07-17 16:43+0200\n"
6
- "PO-Revision-Date: 2023-07-17 14:57\n"
5
+ "POT-Creation-Date: 2023-07-24 11:21+0200\n"
6
+ "PO-Revision-Date: 2023-07-27 15:17\n"
7
7
  "Last-Translator: Open Data Team <i18n@opendata.team>\n"
8
8
  "Language: ar\n"
9
9
  "Language-Team: Arabic\n"
@@ -213,7 +213,7 @@ msgid "Title"
213
213
  msgstr "عنوان"
214
214
 
215
215
  #: udata/core/dataset/forms.py:81 udata/core/dataset/forms.py:141
216
- #: udata/core/jobs/forms.py:28 udata/core/organization/forms.py:25
216
+ #: udata/core/jobs/forms.py:28 udata/core/organization/forms.py:49
217
217
  #: udata/core/reuse/forms.py:21 udata/core/topic/forms.py:17
218
218
  #: udata/harvest/forms.py:62
219
219
  msgid "Description"
@@ -277,7 +277,7 @@ msgstr "مجموعة البيانات متعلقة"
277
277
  msgid "Publish as"
278
278
  msgstr "نشر بإسم"
279
279
 
280
- #: udata/core/dataset/forms.py:138 udata/core/organization/forms.py:23
280
+ #: udata/core/dataset/forms.py:138 udata/core/organization/forms.py:47
281
281
  msgid "Acronym"
282
282
  msgstr "اختصار"
283
283
 
@@ -507,7 +507,7 @@ msgid "You need to update some frequency-based datasets"
507
507
  msgstr "يجب تحديث بعض مجموعات البيانات المستندة إلى الترددات"
508
508
 
509
509
  #: udata/core/discussions/forms.py:14 udata/core/discussions/forms.py:21
510
- #: udata/core/organization/forms.py:54 udata/core/organization/forms.py:58
510
+ #: udata/core/organization/forms.py:80 udata/core/organization/forms.py:84
511
511
  #: udata/harvest/forms.py:78
512
512
  msgid "Comment"
513
513
  msgstr "تعليق"
@@ -530,7 +530,7 @@ msgstr "%(user)s علق نقاشك"
530
530
  msgid "A discussion has been closed"
531
531
  msgstr "وقع إغلاق نقاش"
532
532
 
533
- #: udata/core/jobs/forms.py:27 udata/core/organization/forms.py:21
533
+ #: udata/core/jobs/forms.py:27 udata/core/organization/forms.py:45
534
534
  #: udata/core/post/forms.py:15 udata/core/topic/forms.py:15
535
535
  #: udata/harvest/forms.py:60 udata/templates/api/admin.html:10
536
536
  msgid "Name"
@@ -560,27 +560,50 @@ msgstr "أنشأ منظمة"
560
560
  msgid "updated an organization"
561
561
  msgstr "قام بتحديث منظمة"
562
562
 
563
- #: udata/core/organization/forms.py:23
563
+ #: udata/core/organization/forms.py:25
564
+ #: udata/tests/api/test_organizations_api.py:115
565
+ msgid "A siret number is made of 14 digits"
566
+ msgstr ""
567
+
568
+ #: udata/core/organization/forms.py:36
569
+ #: udata/tests/api/test_organizations_api.py:125
570
+ msgid "A siret number is only made of digits"
571
+ msgstr ""
572
+
573
+ #: udata/core/organization/forms.py:39
574
+ #: udata/tests/api/test_organizations_api.py:120
575
+ msgid "Invalid Siret number"
576
+ msgstr ""
577
+
578
+ #: udata/core/organization/forms.py:47
564
579
  msgid "Shorter organization name"
565
580
  msgstr "الاسم المختصر للمنظمة"
566
581
 
567
- #: udata/core/organization/forms.py:26
582
+ #: udata/core/organization/forms.py:50
568
583
  msgid "The details about your organization"
569
584
  msgstr "تفاصيل حول منظمتك"
570
585
 
571
- #: udata/core/organization/forms.py:28 udata/core/user/forms.py:20
586
+ #: udata/core/organization/forms.py:52 udata/core/user/forms.py:20
572
587
  msgid "Website"
573
588
  msgstr "موقع الكتروني"
574
589
 
575
- #: udata/core/organization/forms.py:28
590
+ #: udata/core/organization/forms.py:52
576
591
  msgid "The organization website URL"
577
592
  msgstr "العنوان الإليكتروني للمؤسسة"
578
593
 
579
- #: udata/core/organization/forms.py:29
594
+ #: udata/core/organization/forms.py:53
580
595
  msgid "Logo"
581
596
  msgstr "شعار"
582
597
 
583
- #: udata/core/organization/forms.py:65
598
+ #: udata/core/organization/forms.py:54
599
+ msgid "Business id"
600
+ msgstr ""
601
+
602
+ #: udata/core/organization/forms.py:55
603
+ msgid "Business identification number"
604
+ msgstr ""
605
+
606
+ #: udata/core/organization/forms.py:91
584
607
  msgid "Role"
585
608
  msgstr "دور"
586
609
 
@@ -607,11 +630,11 @@ msgstr "مقبول"
607
630
  msgid "Refused"
608
631
  msgstr "مرفوض"
609
632
 
610
- #: udata/core/organization/models.py:138
633
+ #: udata/core/organization/models.py:142
611
634
  msgid "Public Service"
612
635
  msgstr "خدمات عامة"
613
636
 
614
- #: udata/core/organization/models.py:139
637
+ #: udata/core/organization/models.py:143
615
638
  msgid "Certified"
616
639
  msgstr "معتمد"
617
640
 
Binary file