Jump to content

The mason's puzzle


Recommended Posts

Just recently, I passed by the Tempest Fort, and noticed a worrying issue. Moss! Some strange moss had invaded the walls. Its root penetrated the solid stone, and weakened its integrity! Unacceptable!

However, it seems that the stones available to patch up the walls is in short supply, and on top of that, they naturally form in difficult shapes. Thus, I'd like to employ your help, to find a way, to most efficiently replace the damaged walls.

The wall to be replaced could be modeled as a solid slate, of dimensions 8x8x3. There are various types of stones available:

  • Z, T and L shaped stones (volume of 4)
  • I shaped stones (volume of 2, or 1x2)
  • Singular, dot/square ( . ) shape stones, volume of 1

Your goal is to find a way to assemble the 8x8x3 walls using these materials. In general, based on scarcity of materials, I've assigned the tiles the following points:

  • Z shape: 4 points
  • T and L: 3 points
  • I: 1 points
  • dot: 0 points

The winning designs shall be rewarded handsomely. In particular:

  • The design with the highest score shall win 3 gold coins, and an anni creature
  • The second place, would be 2 gold coins, along with an anni creature
  • The third place, would be receiving 1 gold coin, and an anni creature

However, there's more!

I look not only for the design that has high point values. There's more to this challenge, than simply finding a single solution with a good point value. Artistry and beauty is a major aspect of masonry. I look also for designs that amazes me, regardless of how well they perform in the actual competition. In particular:

  • Designs with a certain mathematical "beauty" - whenever that be an absolute order, scalability, or an extremely chaotic, complex yet efficient pattern
  • Designs with fantastic demonstration and illustration, demonstrating a huge amount of effort & care
  • Etc.

In general, anything that amazes me greatly, would be rewarded with 1 WP. Your design does not need to achieve a high score to a WP, but a high score itself could certainly amazes me. There's no limited to how many winners, but there's no guarantee that there would be a winner as well.

Deadlines and submission guidelines:

Deadline:

  • You have until the end of anniversary (29th) to submit your design

Submission guideline:

  • You can submit your design in any manner that you like. Rather, coming up with a unique design AND presentation is part of the quest, at least for the WP portion
  • For clarity, I'd ask that you make three 8x8 squares and fill it with numbers. Squares with the same number should be occupied by the same "stone". You may also submit just this three squares as your submission.

Below are the shapes, in image form (with a thickness of 1), as I've been notified that there are confusions to the shapes. They're somewhat similar to tetris shape, as you can tell.

pieces.png

Edited by Demonic God
Link to comment
Share on other sites

  • 2 weeks later...

A bit late... o well. I'm not even sure why I made this, since most contestant drew their own thing xD. This is a tool to visualize what you made, and the scores you get... provided that it doesn't throw an error.

For those that likes tinkering around, this might be fun for you to poke around with :D

from graphics import *

BORDER_THICKNESS = 3
SQUARE_THICKNESS = 50

SHAPES = {
	'T_SHAPE':{
				frozenset({(0,0,0),(0,1,0),(0,2,0),(0,1,1)}),
				frozenset({(0,0,0),(0,0,1),(0,0,2),(0,1,1)}),
				frozenset({(0,0,1),(0,1,1),(0,2,1),(0,1,0)}),
				frozenset({(0,1,0),(0,1,1),(0,1,2),(0,0,1)})
			},
	'L_SHAPE':{
				frozenset({(0,0,0),(0,1,0),(0,2,0),(0,0,1)}),
				frozenset({(0,0,0),(0,1,0),(0,2,0),(0,2,1)}),
				frozenset({(0,0,0),(0,0,1),(0,0,2),(0,1,0)}),
				frozenset({(0,0,0),(0,0,1),(0,0,2),(0,1,2)}),
				frozenset({(0,0,1),(0,1,1),(0,2,1),(0,0,0)}),
				frozenset({(0,0,1),(0,1,1),(0,2,1),(0,2,0)}),
				frozenset({(0,1,0),(0,1,1),(0,1,2),(0,0,0)}),
				frozenset({(0,1,0),(0,1,1),(0,1,2),(0,0,2)})
			},
	'Z_SHAPE':{
				frozenset({(0,0,0),(0,1,0),(0,1,1),(0,2,1)}),
				frozenset({(0,0,1),(0,1,1),(0,1,0),(0,2,0)}),
				frozenset({(0,0,0),(0,0,1),(0,1,1),(0,1,2)}),
				frozenset({(0,1,0),(0,1,1),(0,0,1),(0,0,2)})
			},
	'I_SHAPE':{
				frozenset({(0,0,0),(0,1,0)}),
				frozenset({(0,0,0),(0,0,1)})
			},
	'DOT_SHAPE':{
				frozenset({(0,0,0)})
			}
}

