I checked the timing of my first commit on GitHub and it was 2014. I realized again that I had been making open source since then. I'm wondering if I've been doing it for almost 7 years, and at the same time I'm wondering if I've only been doing it for 7 years.
Well, let's set aside whether these 7 years are long or short for me, I would like to introduce ** what I got through open source development ** along with the products I developed.
The maiden product I distributed as open source to the whole world is the WordPress plugin "Custom DataBase Tables", commonly known as "CDBT". It was his first official WordPress plugin, and the concept was to implement database management tools such as phpMyAdmin and Adminer on the WordPress admin screen. Looking back on it now, I'm a fledgling WordPress plugin developer, but I'd like to praise him for his recklessness, saying that he suddenly released such a blockbuster plugin.
The hardest part of developing this plugin was ** my poor English ability **. I think that I passed the registration examination in the official repository well, but after the release, almost all the inquiries and bug reports received from users all over the world were in English, and the exchange was quite exhausted. I miss you. First of all, I can't understand the English text of the question, I can't reproduce the symptoms even if I struggle to read it, and even if I reply from here (of course, in poor English), it's hard to understand ... It took a long time, but the initial release version had many bugs and many issues. It was a product I developed as a hobby, but after returning home from the company I was working for at the time, I was frustrated by a kind of obsessive thing that I had to deal with the issue of this plug-in. I was about to get confused about English support several times, but only the number of downloads and the number of users who used it continued to grow, which kept me motivated. Is certain. By releasing and maintaining this plugin, it is certain that my English ability has improved dramatically. Now I don't have a hard time reading and writing English, and I'm not so bad at it. Conversation is probably not good at all, but I don't feel any problems when communicating via the internet or email. That said, my English reading and writing skills will only work for technical communication in a particular field. I think that my daily Frank vocabulary is still poor. Even so, it can be said that the acquisition of this English ability was tremendous in continuing open source development.
I still clearly remember the words I was told by a user in the "CDBT" development scene. "** Your English is scary. Please study more English **" (laughs) That should be the case, and at the time of version 1.x, "CDBT" had multilingual UI languages of "English" and "Japanese", but the English UI was operated by my poor English ability. It was terrible enough to cause dysfunction. It seems that it was better to use the Japanese UI while translating it by yourself to use it normally ... (bitter smile) By the way, this language deficiency has been resolved since version 2 (it can be said that my English ability has improved over a year).
This "CDBT" plugin was discontinued in version 2.1.34 about four years ago and is now a deprecated "death plugin" for use with the latest WordPress. However, a total of more than 70,000 downloads have been made, and the number of downloads is still increasing slightly, and there are more than 1000 active users currently using it. Somehow, it was once used by a department of NY City Hall, a Scandinavian airline, and a used car sales company in the Arab world (I have received inquiries and thanks for its operation). When I get this kind of response, I can realize that I am providing worldwide open source, and I get a sense of accomplishment.
I don't know when it will be, but "CDBT" is also a product that I would like to make version 3 in the future. In version 3, I definitely want to be able to use PostgreSQL as a WordPress DBMS ... or something.
The open source products I made, "CSS framework" sloth "" and "shortened URL generation service" forkor ", are UI, documents, comments in the source, content of the introduction page, etc. All notations are unified in English. This is because I think English should be the base language for products that are open source and distributed to the world. Basically, many engineers around the world can read English, and even people who are not good at English can read English. So ** the basic language of open source products should be English **. If you want to create UIs in other languages, it's best to make your product multilingual. Open source products with Japanese UI and Readme, etc. will not be noticed by engineers around the world, and there will be few opportunities for them to use them. In that case, issues will not be accumulated, and stability and expandability will be closed only by the collective intelligence of only a few users. If it is a product for Japanese people, it may be fixed in Japanese, but if it is announced to the world as open source, it is better to set aside a wide range of users to use it. It shouldn't happen.
It's a shame, but the recently released JS library of Japanese maps called "SVG Japan" is also unified in English except for the introduction page of my blog. This JS library currently supports only Japanese maps, but we are aiming for generalization so that it can also support world maps and regionalization of each country in the world in the future, and in anticipation of that, the document is written in English. (I'd like to make a map of China next time ...).
My personal opinion is that we should no longer develop products with a "Galapagos-like feeling" that is closed only in Japan.
The horizontal timeline generation JQuery plugin "jQuery.Timeline V2" is a product I released a long time ago, but it has been used for a long time. I have the most Stars among my GitHub products, so I have a lot of attachments. When developing and maintaining this product, I was keenly aware of the ** troublesome tense of the world **. Anyway, the tense in the world is so complicated and troublesome that I want the Japanese system to become the global standard. Let me introduce a part of how troublesome it is.
The time difference due to the time zone is quite cute compared to the summer time introduced next (although it is troublesome ...). The time zone is the value of how much time difference from Coordinated Universal Time (UTC), and in Japan there is a time difference of +9 hours. Well, if you are an engineer who is involved in system development, there is no one who does not know the time zone, and if it is a product that operates in the same time zone, it is not a mechanism to be so conscious. However, if you are developing open source products that are not border-aware, especially products that handle tenses, you must design and implement processing that takes into consideration cooperation with different time zone regions. For example, especially in a country with a large land area such as the United States, the time zone changes between the eastern part, the central part, the mountainous part, and the western part, so it is necessary to take this into consideration when creating tense processing.
PHP
function show_dt( string $datetime_string ): array {
$_dt = [];
$timezones = [
'UTC',
'America/New_York', // Eastern
'America/Chicago', // Central
'America/Denver', // Mountain
'America/Los_Angeles',// Pacific
'America/Anchorage', // Alaska
'America/Adak', // Hawaii
'Asia/Tokyo',
'Australia/Sydney',
'Europe/Berlin',
'Europe/London',
'GMT',
];
foreach ( $timezones as $tz ) {
$date = new DateTime( $datetime_string, new DateTimeZone( $tz ) );
$_dt[$tz] = $date->format( DATE_RFC2822 );
}
return $_dt;
}
This is the result of trying to get the current time with now
with the above function that can get the date and time for each time zone by giving the date and time character string.
PHP
var_export( show_dt( 'now' ) );// now: 2020/12/18 14:07:06 JST
/*result
array (
'UTC' => 'Fri, 18 Dec 2020 05:07:06 +0000',
'America/New_York' => 'Fri, 18 Dec 2020 00:07:06 -0500',
'America/Chicago' => 'Thu, 17 Dec 2020 23:07:06 -0600',
'America/Denver' => 'Thu, 17 Dec 2020 22:07:06 -0700',
'America/Los_Angeles' => 'Thu, 17 Dec 2020 21:07:06 -0800',
'America/Anchorage' => 'Thu, 17 Dec 2020 20:07:06 -0900',
'America/Adak' => 'Thu, 17 Dec 2020 19:07:06 -1000',
'Asia/Tokyo' => 'Fri, 18 Dec 2020 14:07:06 +0900',
'Australia/Sydney' => 'Fri, 18 Dec 2020 16:07:06 +1100',
'Europe/Berlin' => 'Fri, 18 Dec 2020 06:07:06 +0100',
'Europe/London' => 'Fri, 18 Dec 2020 05:07:06 +0000',
'GMT' => 'Fri, 18 Dec 2020 05:07:06 +0000',
)
*/
In the United States, you can see that there is a considerable time difference in Japan alone. For example, when managing the same tense event in a company with offices in New York and Hawaii, if the registration process of the event is written to the DB in the local tense of the registration point, there will be a time difference in the handling of the tense event between multiple points. Will end up doing. In order to avoid this, it is necessary to unify all internal tenses handled in the DB and application to UTC and design to filter to the local tense only when outputting to the front end.
If it is a product that is used only in Japan, the time zone can be fixed to Asia/Tokyo
in the application, so you do not have to be careful about the time zone, but the user Design and processing suddenly become complicated when each use case has a different time zone. When developing open source, the key points in that area are trained.
The most troublesome is daylight saving time (DST). Although the number of countries and regions that have been abolished has increased in recent years, it is used in many countries including the United States, and this concept is no longer close to ** another dimension **. Daylight saving time is a mechanism that advances some time during a certain period of a day with long daylight hours called daylight saving time, and returns the time advanced at the end of daylight saving time. The time to proceed varies from region to region, with some 30 minutes and 1 hour. The implementation period also varies from region to region and changes every year. It is the worst mechanism that makes me think that it is systematically broken, and it is also the source of chaos for tense. Recently, the number of places such as the EU that abolish the system itself is increasing, so I sincerely hope that it will be eradicated (I think that it will not happen because it is a system adopted in many countries ...).
Daylight saving time increases at the beginning of daylight saving time. In other words, only on the start date, the day will be 24 hours 30 minutes or 25 hours instead of 24 hours. And at the end of daylight savings time, there is less time and less than 24 hours a day. For products that handle tense, this process that straddles the chasm day is a demon. In other words, if you do not calculate the interval between two points in consideration of the features of this summer time, unintended problems such as disappearance of events or time lag will occur. I also remember that a problem that occurred from this summer time was pointed out by a user in the UK on jQuery.Timeline, and I changed the time zone of the development machine to GMT (Greenwich Mean Time ≒ time zone in the UK) and struggled to deal with it. ..
In the United States, there are some areas that have daylight saving time and some areas that do not have daylight saving time even within the same time zone, so if I were developing a scheduler for the United States, my heart might be broken ... w
For example, if you add the type with or without daylight saving time to the time zone of the American Mountains and Hawaii to the previous show_dt ()
function, it will be as follows.
PHP
$timezones = [
'UTC',
'America/New_York', // Eastern
'America/Chicago', // Central
'America/Denver', // Mountain
'America/Phoenix', // Mountain no DST
'America/Los_Angeles',// Pacific
'America/Anchorage', // Alaska
'America/Adak', // Hawaii
'Pacific/Honolulu', // Hawaii no DST
'Asia/Tokyo',
'Australia/Sydney',
'Europe/Berlin',
'Europe/London',
'GMT',
];
Denver and Phoenix belong to the same time zone, but the time difference during daylight saving time changes depending on the presence or absence of daylight saving time. By the way, this year's 2020 summer time in the United States started at 2:00 on 3/8 and ended at 11:12:00, so let's display the time at each timing.
PHP
var_export( show_dt( '2020-3-8 2:00' ) );
/*result:Denver is 3/8 1:59:Time difference up to 59-Same as Phoenix in 7 hours
array (
'UTC' => 'Sun, 08 Mar 2020 02:00:00 +0000',
'America/New_York' => 'Sun, 08 Mar 2020 03:00:00 -0400',
'America/Chicago' => 'Sun, 08 Mar 2020 03:00:00 -0500',
'America/Denver' => 'Sun, 08 Mar 2020 03:00:00 -0600',
'America/Phoenix' => 'Sun, 08 Mar 2020 02:00:00 -0700',
'America/Los_Angeles' => 'Sun, 08 Mar 2020 03:00:00 -0700',
'America/Anchorage' => 'Sun, 08 Mar 2020 03:00:00 -0800',
'America/Adak' => 'Sun, 08 Mar 2020 03:00:00 -0900',
'Pacific/Honolulu' => 'Sun, 08 Mar 2020 02:00:00 -1000',
'Asia/Tokyo' => 'Sun, 08 Mar 2020 02:00:00 +0900',
'Australia/Sydney' => 'Sun, 08 Mar 2020 02:00:00 +1100',
'Europe/Berlin' => 'Sun, 08 Mar 2020 02:00:00 +0100',
'Europe/London' => 'Sun, 08 Mar 2020 02:00:00 +0000',
'GMT' => 'Sun, 08 Mar 2020 02:00:00 +0000',
)
*/
var_export( show_dt( '2020-11-1 2:00' ) );
/*result:Phoenix and Honolulu have no change in time difference before and after daylight saving time
array (
'UTC' => 'Sun, 01 Nov 2020 02:00:00 +0000',
'America/New_York' => 'Sun, 01 Nov 2020 02:00:00 -0500',
'America/Chicago' => 'Sun, 01 Nov 2020 02:00:00 -0600',
'America/Denver' => 'Sun, 01 Nov 2020 02:00:00 -0700',
'America/Phoenix' => 'Sun, 01 Nov 2020 02:00:00 -0700',
'America/Los_Angeles' => 'Sun, 01 Nov 2020 02:00:00 -0800',
'America/Anchorage' => 'Sun, 01 Nov 2020 02:00:00 -0900',
'America/Adak' => 'Sun, 01 Nov 2020 02:00:00 -1000',
'Pacific/Honolulu' => 'Sun, 01 Nov 2020 02:00:00 -1000',
'Asia/Tokyo' => 'Sun, 01 Nov 2020 02:00:00 +0900',
'Australia/Sydney' => 'Sun, 01 Nov 2020 02:00:00 +1100',
'Europe/Berlin' => 'Sun, 01 Nov 2020 02:00:00 +0100',
'Europe/London' => 'Sun, 01 Nov 2020 02:00:00 +0000',
'GMT' => 'Sun, 01 Nov 2020 02:00:00 +0000',
)
*/
No, it's chaos ... I can see how much time is a non-logical system, and it is just a product of human ego. Western engineers are already accustomed to this kind of chaotic tense, so it may be that they have high productivity and development capabilities.
This is not a global tense issue, but a language-specific tense specification issue such as PHP or JavaScript. The DateTime and Date classes, which are tense objects in PHP and JavaScript, have a non-trivial specification that automatically maps two-digit years to 1900 to 2069. For example, in JavaScript, Date.getFullYear ()
and Date. Even if you do your best to avoid this automatic mapping by using setFullYear ()
, it often happens that the automatic mapping is performed by some internal processing and the desired result cannot be obtained as soon as the tense calculation is performed. Occur.
PHP
$date = new DateTime( '1-1-1' );
var_dump( $date->format( 'Y-m-d' ) );
// string(10) "2001-01-01"
$date = new DateTime( '69-1-1' );
// string(10) "2069-01-01"
var_dump( $date->format( 'Y-m-d' ) );
$date = new DateTime( '70-1-1' );
var_dump( $date->format( 'Y-m-d' ) );
// string(10) "1970-01-01"
$date = new DateTime( '99-1-1' );
var_dump( $date->format( 'Y-m-d' ) );
// string(10) "1999-01-01"
PHP maps the years 1-69 to 2001-2069 and the years 70-99 to 1970-1999.
JavaScript
[ 0, 1, 69, 70, 99, 100 ].forEach((y) => {
let dt = new Date( y, 0 )
console.log(`${y}: ${dt}`)
})
/*result:JavaScript is mapped between 1900 and 1999
0: Mon Jan 01 1900 00:00:00 GMT+0900 (Japan Standard Time)
1: Tue Jan 01 1901 00:00:00 GMT+0900 (Japan Standard Time)
69: Wed Jan 01 1969 00:00:00 GMT+0900 (Japan Standard Time)
70: Thu Jan 01 1970 00:00:00 GMT+0900 (Japan Standard Time)
99: Fri Jan 01 1999 00:00:00 GMT+0900 (Japan Standard Time)
100: Fri Jan 01 0100 00:00:00 GMT+0918 (Japan Standard Time)
*/
In JavaScript, 1-2 digit years are mapped from 1900 to 1999. Furthermore, if you define the year argument as a string type instead of a number ...
JavaScript
for(let y=0; y<=100; y++) {
let dt = new Date( y.toString() )//No month specified
console.log(`${y}: ${dt}`)
}
//The result is ... pretty chaos w
The result of the above sample is quite chaotic, so if you are interested, please try it (laugh)
By the way, in Ruby,
Ruby
require "date"
for year in 0..100 do
dt = Date.new(year)
puts dt
end
/*result:Yes, you want this kind of result ...
0000-01-01
0001-01-01
:
0099-01-01
0100-01-01
*/
──The expected result is obtained.
Basically, products that handle tenses from 1 to 99 AD are not needed so much in the practical scene, so the problem may not be obvious, but for general purposes like my jQuery.Timeline If there is a need for open source that supports from the past tense to the future tense, it may be necessary to respond. Well, it depends on the open source author's policy how much to deal with, so there is an option to cut off needs that are too niche without incorporating them into the core. The good thing about open source is that there is a fork in case you really want to deal with it.
This is a problem I've found only with JavaScript Date objects so far. Perhaps it's a core bug? If the time zone of the system is GMT (Greenwich Mean Time ≒ UTC), 1 minute 15 seconds from 0: 0: 0 to 0: 1: 15 on December 1, 1847 will disappear. See the script below.
JavaScript
let DateLoc = new Date(1847,0,1,0,0,0),//Specified date and time: 1847/1/1 0:0:0
DateLoc1 = new Date(1847,10,30,23,59,59),//Specified date and time: 1847/11/30 23:59:59
DateLoc2 = new Date(1847,11,1,0,0,0) //Specified date and time: 1847/12/1 0:0:0
console.log(`loc : ${DateLoc.toString()}`)
console.log(`loc1: ${DateLoc1.toString()}`)
console.log(`loc2: ${DateLoc2.toString()}`)
/*result:
loc : Fri Jan 01 1847 00:00:00 GMT-0001 (Greenwich Mean Time)
loc1: Tue Nov 30 1847 23:59:59 GMT-0001 (Greenwich Mean Time)
loc2: Wed Dec 01 1847 00:01:15 GMT+0000 (Greenwich Mean Time)
*/
After December 1, 1847, it synchronizes with UTC, but there is a mysterious phenomenon that always causes a time difference of 1 minute 15 seconds from Coordinated Universal Time (UTC) at Greenwich Mean Time before November 30, 1847. That's right. Moreover, in the GMT time zone, the time added by 1 minute 15 seconds is returned during the period of 1 minute 15 seconds from 0: 0: 0.0 to 0: 1: 14.999 on December 1, 1847. This time difference is not resolved by going back to 0: 0: 0 on January 1, 1847, which means that GMT has lost 1 minute and 15 seconds on December 1, 1847. In my spare time, I did a little research to see if it was a bug or something historically caused, but I wasn't sure. ** What happened in England that day! ?? ** It's a mystery in JavaScript, and it's interesting because it seems to be a chuunibyo story, but for me who makes a tense-related library with JavaScript, it's one of the fucking specifications that I want you to forgive. is there.
Furthermore, there is such a mystery-like thing in Japan Standard Time (JST). In Japan, it is as follows.
JavaScript
let DateLoc = new Date(1888,0,1,0,0,0), //Specified date and time: 1888/1/1 0:0:0
DateLoc1 = new Date(1888,0,1,0,18,58,999), //Specified date and time: 1888/1/1 0:18:58.999
DateLoc2 = new Date(1888,0,1,0,18,59,0), //Specified date and time: 1888/1/1 0:18:59.0
optJST = { hour12: false, timeZone: 'JST', timeZoneName: 'short', era: 'long' }
console.log(`loc : ${DateLoc.toString()}`)
console.log(`loc1: ${DateLoc1.toString()}`)
console.log(`loc2: ${DateLoc2.toString()}`)
console.log(`JST : ${DateLoc.toLocaleString('ja-JP-u-ca-japanese', optJST)}`)
console.log(`JST1: ${DateLoc1.toLocaleString('ja-JP-u-ca-japanese', optJST)}`)
console.log(`JST2: ${DateLoc2.toLocaleString('ja-JP-u-ca-japanese', optJST)}`)
/*
loc : Sun Jan 01 1888 00:00:00 GMT+0918 (Japan Standard Time)
loc1: Sun Jan 01 1888 00:18:58 GMT+0918 (Japan Standard Time)
loc2: Sun Jan 01 1888 00:18:59 GMT+0900 (Japan Standard Time)
JST :January 1, 1891 0:00:00 GMT+9:18:59
JST1:January 1, 1891 0:18:58 GMT+9:18:59
JST2:January 1, 1891 0:18:59 GMT+9
*/
Before 0:18:59 on January 1, 1888 (Meiji 21), the time difference in Japan's time zone increases by 18 minutes and 59 seconds. Unlike the Greenwich Mean Time mystery, there is no loss of time. The reason for this is that Japan Standard Time was implemented at this timing. Before the JST was implemented, the time zone time difference in Japan was 9 hours 18 minutes 59 seconds. Well, I can understand it because of the historical background, but when it comes to applying this specification to the tense system, when it fluctuates when interval calculation etc. is performed at the time between two points around January 1, 1888. If the difference is not taken into consideration, a time lag will occur. By the way, PHP does not have this 18 minutes 59 seconds time difference, and JST's time zone time difference is uniformly +9 hours. Like JavaScript, Ruby has a time difference of +9 hours 18 minutes 59 seconds before 0:18:59 1888.
Not limited to open source development, it is important to know that the tense specifications for each language are so different. Accumulation of such knowledge will come in handy as a development skill.
──By the way, "jQuery.Timeline" introduced in this section is currently under development for Vanilla JS (native JavaScript) version. Because I want to use it on a Vue.js site without jQuery.
The WEB / ITC industry is changing rapidly. The technology that was popular last year will soon become a legacy, and the latest, more efficient technology will emerge. Under such circumstances, as we continue to develop open source products, we want to adopt new technologies for new products. And you'll want to refactor your published products by introducing new technologies to make them easier to maintain. To do that, ** never stop "learning" **.
At the time of 2014, JavaScript and CSS that were created for each browser to support cross-browser, now if you transpile with Babel or sass/scss, you do not have to worry about client differences at the time of development, and the document is If you write a comment in the source, it will be automatically deployed from there with ESDoc etc., and if you do test-driven development with Jest etc., the speed of the development cycle will become faster and faster. Of course, in order to use these new technologies, it is necessary to learn them each time. But if you don't stop "learning", you will be able to continue developing on the front lines forever.
In my case, I often realize that I can only master the technology by applying the basics I have learned. Completing a product is the culmination of its application. If you only know the basics of the tutorial, you can't say that you can use the technology. Not limited to open source, creating or recreating a product in a modern way brings many technical benefits to you. And products that continue to be metabolized will continue to be used persistently.
I've been making open source for many years and have received some donations. If you're announcing open source, you should only have an entrance to accept donations, regardless of whether you get donations. If you are on GitHub, you can set up a GitHub Sponsor link if you apply, so if you are publishing a product on GitHub, you should definitely set it up.
Overseas users have little resistance to donating when they come across a product that is beneficial to them. There are surprisingly many opportunities for donations regardless of the amount. If you donate, the motivation for development will increase considerably, so it can be said that it is a great contribution to product improvement and continuous maintenance. It would be a waste not to set up the window.
By the way, until now, I have received donations from Japanese people only once. Japanese people don't have much custom to donate, and there is a big cultural influence because the remittance between individuals is regulated by domestic law .... (PayPal is still not able to donate in Japan. I'm doing it). Even so, recently it has become possible to send money via LINE, and it seems that the threshold around that point has been lowered. There is also crowdfunding, so it may be good to find a method that suits you. However, don't expect too much from donations, as many people around the world will not feel like donating to open source products that are originally free to use.
Rather than open source development, publishing products on GitHub often leads to job offers, job change invitations, headhunting, and more. It also comes from all over the world. I'm a freelancer and live my favorite right now, so my forefinger rarely moves when I get an offer, but if I come across these offers while working for a company, I'm sure to consider them. Would have been.
Creating and publishing open source products yourself is directly linked to your portfolio as an engineer, so if you want to work in the industry, it's worth the challenge.
In addition, there are some job support services that aggregate individual development skills including the activities of GitHub, so if you are doing something on GitHub, registering for those services is also an offer promotion. It's a good way. I also register for the following three services for the purpose of visualizing my skills. It's easy because you can sign up for free with your GitHub account.
** Job change site that scores engineer skills **
Using these services, it would be a great advantage to know how much your skills are in the industry from a third-party perspective. Well, if you are free and are not interested in getting a job like me, you can set the status to "I am not interested in changing jobs", suppress notifications and solicitations as much as possible, and use it as a reference index. Kato.
** Freelance job matching site **
Findy Freelance simulates the index of the minimum time unit price from the deviation value of the scored engineer skill, so it can be conveniently used to set the estimated unit price when working free. By the way, I basically do not accept jobs whose evaluation is lower than the minimum unit price calculated here.
It is difficult to eat only by developing open source unless the product is buzzed. However, this is much cheaper in terms of initial investment than creating a web service etc. by yourself and buzzing it, there is no criticism for launching a failed work, and as long as ideas and motivation continue But I think there are many low-risk benefits that you can challenge.
In the case of services, once launched, operating costs such as regular marketing, member support, and server operating costs will increase steadily. Well, as long as you get on track, you can eat by itself, so I think that the direction of creating new services is the right direction for an entrepreneur.
If you are doing free engineering, I think that, in the extreme, you have to either develop services and shift to the management side, or continue to work as an active engineer on the craftsmanship route. Ultimately, if the former succeeds, it will be a million years old. In the latter case, it seems like a lot of roses to stay active all life. However, if a large number of products are created, there is a great possibility that a product with potential will be forked and turned into a service.
Perhaps it's very beneficial for engineers to keep making something, not just open source, and it's not wrong. So there is one thing I can say.
** Now, let's make a product! ** **
Recommended Posts