From 6cd0ebad27dccbf93cf1e9b80c597e640d84acaf Mon Sep 17 00:00:00 2001 From: flarum-bot Date: Fri, 4 Jun 2021 20:44:23 +0000 Subject: [PATCH] Bundled output for commit 9245cc84e00c8304254e89aaea22ef82ccdbf100 Includes transpiled JS/TS. [skip ci] --- js/dist/forum.js | 2 +- js/dist/forum.js.map | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/js/dist/forum.js b/js/dist/forum.js index b170c18..dfc387b 100644 --- a/js/dist/forum.js +++ b/js/dist/forum.js @@ -1,2 +1,2 @@ -module.exports=function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=19)}([,function(t,e){t.exports=flarum.core.compat["common/Model"]},function(t,e){t.exports=flarum.core.compat["forum/app"]},function(t,e,n){"use strict";function r(t,e){return(r=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function o(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t,r(t,e)}n.d(e,"a",(function(){return o}))},function(t,e){t.exports=flarum.core.compat["common/helpers/icon"]},function(t,e){t.exports=flarum.core.compat["common/components/Button"]},function(t,e){t.exports=flarum.core.compat["forum/components/UserPage"]},function(t,e,n){"use strict";n.d(e,"a",(function(){return a}));var r=n(3),o=n(1),i=n.n(o),a=function(t){function e(){for(var e,n=arguments.length,r=new Array(n),o=0;o {\n const split = rule.split(':', 2);\n\n if (split[0] === ruleName) {\n ruleContent = split[1];\n }\n });\n\n return ruleContent;\n }\n\n editorField() {\n return m('.Form-group.Field', [\n m('label', [this.field.icon() ? [icon(this.field.icon()), ' '] : null, this.field.name(), this.field.required() ? ' *' : null]),\n m('.FormField', [\n this.field.prefix() ? m('.prefix', this.field.prefix()) : null,\n this.editorInput(),\n this.field.description() ? m('.helpText', this.field.description()) : null,\n ]),\n ]);\n }\n\n editorInput() {\n return m('input', this.editorInputAttrs());\n }\n\n editorInputAttrs() {\n return {\n className: 'FormControl',\n oninput: (event) => {\n this.set(event.target.value);\n },\n value: this.value,\n required: this.field.required(),\n };\n }\n\n answerField() {\n const iconName = this.readAttribute(this.field, 'icon');\n\n return m('.Masquerade-Bio-Set', [\n m('span.Masquerade-Bio-Field', [iconName ? [icon(iconName), ' '] : null, this.readAttribute(this.field, 'name') + ': ']),\n m('span.Masquerade-Bio-Answer', this.answerContent()),\n ]);\n }\n\n answerContent() {\n return this.value;\n }\n\n static isNoOptionSelectedValue(value) {\n // The value can be null when coming from the API\n // The value can be '' when the field does not exist on the user (the empty string is set in ProfileConfigurePane)\n return value === null || value === '';\n }\n}\n","import icon from 'flarum/common/helpers/icon';\nimport BaseField from './BaseField';\n\nexport default class BooleanField extends BaseField {\n editorInput() {\n return this.options().map((option) =>\n m(\n 'div',\n m('label', [\n m('input[type=radio]', {\n checked: option.selected(this.value),\n onclick: () => {\n this.set(option.key);\n },\n }),\n ' ' + option.label,\n ])\n )\n );\n }\n\n options() {\n let options = [];\n\n if (!this.readAttribute(this.field, 'required')) {\n options.push({\n selected: (value) => BaseField.isNoOptionSelectedValue(value),\n key: null,\n label: app.translator.trans('fof-masquerade.forum.fields.select.none-optional'),\n });\n }\n\n options.push({\n selected: (value) => ['true', '1', 1, true, 'yes'].indexOf(value) !== -1,\n key: 'true',\n label: app.translator.trans('fof-masquerade.forum.fields.boolean.yes'),\n });\n\n options.push({\n selected: (value) => ['false', '0', 0, false, 'no'].indexOf(value) !== -1,\n key: 'false',\n label: app.translator.trans('fof-masquerade.forum.fields.boolean.no'),\n });\n\n // This is probably overkill because it looks like the backend casts the value anyway\n if (\n !BaseField.isNoOptionSelectedValue(this.value) &&\n ['true', '1', 1, true, 'yes', 'false', '0', 0, false, 'no'].indexOf(this.value) === -1\n ) {\n options.push({\n selected: () => true,\n key: this.value,\n label: '(invalid) ' + this.value,\n });\n }\n\n return options;\n }\n\n answerContent() {\n if (BaseField.isNoOptionSelectedValue(this.value)) {\n return '';\n }\n\n return [1, '1', true, 'true', 'yes'].indexOf(this.value) !== -1\n ? [icon('far fa-check-square'), ' ', app.translator.trans('fof-masquerade.forum.fields.boolean.yes')]\n : [icon('far fa-square'), ' ', app.translator.trans('fof-masquerade.forum.fields.boolean.no')];\n }\n}\n","import Button from 'flarum/common/components/Button';\nimport BaseField from './BaseField';\n\nexport default class EmailField extends BaseField {\n editorInputAttrs() {\n let attrs = super.editorInputAttrs();\n\n attrs.type = 'email';\n attrs.placeholder = 'you@example.com';\n\n return attrs;\n }\n\n answerContent() {\n const value = this.value;\n\n if (!value) {\n return null;\n }\n\n const email = value\n .split(/@|\\./)\n .map((segment) => {\n return segment.replace(/(.{2})./g, '$1*');\n })\n .join('*');\n\n return Button.component(\n {\n onclick: () => this.mailTo(),\n className: 'Button Button--text',\n icon: 'far fa-envelope',\n },\n email\n );\n }\n\n mailTo() {\n window.location = 'mailto:' + this.value;\n }\n}\n","import Select from 'flarum/common/components/Select';\nimport BaseField from './BaseField';\n\nconst NO_OPTION_SELECTED_KEY = 'fof_masquerade_no_option_selected';\n\nexport default class EmailField extends BaseField {\n editorInput() {\n return Select.component({\n onchange: (value) => {\n if (value === NO_OPTION_SELECTED_KEY) {\n value = null;\n }\n\n this.set(value);\n },\n value: BaseField.isNoOptionSelectedValue(this.value) ? NO_OPTION_SELECTED_KEY : this.value,\n options: this.options(),\n });\n }\n\n options() {\n let options = {};\n\n if (!this.readAttribute(this.field, 'required')) {\n options[NO_OPTION_SELECTED_KEY] = app.translator.trans('fof-masquerade.forum.fields.select.none-optional');\n } else if (BaseField.isNoOptionSelectedValue(this.value)) {\n options[NO_OPTION_SELECTED_KEY] = app.translator.trans('fof-masquerade.forum.fields.select.none-required');\n }\n\n const validationIn = this.validationRule('in');\n\n if (validationIn) {\n validationIn.split(',').forEach((value) => {\n options[value] = value;\n });\n }\n\n if (!BaseField.isNoOptionSelectedValue(this.value) && typeof options[this.value] === 'undefined') {\n options[this.value] = '(invalid) ' + this.value;\n }\n\n return options;\n }\n}\n","import Button from 'flarum/common/components/Button';\nimport BaseField from './BaseField';\n\nexport default class UrlField extends BaseField {\n editorInputAttrs() {\n let attrs = super.editorInputAttrs();\n\n attrs.type = 'url';\n attrs.placeholder = 'https://example.com';\n\n return attrs;\n }\n\n answerContent() {\n const value = this.value;\n\n if (!value) {\n return null;\n }\n\n return Button.component(\n {\n onclick: () => this.to(),\n className: 'Button Button--text',\n icon: 'fas fa-link',\n },\n value.replace(/^https?:\\/\\//, '')\n );\n }\n\n to() {\n const popup = window.open();\n popup.location = this.value;\n }\n}\n","import BaseField from './BaseField';\nimport BooleanField from './BooleanField';\nimport EmailField from './EmailField';\nimport SelectField from './SelectField';\nimport UrlField from './UrlField';\n\nexport default class TypeFactory {\n static typeForField({ field, set, value }) {\n let className = BaseField;\n\n const type = this.identify(field);\n\n if (type) {\n className = this.types()[type];\n }\n\n return new className({\n field,\n set,\n value,\n });\n }\n\n static fieldAttribute(field, attribute) {\n if (typeof field[attribute] === 'function') {\n return field[attribute]();\n }\n\n return field[attribute];\n }\n\n static types() {\n return {\n boolean: BooleanField,\n email: EmailField,\n select: SelectField,\n url: UrlField,\n };\n }\n\n /**\n * Identifies how to parse the field answer.\n * @returns {null|string}\n */\n static identify(field) {\n const validation = (this.fieldAttribute(field, 'validation') || '').split(',');\n let identified = null;\n\n // If the field has a type we use it\n const fieldType = this.fieldAttribute(field, 'type');\n if (typeof this.types()[fieldType] !== 'undefined') {\n return fieldType;\n }\n\n // If it's an advanced field with no type we then guess the best type\n validation.forEach((rule) => {\n rule = rule.trim();\n\n if (typeof this.types()[rule] !== 'undefined') {\n identified = rule;\n }\n });\n\n return identified;\n }\n}\n","import app from 'flarum/forum/app';\nimport UserPage from 'flarum/forum/components/UserPage';\nimport Button from 'flarum/common/components/Button';\nimport Link from 'flarum/common/components/Link';\nimport TypeFactory from './../types/TypeFactory';\n\n/* global m */\n\nexport default class ProfileConfigurePane extends UserPage {\n oninit(vnode) {\n super.oninit(vnode);\n this.loading = true;\n\n this.loadUser(app.session.user.username());\n this.enforceProfileCompletion = app.forum.attribute('masquerade.force-profile-completion') || false;\n this.profileCompleted = app.forum.attribute('masquerade.profile-completed') || false;\n this.profileNowCompleted = false; // Show \"after required\" text\n this.fields = [];\n this.answers = {};\n this.load();\n\n // Show disabled state if everything is saved\n // Unless the profile isn't complete, in which case show enabled button so it's obvious you will need to save\n this.dirty = !this.profileCompleted;\n }\n\n content() {\n return m(\n 'form.ProfileConfigurePane',\n {\n onsubmit: this.update.bind(this),\n },\n [\n this.enforceProfileCompletion && !this.profileCompleted\n ? m('.Alert.Alert--Error', app.translator.trans('fof-masquerade.forum.alerts.profile-completion-required'))\n : null,\n m(\n '.Fields',\n this.fields\n .sort((a, b) => a.sort() - b.sort())\n .map((field) => {\n if (!this.answers.hasOwnProperty(field.id())) {\n this.answers[field.id()] = field.answer() ? field.answer().content() : '';\n }\n\n return this.field(field);\n })\n ),\n Button.component(\n {\n type: 'submit',\n className: 'Button Button--primary',\n loading: this.loading,\n disabled: !this.dirty,\n },\n app.translator.trans('fof-masquerade.forum.buttons.save-profile')\n ),\n this.profileNowCompleted\n ? m(\n 'span.Masquerade-NowCompleted',\n app.translator.trans('fof-masquerade.forum.alerts.profile-completed', {\n a: m(Link, {\n href: app.route('index'),\n }),\n })\n )\n : null,\n ]\n );\n }\n\n field(field) {\n const type = TypeFactory.typeForField({\n field,\n set: this.set.bind(this, field),\n value: this.answers[field.id()],\n });\n\n return type.editorField();\n }\n\n load() {\n app.request({\n method: 'GET',\n url: app.forum.attribute('apiUrl') + '/masquerade/configure',\n }).then(this.parseResponse.bind(this));\n }\n\n set(field, value) {\n this.answers[field.id()] = value;\n this.dirty = true;\n }\n\n update(e) {\n e.preventDefault();\n\n this.loading = true;\n\n app.request({\n method: 'POST',\n url: app.forum.attribute('apiUrl') + '/masquerade/configure',\n body: this.answers,\n })\n .then((response) => {\n this.dirty = false;\n if (!this.profileCompleted) {\n this.profileCompleted = true;\n this.profileNowCompleted = true;\n }\n\n this.parseResponse(response);\n })\n .catch(() => {\n this.loading = false;\n m.redraw();\n });\n }\n\n parseResponse(response) {\n this.fields = app.store.pushPayload(response);\n this.loading = false;\n m.redraw();\n }\n}\n","import UserPage from 'flarum/forum/components/UserPage';\nimport TypeFactory from './../types/TypeFactory';\n\n/* global m */\n\nexport default class ProfileConfigurePane extends UserPage {\n oninit(vnode) {\n super.oninit(vnode);\n this.loading = true;\n\n this.fields = [];\n this.answers = {};\n\n this.loadUser(m.route.param('username'));\n }\n\n content() {\n return m('.Masquerade-Bio', [\n m(\n '.Fields',\n this.fields\n .sort((a, b) => a.sort() - b.sort())\n .map((field) => {\n // UserID check must be done with == because userId() is number while id() is string\n this.answers[field.id()] = field.answer() && field.answer().userId() == this.user.id() ? field.answer().content() : null;\n\n return this.field(field);\n })\n ),\n ]);\n }\n\n field(field) {\n const type = TypeFactory.typeForField({\n field,\n value: this.answers[field.id()],\n });\n\n return type.answerField();\n }\n\n load(user) {\n app.request({\n method: 'GET',\n url: app.forum.attribute('apiUrl') + '/masquerade/profile/' + user.id(),\n }).then(this.parseResponse.bind(this));\n }\n\n show(user) {\n this.load(user);\n\n super.show(user);\n }\n\n parseResponse(response) {\n this.answers = {};\n this.fields = app.store.pushPayload(response);\n\n this.loading = false;\n m.redraw();\n }\n}\n","import { extend } from 'flarum/common/extend';\nimport UserCard from 'flarum/forum/components/UserCard';\nimport TypeFactory from './types/TypeFactory';\n\nexport default function () {\n extend(UserCard.prototype, 'infoItems', function (items) {\n let answers = app.forum.attribute('canViewMasquerade') ? this.attrs.user.bioFields() || [] : [];\n\n items.add(\n 'masquerade-bio',\n m(\n 'div',\n answers.map((answer) => {\n const field = answer.attribute('field');\n const type = TypeFactory.typeForField({\n field,\n value: answer.content(),\n });\n\n return type.answerField();\n })\n )\n );\n });\n}\n","import app from 'flarum/forum/app';\nimport User from 'flarum/common/models/User';\nimport Field from './../lib/models/Field';\nimport Answer from './../lib/models/Answer';\nimport Model from 'flarum/common/Model';\n\nimport addProfilePane from './addProfilePane';\nimport mutateUserHero from './mutateUserHero';\n\napp.initializers.add('fof-masquerade', (app) => {\n app.store.models['masquerade-field'] = Field;\n app.store.models['masquerade-answer'] = Answer;\n\n User.prototype.bioFields = Model.hasMany('bioFields');\n\n addProfilePane();\n\n mutateUserHero();\n});\n","import { extend } from 'flarum/common/extend';\nimport app from 'flarum/forum/app';\nimport LinkButton from 'flarum/common/components/LinkButton';\nimport UserPage from 'flarum/forum/components/UserPage';\nimport ProfileConfigurePane from './panes/ProfileConfigurePane';\nimport ProfilePane from './panes/ProfilePane';\n\nexport default function () {\n // The configure route must be registered first because otherwise there's a conflict between the two routes\n app.routes['fof-masquerade-configure-profile'] = {\n path: '/masquerade/configure',\n component: ProfileConfigurePane,\n };\n app.routes['fof-masquerade-view-profile'] = {\n path: '/masquerade/:username',\n component: ProfilePane,\n };\n\n extend(UserPage.prototype, 'navItems', function (items) {\n const isOwnProfileAndCanHaveMasquerade = app.forum.attribute('canHaveMasquerade') && app.session.user.id() === this.user.id();\n\n if (app.forum.attribute('canViewMasquerade') || isOwnProfileAndCanHaveMasquerade) {\n const href = isOwnProfileAndCanHaveMasquerade\n ? app.route('fof-masquerade-configure-profile')\n : app.route('fof-masquerade-view-profile', { username: this.user.username() });\n items.add(\n 'masquerade',\n LinkButton.component(\n {\n href,\n icon: 'far fa-id-card',\n },\n app.translator.trans('fof-masquerade.forum.buttons.view-profile')\n ),\n 200\n );\n }\n });\n}\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack://@fof/masquerade/webpack/bootstrap","webpack://@fof/masquerade/external \"flarum.core.compat['common/Model']\"","webpack://@fof/masquerade/external \"flarum.core.compat['forum/app']\"","webpack://@fof/masquerade/./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js","webpack://@fof/masquerade/./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js","webpack://@fof/masquerade/external \"flarum.core.compat['common/helpers/icon']\"","webpack://@fof/masquerade/external \"flarum.core.compat['common/components/Button']\"","webpack://@fof/masquerade/external \"flarum.core.compat['forum/components/UserPage']\"","webpack://@fof/masquerade/./src/lib/models/Field.js","webpack://@fof/masquerade/external \"flarum.core.compat['common/components/Select']\"","webpack://@fof/masquerade/external \"flarum.core.compat['common/extend']\"","webpack://@fof/masquerade/external \"flarum.core.compat['common/models/User']\"","webpack://@fof/masquerade/external \"flarum.core.compat['common/components/LinkButton']\"","webpack://@fof/masquerade/external \"flarum.core.compat['common/components/Link']\"","webpack://@fof/masquerade/external \"flarum.core.compat['forum/components/UserCard']\"","webpack://@fof/masquerade/./src/lib/models/Answer.js","webpack://@fof/masquerade/./src/forum/types/BaseField.js","webpack://@fof/masquerade/./src/forum/types/BooleanField.js","webpack://@fof/masquerade/./src/forum/types/EmailField.js","webpack://@fof/masquerade/./src/forum/types/SelectField.js","webpack://@fof/masquerade/./src/forum/types/UrlField.js","webpack://@fof/masquerade/./src/forum/types/TypeFactory.js","webpack://@fof/masquerade/./src/forum/panes/ProfileConfigurePane.js","webpack://@fof/masquerade/./src/forum/panes/ProfilePane.js","webpack://@fof/masquerade/./src/forum/mutateUserHero.js","webpack://@fof/masquerade/./src/forum/index.js","webpack://@fof/masquerade/./src/forum/addProfilePane.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","flarum","core","compat","_setPrototypeOf","setPrototypeOf","__proto__","_inheritsLoose","subClass","superClass","constructor","Field","Model","attribute","description","type","validation","required","prefix","icon","sort","deleted_at","transformDate","answer","hasOne","on_bio","apiEndpoint","this","exists","data","id","Answer","content","field","userId","BaseField","set","readAttribute","validationRules","split","validationRule","ruleName","ruleContent","forEach","rule","editorField","editorInput","editorInputAttrs","className","oninput","event","target","answerField","iconName","hasAnswer","answerContent","Boolean","keys","length","isNoOptionSelectedValue","BooleanField","options","map","option","checked","selected","onclick","label","push","app","translator","trans","indexOf","EmailField","attrs","placeholder","email","segment","replace","join","Button","component","mailTo","window","location","Select","onchange","validationIn","UrlField","to","open","TypeFactory","typeForField","identify","types","fieldAttribute","boolean","select","SelectField","url","identified","fieldType","trim","ProfileConfigurePane","oninit","vnode","loading","loadUser","session","user","username","enforceProfileCompletion","forum","profileCompleted","profileNowCompleted","fields","answers","load","dirty","onsubmit","update","a","b","disabled","Link","href","route","request","method","then","parseResponse","e","preventDefault","body","response","redraw","store","pushPayload","UserPage","param","show","extend","UserCard","items","bioFields","add","initializers","models","User","hasMany","routes","path","ProfilePane","isOwnProfileAndCanHaveMasquerade","LinkButton","mutateUserHero"],"mappings":"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","file":"forum.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\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 \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\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.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\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// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 19);\n","module.exports = flarum.core.compat['common/Model'];","module.exports = flarum.core.compat['forum/app'];","export default function _setPrototypeOf(o, p) {\n _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n\n return _setPrototypeOf(o, p);\n}","import setPrototypeOf from \"./setPrototypeOf.js\";\nexport default function _inheritsLoose(subClass, superClass) {\n subClass.prototype = Object.create(superClass.prototype);\n subClass.prototype.constructor = subClass;\n setPrototypeOf(subClass, superClass);\n}","module.exports = flarum.core.compat['common/helpers/icon'];","module.exports = flarum.core.compat['common/components/Button'];","module.exports = flarum.core.compat['forum/components/UserPage'];","import Model from 'flarum/common/Model';\n\nexport default class Field extends Model {\n name = Model.attribute('name');\n description = Model.attribute('description');\n type = Model.attribute('type');\n validation = Model.attribute('validation');\n required = Model.attribute('required');\n prefix = Model.attribute('prefix');\n icon = Model.attribute('icon');\n sort = Model.attribute('sort');\n deleted_at = Model.attribute('deleted_at', Model.transformDate);\n answer = Model.hasOne('answer');\n on_bio = Model.attribute('on_bio');\n\n apiEndpoint() {\n return '/masquerade/fields' + (this.exists ? '/' + this.data.id : '');\n }\n}\n","module.exports = flarum.core.compat['common/components/Select'];","module.exports = flarum.core.compat['common/extend'];","module.exports = flarum.core.compat['common/models/User'];","module.exports = flarum.core.compat['common/components/LinkButton'];","module.exports = flarum.core.compat['common/components/Link'];","module.exports = flarum.core.compat['forum/components/UserCard'];","import Model from 'flarum/common/Model';\n\nexport default class Answer extends Model {\n content = Model.attribute('content');\n field = Model.hasOne('field');\n userId = Model.attribute('user_id');\n\n apiEndpoint() {\n return '/masquerade/configure' + (this.exists ? '/' + this.data.id : '');\n }\n}\n","import icon from 'flarum/common/helpers/icon';\n\n/* global m */\n\nexport default class BaseField {\n constructor({ field, set, value }) {\n this.field = field;\n this.set = set;\n this.value = value;\n }\n\n readAttribute(object, attribute) {\n if (typeof object[attribute] === 'function') {\n return object[attribute]();\n }\n\n return object[attribute];\n }\n\n /**\n * Gets all Laravel validation rules split by rule\n * @returns {Array}\n */\n validationRules() {\n return this.readAttribute(this.field, 'validation').split('|');\n }\n\n /**\n * Gets a Laravel validation rule by name\n * @param {string} ruleName\n * @returns {string|null}\n */\n validationRule(ruleName) {\n let ruleContent = null;\n\n this.validationRules().forEach((rule) => {\n const split = rule.split(':', 2);\n\n if (split[0] === ruleName) {\n ruleContent = split[1];\n }\n });\n\n return ruleContent;\n }\n\n editorField() {\n return m('.Form-group.Field', [\n m('label', [this.field.icon() ? [icon(this.field.icon()), ' '] : null, this.field.name(), this.field.required() ? ' *' : null]),\n m('.FormField', [\n this.field.prefix() ? m('.prefix', this.field.prefix()) : null,\n this.editorInput(),\n this.field.description() ? m('.helpText', this.field.description()) : null,\n ]),\n ]);\n }\n\n editorInput() {\n return m('input', this.editorInputAttrs());\n }\n\n editorInputAttrs() {\n return {\n className: 'FormControl',\n oninput: (event) => {\n this.set(event.target.value);\n },\n value: this.value,\n required: this.field.required(),\n };\n }\n\n answerField() {\n const iconName = this.readAttribute(this.field, 'icon');\n\n return (\n
\n \n {iconName && [icon(iconName), ' ']}\n {this.readAttribute(this.field, 'name')}:{' '}\n \n {this.answerContent()}\n
\n );\n }\n\n answerContent() {\n return this.value;\n }\n\n hasAnswer() {\n const answerContent = this.answerContent();\n\n if (answerContent === null) {\n return false;\n }\n\n if (typeof answerContent === 'object') {\n return Boolean(Object.keys(answerContent).length);\n }\n\n return Boolean(answerContent?.length);\n }\n\n static isNoOptionSelectedValue(value) {\n // The value can be null when coming from the API\n // The value can be '' when the field does not exist on the user (the empty string is set in ProfileConfigurePane)\n return value === null || value === '';\n }\n}\n","import icon from 'flarum/common/helpers/icon';\nimport BaseField from './BaseField';\n\nexport default class BooleanField extends BaseField {\n editorInput() {\n return this.options().map((option) =>\n m(\n 'div',\n m('label', [\n m('input[type=radio]', {\n checked: option.selected(this.value),\n onclick: () => {\n this.set(option.key);\n },\n }),\n ' ' + option.label,\n ])\n )\n );\n }\n\n options() {\n let options = [];\n\n if (!this.readAttribute(this.field, 'required')) {\n options.push({\n selected: (value) => BaseField.isNoOptionSelectedValue(value),\n key: null,\n label: app.translator.trans('fof-masquerade.forum.fields.select.none-optional'),\n });\n }\n\n options.push({\n selected: (value) => ['true', '1', 1, true, 'yes'].indexOf(value) !== -1,\n key: 'true',\n label: app.translator.trans('fof-masquerade.forum.fields.boolean.yes'),\n });\n\n options.push({\n selected: (value) => ['false', '0', 0, false, 'no'].indexOf(value) !== -1,\n key: 'false',\n label: app.translator.trans('fof-masquerade.forum.fields.boolean.no'),\n });\n\n // This is probably overkill because it looks like the backend casts the value anyway\n if (\n !BaseField.isNoOptionSelectedValue(this.value) &&\n ['true', '1', 1, true, 'yes', 'false', '0', 0, false, 'no'].indexOf(this.value) === -1\n ) {\n options.push({\n selected: () => true,\n key: this.value,\n label: '(invalid) ' + this.value,\n });\n }\n\n return options;\n }\n\n answerContent() {\n if (BaseField.isNoOptionSelectedValue(this.value)) {\n return '';\n }\n\n return [1, '1', true, 'true', 'yes'].indexOf(this.value) !== -1\n ? [icon('far fa-check-square'), ' ', app.translator.trans('fof-masquerade.forum.fields.boolean.yes')]\n : [icon('far fa-square'), ' ', app.translator.trans('fof-masquerade.forum.fields.boolean.no')];\n }\n}\n","import Button from 'flarum/common/components/Button';\nimport BaseField from './BaseField';\n\nexport default class EmailField extends BaseField {\n editorInputAttrs() {\n let attrs = super.editorInputAttrs();\n\n attrs.type = 'email';\n attrs.placeholder = 'you@example.com';\n\n return attrs;\n }\n\n answerContent() {\n const value = this.value;\n\n if (!value) {\n return null;\n }\n\n const email = value\n .split(/@|\\./)\n .map((segment) => {\n return segment.replace(/(.{2})./g, '$1*');\n })\n .join('*');\n\n return Button.component(\n {\n onclick: () => this.mailTo(),\n className: 'Button Button--text',\n icon: 'far fa-envelope',\n },\n email\n );\n }\n\n mailTo() {\n window.location = 'mailto:' + this.value;\n }\n}\n","import Select from 'flarum/common/components/Select';\nimport BaseField from './BaseField';\n\nconst NO_OPTION_SELECTED_KEY = 'fof_masquerade_no_option_selected';\n\nexport default class EmailField extends BaseField {\n editorInput() {\n return Select.component({\n onchange: (value) => {\n if (value === NO_OPTION_SELECTED_KEY) {\n value = null;\n }\n\n this.set(value);\n },\n value: BaseField.isNoOptionSelectedValue(this.value) ? NO_OPTION_SELECTED_KEY : this.value,\n options: this.options(),\n });\n }\n\n options() {\n let options = {};\n\n if (!this.readAttribute(this.field, 'required')) {\n options[NO_OPTION_SELECTED_KEY] = app.translator.trans('fof-masquerade.forum.fields.select.none-optional');\n } else if (BaseField.isNoOptionSelectedValue(this.value)) {\n options[NO_OPTION_SELECTED_KEY] = app.translator.trans('fof-masquerade.forum.fields.select.none-required');\n }\n\n const validationIn = this.validationRule('in');\n\n if (validationIn) {\n validationIn.split(',').forEach((value) => {\n options[value] = value;\n });\n }\n\n if (!BaseField.isNoOptionSelectedValue(this.value) && typeof options[this.value] === 'undefined') {\n options[this.value] = '(invalid) ' + this.value;\n }\n\n return options;\n }\n}\n","import Button from 'flarum/common/components/Button';\nimport BaseField from './BaseField';\n\nexport default class UrlField extends BaseField {\n editorInputAttrs() {\n let attrs = super.editorInputAttrs();\n\n attrs.type = 'url';\n attrs.placeholder = 'https://example.com';\n\n return attrs;\n }\n\n answerContent() {\n const value = this.value;\n\n if (!value) {\n return null;\n }\n\n return Button.component(\n {\n onclick: () => this.to(),\n className: 'Button Button--text',\n icon: 'fas fa-link',\n },\n value.replace(/^https?:\\/\\//, '')\n );\n }\n\n to() {\n const popup = window.open();\n popup.location = this.value;\n }\n}\n","import BaseField from './BaseField';\nimport BooleanField from './BooleanField';\nimport EmailField from './EmailField';\nimport SelectField from './SelectField';\nimport UrlField from './UrlField';\n\nexport default class TypeFactory {\n static typeForField({ field, set, value }) {\n let className = BaseField;\n\n const type = this.identify(field);\n\n if (type) {\n className = this.types()[type];\n }\n\n return new className({\n field,\n set,\n value,\n });\n }\n\n static fieldAttribute(field, attribute) {\n if (typeof field[attribute] === 'function') {\n return field[attribute]();\n }\n\n return field[attribute];\n }\n\n static types() {\n return {\n boolean: BooleanField,\n email: EmailField,\n select: SelectField,\n url: UrlField,\n };\n }\n\n /**\n * Identifies how to parse the field answer.\n * @returns {null|string}\n */\n static identify(field) {\n const validation = (this.fieldAttribute(field, 'validation') || '').split(',');\n let identified = null;\n\n // If the field has a type we use it\n const fieldType = this.fieldAttribute(field, 'type');\n if (typeof this.types()[fieldType] !== 'undefined') {\n return fieldType;\n }\n\n // If it's an advanced field with no type we then guess the best type\n validation.forEach((rule) => {\n rule = rule.trim();\n\n if (typeof this.types()[rule] !== 'undefined') {\n identified = rule;\n }\n });\n\n return identified;\n }\n}\n","import app from 'flarum/forum/app';\nimport UserPage from 'flarum/forum/components/UserPage';\nimport Button from 'flarum/common/components/Button';\nimport Link from 'flarum/common/components/Link';\nimport TypeFactory from './../types/TypeFactory';\n\n/* global m */\n\nexport default class ProfileConfigurePane extends UserPage {\n oninit(vnode) {\n super.oninit(vnode);\n this.loading = true;\n\n this.loadUser(app.session.user.username());\n this.enforceProfileCompletion = app.forum.attribute('masquerade.force-profile-completion') || false;\n this.profileCompleted = app.forum.attribute('masquerade.profile-completed') || false;\n this.profileNowCompleted = false; // Show \"after required\" text\n this.fields = [];\n this.answers = {};\n this.load();\n\n // Show disabled state if everything is saved\n // Unless the profile isn't complete, in which case show enabled button so it's obvious you will need to save\n this.dirty = !this.profileCompleted;\n }\n\n content() {\n return m(\n 'form.ProfileConfigurePane',\n {\n onsubmit: this.update.bind(this),\n },\n [\n this.enforceProfileCompletion && !this.profileCompleted\n ? m('.Alert.Alert--Error', app.translator.trans('fof-masquerade.forum.alerts.profile-completion-required'))\n : null,\n m(\n '.Fields',\n this.fields\n .sort((a, b) => a.sort() - b.sort())\n .map((field) => {\n if (!this.answers.hasOwnProperty(field.id())) {\n this.answers[field.id()] = field.answer() ? field.answer().content() : '';\n }\n\n return this.field(field);\n })\n ),\n Button.component(\n {\n type: 'submit',\n className: 'Button Button--primary',\n loading: this.loading,\n disabled: !this.dirty,\n },\n app.translator.trans('fof-masquerade.forum.buttons.save-profile')\n ),\n this.profileNowCompleted\n ? m(\n 'span.Masquerade-NowCompleted',\n app.translator.trans('fof-masquerade.forum.alerts.profile-completed', {\n a: m(Link, {\n href: app.route('index'),\n }),\n })\n )\n : null,\n ]\n );\n }\n\n field(field) {\n const type = TypeFactory.typeForField({\n field,\n set: this.set.bind(this, field),\n value: this.answers[field.id()],\n });\n\n return type.editorField();\n }\n\n load() {\n app.request({\n method: 'GET',\n url: app.forum.attribute('apiUrl') + '/masquerade/configure',\n }).then(this.parseResponse.bind(this));\n }\n\n set(field, value) {\n this.answers[field.id()] = value;\n this.dirty = true;\n }\n\n update(e) {\n e.preventDefault();\n\n this.loading = true;\n\n app.request({\n method: 'POST',\n url: app.forum.attribute('apiUrl') + '/masquerade/configure',\n body: this.answers,\n })\n .then((response) => {\n this.dirty = false;\n if (!this.profileCompleted) {\n this.profileCompleted = true;\n this.profileNowCompleted = true;\n }\n\n this.parseResponse(response);\n })\n .catch(() => {\n this.loading = false;\n m.redraw();\n });\n }\n\n parseResponse(response) {\n this.fields = app.store.pushPayload(response);\n this.loading = false;\n m.redraw();\n }\n}\n","import UserPage from 'flarum/forum/components/UserPage';\nimport TypeFactory from './../types/TypeFactory';\n\n/* global m */\n\nexport default class ProfileConfigurePane extends UserPage {\n oninit(vnode) {\n super.oninit(vnode);\n this.loading = true;\n\n this.fields = [];\n this.answers = {};\n\n this.loadUser(m.route.param('username'));\n }\n\n content() {\n return m('.Masquerade-Bio', [\n m(\n '.Fields',\n this.fields\n .sort((a, b) => a.sort() - b.sort())\n .map((field) => {\n // UserID check must be done with == because userId() is number while id() is string\n this.answers[field.id()] = field.answer() && field.answer().userId() == this.user.id() ? field.answer().content() : null;\n\n return this.field(field);\n })\n ),\n ]);\n }\n\n field(field) {\n const type = TypeFactory.typeForField({\n field,\n value: this.answers[field.id()],\n });\n\n return type.answerField();\n }\n\n load(user) {\n app.request({\n method: 'GET',\n url: app.forum.attribute('apiUrl') + '/masquerade/profile/' + user.id(),\n }).then(this.parseResponse.bind(this));\n }\n\n show(user) {\n this.load(user);\n\n super.show(user);\n }\n\n parseResponse(response) {\n this.answers = {};\n this.fields = app.store.pushPayload(response);\n\n this.loading = false;\n m.redraw();\n }\n}\n","import { extend } from 'flarum/common/extend';\nimport UserCard from 'flarum/forum/components/UserCard';\nimport TypeFactory from './types/TypeFactory';\n\nexport default function () {\n extend(UserCard.prototype, 'infoItems', function (items) {\n let answers = app.forum.attribute('canViewMasquerade') ? this.attrs.user.bioFields() || [] : [];\n\n items.add(\n 'masquerade-bio',\n m(\n 'div',\n answers.map((answer) => {\n const field = answer.attribute('field');\n const type = TypeFactory.typeForField({\n field,\n value: answer.content(),\n });\n\n return type.answerField();\n })\n )\n );\n });\n}\n","import app from 'flarum/forum/app';\nimport User from 'flarum/common/models/User';\nimport Field from './../lib/models/Field';\nimport Answer from './../lib/models/Answer';\nimport Model from 'flarum/common/Model';\n\nimport addProfilePane from './addProfilePane';\nimport mutateUserHero from './mutateUserHero';\n\napp.initializers.add('fof-masquerade', (app) => {\n app.store.models['masquerade-field'] = Field;\n app.store.models['masquerade-answer'] = Answer;\n\n User.prototype.bioFields = Model.hasMany('bioFields');\n\n addProfilePane();\n\n mutateUserHero();\n});\n","import { extend } from 'flarum/common/extend';\nimport app from 'flarum/forum/app';\nimport LinkButton from 'flarum/common/components/LinkButton';\nimport UserPage from 'flarum/forum/components/UserPage';\nimport ProfileConfigurePane from './panes/ProfileConfigurePane';\nimport ProfilePane from './panes/ProfilePane';\n\nexport default function () {\n // The configure route must be registered first because otherwise there's a conflict between the two routes\n app.routes['fof-masquerade-configure-profile'] = {\n path: '/masquerade/configure',\n component: ProfileConfigurePane,\n };\n app.routes['fof-masquerade-view-profile'] = {\n path: '/masquerade/:username',\n component: ProfilePane,\n };\n\n extend(UserPage.prototype, 'navItems', function (items) {\n const isOwnProfileAndCanHaveMasquerade = app.forum.attribute('canHaveMasquerade') && app.session.user.id() === this.user.id();\n\n if (app.forum.attribute('canViewMasquerade') || isOwnProfileAndCanHaveMasquerade) {\n const href = isOwnProfileAndCanHaveMasquerade\n ? app.route('fof-masquerade-configure-profile')\n : app.route('fof-masquerade-view-profile', { username: this.user.username() });\n items.add(\n 'masquerade',\n LinkButton.component(\n {\n href,\n icon: 'far fa-id-card',\n },\n app.translator.trans('fof-masquerade.forum.buttons.view-profile')\n ),\n 200\n );\n }\n });\n}\n"],"sourceRoot":""} \ No newline at end of file