POINTS = {
	'Z_SHAPE': 4,
	'T_SHAPE': 3,
	'L_SHAPE': 3,
	'I_SHAPE': 1,
	'DOT_SHAPE': 0
}

COLORS = {
	'Z_SHAPE': 'red',
	'T_SHAPE': 'green',
	'L_SHAPE': 'blue',
	'I_SHAPE': 'purple',
	'DOT_SHAPE': 'yellow',
	'BORDER': 'black'
}

def rotateFlat(shape):
	o = []	#re-order
	detect = [max(x) for x in [*zip(*shape)]]
	if detect[0] == 0:
		return shape # already flat
	elif detect[1] == 0:
		o = [1,0,2]
	elif detect[2] == 0:
		o = [2,1,0]
	else:
		raise Exception('Nonrotatable shape')

	return {(x[o[0]],x[o[1]],x[o[2]]) for x in shape}

def getSimplifiedShape(index, matrix):
	tiles = []
	for x,surface in enumerate(matrix):
		for y,line in enumerate(surface):
			for z,point in enumerate(line):
				if point == index:
					tiles.append([x,y,z])

	simplifier = [min(x) for x in [*zip(*tiles)]]	#Transpose to find min x y z
	simplified_shape = {(tile[0] - simplifier[0], tile[1] - simplifier[1], tile[2] - simplifier[2]) for tile in tiles}
	simplified_shape = rotateFlat(simplified_shape)

	return simplified_shape

def getShape(index, matrix):
	simplified_shape = getSimplifiedShape(index, matrix)
	for SHAPE in SHAPES:
		if simplified_shape in SHAPES[SHAPE]:
			return SHAPE
	else:
		print(f'Cannot find shape {simplified_shape}')
		raise Exception()

def getColor(matrix, layer, x, y):
	if isBorder(x,y):
		return COLORS['BORDER']
	elif isInnerBorder(x,y):
		if _isInnerBorder(x) and not _isInnerBorder(y):
			x, y = getIndex(x,y)
			index_1 = matrix[layer][y][x-1]
			index_2 = matrix[layer][y][x]
		elif _isInnerBorder(y) and not _isInnerBorder(x):
			x, y = getIndex(x,y)
			index_1 = matrix[layer][y-1][x]
			index_2 = matrix[layer][y][x]
		else:
			return COLORS['BORDER']

		if index_1 == index_2:
			shape = getShape(index_1, matrix)
			return COLORS[shape]
		else:
			return COLORS['BORDER']
	else:
		x, y = getIndex(x,y)
		index = matrix[layer][y][x]
		shape = getShape(index, matrix)
		return COLORS[shape]

def draw(matrix, offset_x = 30, offset_y = 30):
	size = BORDER_THICKNESS * 9 + SQUARE_THICKNESS * 8
	window = GraphWin(width = size * 3  + offset_x * 4, height = size + offset_y * 2 + 40)

	indexSet = set()
	score = 0
	for surface in matrix:
		for line in surface:
			for index in line:
				if index in indexSet:
					continue
				else:
					indexSet.add(index)
					score += POINTS[getShape(index, matrix)]

	message = Text(Point(window.getWidth() / 2 - 50, window.getHeight() - 40), f'Score: {score}')
	message.setTextColor('black')
	message.setSize(20)
	message.draw(window)

	for layer in range(3):
		for y in range(size):
			x = 0
			while x < size:
				color = getColor(matrix, layer, x, y)
				point_a = Point(x + offset_x * (layer + 1) + layer * size, y + offset_y)

				if color != COLORS['BORDER']:
					if _isInnerBorder(x):
						length = BORDER_THICKNESS
					else:
						length = SQUARE_THICKNESS
				elif _isBorder(y):
					length = size
				elif _isInnerBorder(x) or _isBorder(x):
					length = BORDER_THICKNESS
				else:
					length = SQUARE_THICKNESS

				point_b = Point(point_a.getX() + length	, point_a.getY())
				x += length
				line = Line(point_a, point_b)
				line.setFill(color)
				line.draw(window)


def _isBorder(x):
	return x < BORDER_THICKNESS or x >= ((BORDER_THICKNESS + SQUARE_THICKNESS) * 8)

def isBorder(x, y):
	return _isBorder(x) or _isBorder(y)

def _isInnerBorder(x):
	if _isBorder(x):
		return False

	while x >= BORDER_THICKNESS + SQUARE_THICKNESS:
		x -= BORDER_THICKNESS + SQUARE_THICKNESS
		if _isBorder(x):
			return True

	return False

def isInnerBorder(x,y):
	if isBorder(x,y):
		return False

	return _isInnerBorder(x) or _isInnerBorder(y)

def getIndex(x,y):
	return (x//(BORDER_THICKNESS + SQUARE_THICKNESS), y//(BORDER_THICKNESS + SQUARE_THICKNESS))

testArr = [
			[
				[0, 0, 1, 1, 1, 2, 2, 2],
				[3, 0, 0, 1, 4, 13, 14, 2],
				[3, 17, 18, 4, 4, 21, 22, 23],
				[24, 25, 26, 27, 4, 29, 30, 31],
				[32, 33, 34, 35, 36, 37, 38, 39],
				[40, 41, 42, 43, 44, 45, 46, 47],
				[48, 49, 50, 51, 52, 53, 54, 55],
				[56, 57, 58, 59, 60, 61, 62, 63]
			],
			[
				[64, 65, 66, 67, 68, 69, 70, 71],
				[72, 73, 74, 75, 76, 77, 78, 79],
				[80, 81, 82, 83, 84, 85, 86, 87],
				[88, 89, 90, 91, 92, 93, 94, 95],
				[96, 97, 98, 99, 100, 101, 102, 103],
				[104, 105, 106, 107, 108, 109, 110, 111],
				[112, 113, 114, 115, 116, 117, 118, 119],
				[120, 121, 122, 123, 124, 125, 126, 127]
			],
			[
				[128, 129, 130, 131, 132, 133, 134, 135],
				[136, 137, 138, 139, 140, 141, 142, 143],
				[144, 145, 146, 147, 148, 149, 150, 151],
				[152, 153, 154, 155, 156, 157, 158, 159],
				[160, 161, 162, 163, 164, 165, 166, 167],
				[168, 169, 170, 171, 172, 173, 174, 175],
				[176, 177, 178, 179, 180, 181, 182, 183],
				[184, 185, 186, 187, 188, 189, 190, 191]
			]
		]

# draw(testArr)
f = open("blocks.txt", "r", encoding="utf-8")
matrix = []
layer = []
for line in f:
	line.replace(';',' ').replace(',',' ')
	data = [int(x) for x in line.split()]
	if len(data) == 0:
		continue
	assert len(data) == 8
	layer.append(data)
	if len(layer) == 8:
		matrix.append(layer)
		layer = []

f.close()

draw(matrix)
input("Enter any key to quit.")

You'd need to have python + graphics.py installed. Make a text file, name it "blocks.txt", and it *should* work.

Here's an example of how "blocks.txt" should look like :D

0 0 1 1 1 2 2 2
3 0 0 1 4 13 14 2
3 17 18 4 4 21 22 23
24 25 26 27 4 29 30 31
32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47
48 49 50 51 52 53 54 55
56 57 58 59 60 61 62 63

64 65 66 67 68 69 70 71
72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87
88 89 90 91 92 93 94 95
96 97 98 99 100 101 102 103
104 105 106 107 108 109 110 111
112 113 114 115 116 117 118 119
120 121 122 123 124 125 126 127

128 129 130 131 132 133 134 135
136 137 138 139 140 141 142 143
144 145 146 147 148 149 150 151
152 153 154 155 156 157 158 159
160 161 162 163 164 165 166 167
168 169 170 171 172 173 174 175
176 177 178 179 180 181 182 183
184 185 186 187 188 189 190 191

If you don't get any of this... well, it's just a tool ~~that I made after Yoshi submitted numbers~~ that is kinda used to grade stuff.

I'll be making the grading script for the rock-paper-scissor game later, for those who wants to poke around with that too :D

Link to comment
Share on other sites

Posted (edited)

Here's a the results!

  1. @Aia del Mana - 188
  2. @Fyrd Argentus - 184
  3. @Yoshi - 181
  4. @Kaya - 181 (Yoshi submitted earlier)
  5. @Nepgear- 177
  6. @Jubaris - 174
  7. @Dracoloth - 165
  8. @Pipstickz - 164
  9. @Aelis - 160
  10. @Ungod - 116

Congratulations to the top masons!

In addition, @Aia del Manaand @Fyrd Argentusboth presented solutions that are quite fascinating. They both won a WP each! Congratulations!

Below are each player's submission, in order:

Edited by Demonic God
Link to comment
Share on other sites

3. Yoshi

submission.thumb.png.a94126cf79a36d5bcd846dd310cf62d0.png

The first submission (and so far... the only submission that used my suggestion of a numbering format. With multiple revisions. He himself was the reason why I made the python script for visualization and scoring xD.

(Note to Yoshi - you could've gotten 184 - and the second prize, as you did submit before Fyrd)

sub.thumb.png.402537d6cb0bac0991d84a638380e907.png

Link to comment
Share on other sites

10. Ungod

submission.png.04bb2ddcc93eb968e6a51c305bc62ef9.png

I'll... just assume I understand his schematics. It also seems that he's missing 6 empty spaces unaccounted for, if I'm reading his material summary correctly xD

Regardless, a very creative approach, that comes with some actual masonry reasoning! - had it come with some actual rocks and such, or a small scale physical model with some stones, I'd have awarded a wp :P

Link to comment
Share on other sites

1 hour ago, Demonic God said:

It also seems that he's missing 6 empty spaces unaccounted for

you're right, my description of the z stones is somewhat wrong (well, it works if I change the design for the middle sections, but...what I described and what I drew are different indeed)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Forum Statistics

    16.6k
    Total Topics
    179k
    Total Posts
  • Similar Content

    • By Demonic God
      This quest was originally ran during the 2020 anniversary - here.
      After nearly a year, I happened to discuss this quest with @Aia del Mana, who had generously offered to sponsor this into a permanent quest. In essence, the quest is identical, though, after it has proven to be of... quite high difficulty, the requirements has been reduced somewhat, and the rewards increased to reflect it.
      The quest will be, as following:
      A hunt for Darvin.
      Darvin, the advanced Aramor, had escaped into a new section of the labyrinth, and needs to be captured. This new section is a huge interconnected area, akin to a chessboard. Each turn, A25 holders, using their given A25 tools, freely teleports into a tile of their choosing. Each turn, Darvin surfs the heat current, moving to a different adjacent tile. He cannot move to tiles diagonal to his current location, as there would be no heatvein connecting the two square. He cannot remain still, as such is the nature that he was given. Each party action happen simultaneously. The tool holders and Darvin must move, at the same turn, to the same square, for Darvin to be considered "found". By chance, magic, or unknown mechanic within the realm itself, almost like quantum physics, he cannot be found unless, by deduction, he must be found. Should one seek him out at random, even how improbable it would be, he shall never be found. Noticing these rules, Chew deducted a simple way method: to organize a massive manhunt, placing players in every tile. Gets the job done, gets it done fast. However, Mur insist that the A25 tools may only be handed out to as few people as possible. To this end, find the methods needed, and the numbers of tools to hand out, to solve the following situations: 1. If the labyrinth size is 3x3. For this simple case, simply pointing out a correct pattern (with the minimum number of tools holders), would suffice. Those who solve this should expect a spell document to celebrate their success.
      2. If the labyrinth size is 5x5. A detailed mathematical proof, showing not only the pattern, but that it is indeed the minimum number of tool holder needed. A wishpoint will be rewarded.
      3. If the labyrinth size is unknown (n x n). A detailed mathematical proof, showing the pattern/rules is required. A single selection between a colored Winderwild, Elemental, or Pope, shall be rewarded. This is not first-come, first-served, anyone who managed to meet the requirements shall be rewarded all the same. I could provide aid and discussion if you want to challenge this - as this task is quite difficult.
      In mathematical terms (or simplified terms):
      Darvin will be on a chessboard-like grid. Each turn, he must move one tile, up, down, left or right. Each turn, you choose a number of squares to find Darvin. Actions happen simultaneously. Darvin is considered found, if he and you chose the same square. Darvin cannot be found at random. You must prove that he must be found using your pattern. Think of it as a strategy game, and that he knows your strategy from the very start. Find a pattern that he can't beat. You must find a pattern that requires the least amount of searches per turn. 1. Find the solution if the square is 3x3. No proof required, just the pattern. I've been authorized to grant you a spell-document should you submit a valid solution.
      2. Find the solution if the square is 5x5. Proof, including why the pattern is optimal (uses the least amount of searches per turn), is required. A wishpoint will be rewarded.
      3. Find the general solution for an n x n square, showing the pattern, as well as the proof for why it is optimal. Aid may be provided if requested. You may choose between a colored Winderwild, Elemental, or Pope as your reward.
      Rules:
      Solutions must be submitted in a private manner. Any private methods is acceptable, though I must warn that I do not check the ingame inbox often. Do not discuss, share, or collaborate. Please check your work thoroughly before submitting. If I feel like you're probing for the answer by having me pointing out mistakes, you may be disqualified. This applies mostly to reward 1, and somewhat for reward 2. To clarify, for task 2 and 3, a detailed proof of not only how the pattern will work, but also why you can't find Darvin with less tool holders will be required. For task 1, simply showing a pattern would suffice, without much explanation needed.
      If there's anything you need clarification on, feel free to DM or post a reply.
      Winners:
      Tier 1:
      @Aelis(as he finished it during the 2020 anniversary) @Kaya- May 7th, 2021 Tier 2:
      @Kaya- May 10th, 2021 Tier 3:
    • By Demonic God
      As you can tell from... the Darvin quest, I am a bit obsessed with Advanced Aramors!
      So, as part of an experiment, I would love to craft Aramors that are capable of doing more, on their own. To that end, I'd love to start with making Aramors that can, for now, participate in simple games of Rock Paper Scissors!
      Your goal for this quest, would be to aid me in making such a creation. Specifically, I ask for you to design a strategy, one that is unambiguous and non randomized. Something that an Aramor can be programmed with!
      Your strategy will compete with others in a tournament. The rules for the tournament is as follow:
      Every strategy will compete with every other strategy Each duel will last until one side receive 3 10 wins. If it is mathematically impossible exceeds 500 draws, both side receives a loss it's considered a draw. This was added because the 500 draws checker got tripped... a lot. The worst strategy will be eliminated after every duel has happened. This will repeat with the surviving strategies until one emerge victorious The worst strategy would be evaluated with the following criteria: Least wins Most losses Lose against strategies with similar win/loss (i.e if A has 2 wins and 5 losses, and B also has 2 wins and 5 losses, and B lost against A, then B is eliminated) If the above criteria fail to select a single loser, all of them would be eliminated The tournament will repeat without the winner(s) until all prizes are filled The rules for strategies are as follow:
      Your goal is to design a strategy, to participate in a tournament of rock, paper, scissors! Your strategy must not be random and must cover all scenarios. Your strategy is not limited to the game itself. It can adapt to the round it's on, the opponent, etc. Possible strategy includes: Always choose rock If there is less than 3 participant left, always choose rock If opponent is Aia, always choose rock Cooperation is not only allowed, it is welcomed. You are free to rig matches as you please. Rewards
      1st - Anniversary creature. A choice between a colored pope, and a colored elemental, courtesy of Lady @Aia del Mana 2nd - Anniversary creature. A colored pope or elemental, whichever remains after the winner had their pick 3rd -  Anniversary creature. Deadline:
      I wish to wrap up the competition as soon as everyone who wish to join had done so. Thus, there would be two deadlines:
      Hard deadline: End of anniversary + 3 days. Soft deadline: 9 days (April 21st) from now. After this date, I will begin judging as soon as everyone who had announced their participant has submitted their strategy. You may join in after the soft deadline, as long as judging has not begun. Soft deadline is meant to avoid unnecessary waiting.
    • By Granos
      Since nobody has posted anything I figured I would as today and tomorrow were suggested. Perhaps delaying a bit more to garner more interest may be needed. What server times work best for everyone. Personally I feel that 22:00 server time may work well.

      As for nominations:
      Mag and Aia are deserving of some recognition.

      Please suggest more times so we can come to a consensus for the ideal time.
      Please suggest more people for medals try to include which ones. 
    • By Demonic God
      The other day, I headed to the Golemus Laboratory, for some experimentation. Tinkering around, messing with the Aramors to-be-filled with AI cores.
      Alas, such work is boring! So boring indeed, that half way through, as my attention span dictate... I decided to make a very, very bouncy ball. A drop of blood, glue, rare minerals... and Voila!
      Throwing this thing in open space, would be unwise. Not that it would do any damages, but I prefer to not lose my shiny possessions. So, I had a small room built, and gave it a throw. Alas... I did not expect it to bounce so vigorously, the damn thing bounced so well, catching it would be impossible! As I ponder upon this dilemma, miraculously, the ball bounced straight back at me. Damn thing almost broke a tooth of mine, but I did managed to catch it. Impressed by this outcome, I laid down my pen and paper, and begins working out, how exactly did the ball bounce back to exactly where I was? And how many times, did that damn thing bounced around?
      So, I ask for your help, to determine the numbers of bounces the ball made. Here are the details of how it all went down - according to my memory:
      The ball somehow ignored gravity, and flew parallel to the ground at all times I started at the South-West corner of the room The ball was thrown perfectly North-East. (45 degree) The room is almost a square, of dimension 2020 cm x 2021 cm. I fully intend to sue the contractor for this error. Summarized in mathematical terms:
      You throw a perfectly bouncy ball in a rectangle (2020 x 2021) room from a corner The ball was thrown at a 45 degree angle The ball ignored gravity, and flew parallel to the ground at all time How many bounces did the ball make before it return to your location? Rewards:
      Most elegant solution - 1 Anni crit Most creative/unorthodox solution - 1 Anni crit Fastest correct solution - 1 GC All correct solutions - 5SC + 1 spell stone Lock in chaos Acoustic Remains Teleport to Papercabin
    • By Ungod
      I'll take this opportunity to warmly welcome all to Marind Bell, where for the next couple days you will be able to listen to minstrels singing about love and war (a.k.a. I will be posting link to various music pieces with the theme knights&maidens). I encourage visiting the more secluded areas.
      Love and battles. Epic battles, battles of dominance, battles of attrition, battles of retribution. Fiery love, withering love, useful love, used love. In this theme is the following riddle/puzzle, entirely a forum quest (hence the submissions will be by forum PM, to yours truly). Fastest correct answers win, and the prize pool is: 1g5s+anniv creature for 1st correct solution, 1g for 2nd, 5sc for 3rd. (you'll find the riddle quite easy):
      There is this tale I heard, a tale
      about a growing man
      who fends off heathen belief.
      A troll with hair of golden sheen
      smitten with this Christian youth
      besought him to endear her.
      He dared not approach her, in spite
      of nature's laws, despite her charm
      for he was Christian and she - a troll.
      He stared at the wooden cross
      heavy in his arm, preoccupied.
      His fate was questioned, and he uttered.
      'Begone', he said, and wail she did
      and ran away, cursing her fate
      for surely even trolls do understand -
      delivery's in God, in God Almighty.
      The bald priest smirked and gave a cry
      The light, and God, be given praise!
      This village, as the rest, will bathe in it.
      This tale shall be sung, for we will
      write it down for ages to come.
      What better way to reinforce our faith?!
      Herr Mannelig, the valiant knight of God,
      whose light is everreaching and all-wise,
      defeating the dark arts of trolls!
      And so the tale shall be woven
      And priests looked out for ink
      And priests took out young vellum
       
      (deadline is until the end of the anniv)
  • Recently Browsing

    No registered users viewing this page.

  • Upcoming Events

    No upcoming events found
  • Recent Event Reviews

×
×
  • Create New...