text:
← SRNT believes research should be replicated (when they don't like the results)
Newsflash: Tobacco companies are incredibly timid →
A give-and-take on censoring ecig research that gets almost everything wrong
Posted on 28 February 2016 by Carl V Phillips | 5 Comments
I have watched with some amusement the swirl of attention around this op-ed (for that is what it is) by Jim McCambridge, in the journal Addiction, calling for further censorship of THR research, and this response to it in a blog post by Neil McKeganey and Christopher Russell. My amusement is first because it seems like this exchange feels like it was written 15 years ago and second because of the huge oversights by all involved.
It is hardly worth recounting the content of the McCambridge piece because anyone who follows these issues has read it all dozens of times before. He is calling for a ban on publishing of e-cigarette research that is funded by industry. (Publishing by whom? Great question. Read on.) This, of course, is based entirely on hand-waving innuendo about misleading cigarette industry research from c.1970. He admits, in the most opaque way possible, that there is no evidence that this is still occurring. He fails to note that this is also true about the last four decades.
McCambridge extends this to full-on McCarthyism about anyone who has ever done research associated with industry. How much research would this have to be in order to disqualify? What type of relationship counts? He does not say, of course, because that would require trying to justify his position based on some stated goal, which he never attempts to do. He could not. Does the industry he is seeking to censor include just those e-cigarette manufacturers who existed as corporate entities in 1970, or does it also include the new wave of e-cigarette companies? He does not say, because that would require introducing actual substance to his diatribe. (It is largely moot right now, since the latter do not do or support much research, but that will presumably change.)
As much as I panned the facile and ham-handed discussion of conflict of interest by Marcus Munafo in the pages of Nicotine & Tobacco Research a few days ago, McCambridge's drivel makes Munafo look almost scholarly by comparison. The Addiction piece has literally no analytic content; it is just a statement of personal pique peppered with some references that are used as in a middle school term paper, as pro forma decoration rather than analysis.
So that brings up the unseen elephant in the room: Why did Addiction editor Robert West decide to publish this boring and content-free statement of one extremist's personal politics? The only apparent explanation is that it is a trial balloon, to see which way the wind blows on this before deciding whether Addiction will join in the attempted censorship. This is standard practice for political actors (and obviously this is all about politics; it has nothing to do with science), to have some supposedly respectable outsider endorse what they are considering doing, in order to see what the reaction is before they commit.
Now I am not entirely sure whose reaction West is interested in observing. It is not exactly a mystery that the "public health" people will come down in favor of trying to censor any research that is not sanctioned by Public Health Inc. It is equally clear that anyone who cares about science and real ethics will oppose it. I can only surmise that the target audience consists of the couple of hundred "public health" people who have embraced e-cigarettes (only as a tool to be imposed on smokers to get them to quit smoking, of course) but still cling to the illiberal and anti-scientific Tobacco Control Industry mindset.
It is amusing to note what no one in these discussions seems to notice: This type of censorship only hurts "public health" people. What happens if the public health journals censor industry research from their pages? It gets published in scientific journals instead. The work coming out of industry research shops is almost all straightforward real science, and legitimate journals that publish research of the particular type are not going to join in the censorship. A handful of them might succumb to some editor's personal pique or outside political pressure, but there are plenty of other options. There are fewer, but still enough, options for the (relatively rare) pieces coming out of those shops that do not fit within a standard scientific discipline (e.g., big-picture analyses of harm reduction).
All moves like this "accomplish" are keeping the best science out of the pages of public health journals (for the major companies do almost all the good lab science in the field, and higher-quality epidemiology). This lowers the average quality of those journals, as is often noted. But it also keeps public health people, who are not exactly known for reading broadly, from learning what the industry has to say. Industry employees and outside researchers that are closely tied to industry do not blog. They do not comment on posts or articles, except for very technical points. They do not tack on unrelated editorial wanderings to their papers in scientific journals.
Does this mean that their big-picture analyses and political opinions never have any influence? Um, yeah.
What is truly hilarious is that the same "public health" people who scream about the enormous influence that industry has — thanks to their private and semi-private communications channels with the oligarchy — think that censoring them out of journal pages is a good move. If "public health" people understood any tactics other than using propaganda and brute force power via their control of government agencies, or even if they just understood the implications of their own rhetoric, they would be trying to sucker industry actors into publishing every study report, analysis, or commentary they wanted in public health journals. That way the "public health" people would actually get a good look at it, and be able to respond in a context where they have the upper hand (e.g., by soliciting real-time rebuttals or forcing authors to insert material into their papers). But because they are so far up their own…um, echo chamber, they think that it is a win to prevent this. They actually think their journals are just so important that putting such material on their own pages, instead of forcing it to be communicated out of their sight or control, would hurt their cause.
So if industry itself is not hurt by the censorship, who is hurt? It is the individual independent researchers who are targeted by the McCarthyist tactics. Researchers who are employed by industry or do most of their work on behalf of industry are untouched for the reasons noted above. The only ones hurt are those honest scientists wish to be part of the "public health" club — for whatever reason — but also want to take advantage of possible opportunities to get industry funding for their research. In this sense, the ad hominem attacks are a win for the "public health" extremists, in that they do keep some of their own people too scared to risk their academic and government dole by stepping out of line and doing unapproved research. But those who end up getting punished are still their own peeps.
(Notice, by the way, that this observation, combined with my assessment of who the trial balloon was targeted at, suggest that the balloon is going to crash.)
McKeganey and Russell are two of those targeted by the McCarthyist attack, as independent researchers who have taken industry funding. They make several good points including the very nice observation,
When it comes to assessing the health harm and public health benefits of e-cigarettes McCambridge must feel we are in a world of excess knowledge that he should so comprehensively discard research solely on the basis of the funding received.
This is a great line, though I cannot tell whether they really believe this was an oversight on McCambridge's part, or whether it is the clever tactic of making a disingenuous statement you know your opponents dare not question. Of course, "public health" people like McCambridge do not consider minimizing the available knowledge to be a bug. To them it is a feature, though they cannot admit that. Their goals benefit from there being genuine uncertainty about e-cigarettes, and it certainly benefit from the predominant "research" on the topic being the junk-science that they produce. Excess knowledge is not on their side, and they know it.
Of course, this point is largely moot due to what I mentioned above: Keeping the good science out of Addiction and a few other journals is not going to stop it from being done. It will merely inconvenience public health people.
The amusing part about McKeganey and Russell is their suggestions that there is something even slightly new about this, with phrases including (emphasis added):
"the rise of academic McCarthyism"… "new McCarthyism" … "danger of creating an academic environment in which allegation or suspicion has supplanted proof when it comes to scientific misconduct" … "dangerous waters"
Um, yeah. Allow me to call attention to just a few of the papers I wrote or edited on this topic a decade ago. (In one of those papers, the author suggests that McCarthy is really not a strong enough metaphor, and that Lysenko/Stalin is more to the point.) There are, of course, many more such papers by many authors, responding to exactly this particular McCarthyism, dating back another decade before that. Or you can look at the archives of this blog, or of my previous blogs. Or those of dozens of others who have been writing on this topic.
McKeganey and Russell make the observation,
There is a real danger here of creating [sic] an academic environment in which allegation or suspicion has supplanted proof when it comes to scientific misconduct. The clearest example of this is contained within McCambridge's own published commentary in which he acknowledges that he is not aware of evidence that the pharmaceutical industry has engaged in the same past misconduct as the tobacco industry. Yet, he says, he would not be surprised if this were the case, and he then goes on to offer a range of possible mechanisms though which the very thing he has acknowledged he has no proof is occurring may be taking place. Suspicion has assumed primacy over evidence.
I think it gives far too much credit to the perpetrators responsible for this (extant!) toxic environment to suggest it is about genuine suspicion. This seems to be a case of getting sucked into the extremists' rhetoric and thereby endorsing it by implication. Just because someone can make up a hypothetical, it does not qualify as genuine suspicion. For every legend about events in the world, there is some nutcase who is "suspicious" that it is true. To treat this as anything other than pure bullying, motivated by the outcomes it produces rather than the rhetoric used to sell it, is to have already conceded most of the fight. (Oh, and anyone who genuinely wonders whether the pharmaceutical industry has gone to great, often nefarious, lengths to skew the literature in their favor is really far up his own echo chamber.)
What is missing from the McKeganey and Russell response is the most important point in all of this, that there is massive undeclared and unexamined — but incredibly obvious — conflict of interest present in non-industry research. "Public health" people produce boatloads of junk science that is designed specifically to further their special-interest politics. This blatant conflict of interest dwarfs any effects of industry funding. If you want to look for the "clearest example" of dishonesty and bad intentions "contained within McCambridge's own published commentary", it is not in the text, but in his own conflict of interest statement, in which he declares: "None." Yes, what possible conflict of interest could there be in someone's attempt to censor his political opponents and to make sure that his own faction and their funders have a monopoly on deciding what research is done?
[Update: An early reader suggested that I had not really made my case for the title of this post. I realized that I agree, that I had not clearly built up the thesis. So here is what I had in mind but never managed to say: There are legitimate concerns about industry-funded research, particularly it being used anti-competitively. For example, big companies with more resources can do research designed to suggest that their product might be a little bit less harmful than competing products — as with a closed-system e-cigarette with very limited ingredients versus less controlled systems — and the no one is in a position to respond effectively. This, unlike them producing falsified results, is a legitimate concern. But it is never mentioned by the would-be censors. The rebuttal post missed the biggest point, about COI among non-industry researchers, as I noted, and suggested this is some emerging problem rather than an ongoing extant problem. But my other concern was that it lent unwarranted legitimacy to the attacks, trying to debate the details and express concern about what it implied were unintended harms, rather than calling out the attacks for what they really are and recognizing that those harms are goals. These observations, plus the various elephants that no one seemed to even notice, are the basis for the title.]
Finally, it is worth noting that the single concrete example McCarthy… er, McCambridge mentions [I really did type that Freudian slip] is the Nutt et al. paper that consisted of made-up estimates of the harms from various tobacco products and associated non-tobacco products. This has become a favorite for the McCarthyists because some of the people involved with making up the numbers had received industry funding in the past and did not bother to mention it. As I have explained at length, the numbers from that paper come not from any scientific process, but from a bunch of people getting together and pulling them out of thin air. Many of the claims resulting from that "process" are utterly absurd on their face.
But the paper does serve one useful purpose: The obsession with the industry funding points out the utter scientific and intellectual vacuousness of public health. "Public health" people do not like the paper because it dares claim that there are lower-risk tobacco products (even though they should really love it because it grossly overstates the risks for those products, putting them at levels that actually support many anti-THR positions — as I said, they understand little about tactics). So they have been campaigning to discredit it. There are a host of grounds for criticizing that paper — indeed, more than there are for most anti-THR junk science papers — most notably that it is just a bunch of made-up numbers that should never be cited as evidence of anything. But this does not seem to bother the public health people, apparently because they simply do not recognize that making up numbers is problem. So instead their entire line of attack is ad hominem.
If you try to explain that — or any of the other oversights and absurdities noted above — to a thinking person who is not familiar with the behavior of "public health", their first reaction is often that you must be joking. Discussions of scientific integrity in this field are self-parodies. At least that makes them, like the campaign for the Republican POTUS nomination, good for some amusement and interesting substantive analysis — so long as you can force yourself to view them from the outside and ignore the worldly impacts they have. However, the other thing these discussions have in common with that nomination race is that the substantive analysis plays no apparent role in the battle, and that perhaps the only viable tactic is ridicule.
This entry was posted in truths and tagged COI, peer review. Bookmark the permalink.
5 responses to "A give-and-take on censoring ecig research that gets almost everything wrong"
Pingback: Tobacco Industry Funded E-Cigarette Research and the Rise of Academic McCarthyism
natepickering | 29 February 2016 at 8:52 pm | Reply
If "industry funding" is a poison pill that invalidates all such research, are we left with anything valid?
Carl V Phillips | 29 February 2016 at 9:10 pm | Reply
[Edit: No, that is too glib. The anti-THR research funded by government and their cronies is generally not to be trusted. There is some unfunded research (mine and others) that is valid, being based on a genuine interest in finding out the truth. But it mostly falls upon industry to fund valid research — thus the "nope".]
Pingback: Newsflash: Tobacco companies are incredibly timid | Anti-THR Lies and related topics
charlie | 14 April 2016 at 6:38 pm | Reply
I understand the tobacco companies are doing some interesting research on vaping. I'd love to see it and see how it gets reviewed by other researchers. I corresponded with a guy who is apparently a neuro sciene teacher. I suggested a study where the grades of student vapers are compared to the rest of the student body. (What if nicotine makes you smarter?) He says the politics of his school would prevent that from ever being approved. There is censorship on lots of levels already.
How about a study where you follow lots of vapers, the older the better, and see how they do via consent to access health insurance records. I have a feeling the health differences between senior citizen vapers and the same age group who continue to smoke will be dramatic and not require so much finesse to detect.


text:
The biggest genre surprises and snubs from the 2021 Golden Globe nominations
February 3, 2021, 10:09 AM ET
By Matthew Jackson
Credit: Christopher Willard/Hulu
This year's Golden Globe nominees were always going to be a little weird. In a year when dozens of major films were pushed to future release dates and dozens more were shuffled off to video-on-demand and streaming releases due to the ongoing pandemic, it was a little tricky to track the conversation around the biggest titles. Still, going into Wednesday's nominations, a few things seemed certain, even among the somewhat thin selection of genre movies and shows that always have to fight against the prestige releases for nominations during awards season. Now that we know what the nominations actually look like versus what we thought they'd look like, it's time to talk about the uncertain, from the pleasant surprises to the unpleasant ones.
Here are our picks for the biggest surprises and snubs among genre movies and shows in this year's Golden Globe nominations.
Surprise: La Llorona for Best Foreign Language Film — Horror cinema has, with a few key exceptions, always had to fight for space in awards season, so it's nice when any title gets to slip into the field, and this year the horror gem that managed to crack the Golden Globes is Jayro Bustamente's politically charged take on the La Llorona legend. We've known for a few months that Guatemala planned to submit the film as its entry for Best International Film at the Oscars this year, and now that level of attention and the immense critical acclaimed heaped on the film have landed it a Globes nod.
Snub: Cristin Milioti for Palm Springs — Though it couldn't have possibly been planned, time loop comedy Palm Springs felt like the perfect movie for 2020, a film that arrived at just the right time to deliver a beautifully orchestrated film about finding meaning in the same-ness of daily life, and for the most part the Hollywood Foreign Press agreed with critics and audiences on that score. The film got its expected nod for Motion Picture — Musical or Comedy, and snagged an acting nod for star Andy Samberg. Even among the celebration, though, something was missing: A nomination for co-star Cristin Milioti, who carried just as much, if not more, of the film as Samberg did and who ultimately steered the movie into its final emotional turn.
Snub: The Boys — Though it's been around for a couple of years now, 2020 really felt like the breakout year for Amazon's superhero satire series The Boys, particularly as it turned its darkly comic lens even more into the political climate of the United States and pulled no punches with an insane Season 2 finale. It was perhaps a long shot for a Globes win, but more than a few pundits thought it at least had a shot at a nod for Best Television Series, perhaps even in the Drama category. Sadly, it seems those hopes were false, perhaps because no one was sure if it deserved to contend for Drama or Comedy honors.
Surprise: Ratched — It might be a bit of a stretch to called Ratched a genre series, but Evan Romansky and Ryan Murphy's One Flew Over the Cuckoo's Nest prequel skirts the line between thriller and outright horror enough that we're going to count it here, in part because we didn't expect to be talking about in connection with the Globes at all. The series arrived on Netflix in September to mixed reviews despite the always compelling Sarah Paulson at the center of its narrative, and it didn't seem like a major awards contender. Still, Paulson's presence and Netflix's ongoing goodwill with awards organizations seems to have put it over the top.
Snub: The cast of Lovecraft Country — With its mix of horror and incisive commentary on the history of racism in America, HBO's Lovecraft Country became one of the most buzzed-about and acclaimed new series of 2020, and now it's getting the awards love to back that up...some of it, anyway. The series got its expected nomination for Best Television Series - Drama on Wednesday morning, but it was still snubbed in the acting categories, leaving stars Jonathan Majors and Jurnee Smollett without Globe nods for their powerful, versatile work on the genre-bending series.
Snub: What We Do in the Shadows for Everything — What We Do in the Shadows could have been an amusing novelty series, a flash in the pan inspired by a beloved cult film that didn't offer anything lasting. Instead, the FX mockumentary series has become one of the most consistently delightful and surprising shows on television over the course of two seasons, and in Season 2 it managed to infuse some real narrative complexity into its already winning blend of comedy and supernatural fantasy. Sadly, none of that translated to love from the Globes, as both the series itself and its cast — including Matt Berry, who was a favorite for an acting nod this year — were left waiting in their coffins for nominations that never came.
Snub: Pedro Pascal for The Mandalorian — It's easy to chalk The Mandalorian's popularity up to the sheer presence of new live-action Star Wars stories at the push of a button, and certainly the might of the franchise has something to do with its success. But what's sometimes lost in conversations about the show is just how much Pedro Pascal contributes to its effectiveness, which is why he spent so much time in interviews for Season 2 talking about getting out into the armor more so he could imbue the title character with more of his own physicality and presence. This is a show whose two main characters are a cute green puppet and a guy who almost never takes his shiny, eyeless helmet off, and yet it still carries tremendous emotional stakes every single week. A lot of that is thanks to Pascal, and while it was nice to see the show pick up a Best Television Series - Drama nomination, it was a little disheartening to see Mando himself left out of the love.
Golden Globes 2020: Joker's wild with two big wins while the rest of genre folds
WIRE Buzz: Golden Globes delayed; more V/H/S; and David F. Sandberg horror
Tim Allen returns for 'Santa Clause' sequel series on Disney+
The Expanse star Shohreh Aghdashloo reveals why she thinks the finale's legacy will endure
Peacock's Wolf Like Me trailer reveals series secret
DC announces 'Flashpoint' sequel series 'Flashpoint Beyond'
School's out in trailer for Netflix zombie series 'All of Us Are Dead'

redpajama_set_name: RedPajamaCommonCrawl


text:
Famous People with Epilepsy
Epilepsy is a neurological disorder that causes unprovoked, recurrent seizures. Many manage to control this condition with medication, but there is no cure for epilepsy. Surgery may be used to help manage extreme cases of this disease. Listed below are famous people that have epilepsy and how they have overcome this condition to leave a significant impact on the world.
Musician Neil Young is known for his powerful lyrics and is often noted as one of the greatest guitarists from his time. Young also acts as a spokesman for environmental issues and acts as a peacekeeper, using his music as a way to speak out against injustice. Neil Young has suffered from many medical obstacles including polio, epilepsy and diabetes.
The following video showcases Neil Young in concert in 1971:
Stage and voice actor Hugo Weaving is best known for his role as leader of the elves in Lord of the Rings or the virtual, invincible villain in The Matrix. Weaving was diagnosed with epilepsy when he was 13 and due to this condition he cannot drive.
Burton was once the highest paid actor in Hollywood, famed for his distinctive voice. Epilepsy plagued him all his life, and he eventually fell into deep alcoholism trying to control his seizures. This led to manic depression which he refused to treat because he did not trust doctors. In some cases he seemed to be scared of mental illness than his epilepsy.
Danny Glover
Danny Glover acted in Lethal Weapon alongside Mel Gibson as well as in Predator 2. Glover was noted for having dyslexia in school, causing his school staff to label him retarded. He revealed on an episode of the Rosie O'Donnell Show that he was diagnosed with epilepsy at 15. The early development of this disease caused him to experience six seizures in a row during a family cross-country trip.
Chanda Gunn
American hockey player Chanda Gunn won bronze at the Winter Olympics in 2006 in spite of suffering from temporal lobe epilepsy. Gunn is determined to make the most of each day and faces life with zest. In addition to her metal at the Olympics, Gunn was the first player to be a finalist for both the Humanitarian Award for college hockey's finest citizen and the Patty Kazmaier Award for best female hockey player in the nation.
Roosevelt served as a historian, soldier, naturalist, explorer, Governor of New York, author and President of the United States from October 27, 1858- January 6, 1919. He suffered from epileptic seizures, asthma and poor eyesight, but still had a great personal strength and courage that many admired.
Bud Abbott
American comedian, producer and actor Bud Abbott would often try to hide the fact that he had epilepsy. He suffered from this disease his whole life and eventually started trying to control it with alcohol. His alcoholism eventually caused him tax issues with the IRS, leading him to go bankrupt.
Swedish engineer, chemist, innovator, inventor of dynamite and armaments manufacturer Alfred Nobel was plagued with epileptic seizures as a child. He wrote of these agonies in a poem which is often quoted today. Alfred Nobel outlined the foundations for the Nobel Prize in his will in 1895 which dedicated much of his estate to establishing the prize.
The passionate artists Vincent Van Gogh believed in expressing all emotions through color. His epilepsy symptoms once caused him to chase his friends with a razor and then cut off part of his earlobe. He later shot himself, believing this course of action to be "for the good of all." He is now remembered through his many colorful paintings.
Baron Byron of Rochdale in County Palatine of Lancaster is a well-known title from the Peerage of England. This title was founded in 1643 for Sir John Byron via letters patent. Sir John Byron was a cavalier general and a member of Parliament. Some biographies of Sir Byron imply that he suffered from epileptic seizures as some of his written passages speak of symptoms that are similar to those of epilepsy.
Edgar Allen Poe was a literacy critic and author during the Romantic Movement. He has written many short stories and books known for their mysterious and macabre themes. He is often credited with inventing detective fiction. Many believe Poe's mental instability stemmed from drug use, but today historians suspect that he may have had epilepsy that was undiagnosed, leading to frequent confusion.
In many portrayals, Julius Caesar is depicted as suffering from epilepsy. The famous movie Caesar and Cleopatra featuring Richard Burton and Elizabeth Taylor shows Caesar fearing the likelihood that he would have an epileptic attack when he addressed the Roman populace. Wikipedia also notes that Caesar had four documented episodes of complete partial seizures, and may have also experienced seizures when he was young. Many historians argue that these seizures could have been caused by chills form malaria or low blood sugar.
Famous People with Cerebral Palsy
Famous People with Asperger's
Famous Deaf People
Famous People with Dyslexia
Famous Blind People
Famous People with Schizophrenia
Patau Syndrome
Famous People with MS
High Functioning Autism
Famous People with Bipolar Disorder
Famous Celebrities with Borderline Personality Disorder
Edwards Syndrome
Facts about Physical Therapy


text:
Expanded Link URLs
« Return to Article
Mobster Anthony Rabito Banned From Favorite Italian Restaurants
Erin Zimmer
Mobster Anthony "Fat Tony" Rabito, consigliere of the Bonanno crime family, can no longer get his fat on at four old-school Italian eateries in New York City, according to the New York Post. Just released from Loretto federal prison in Pennsylvania last month after charges of gambling, racketeering, and extortion, Rabito won't be able to celebrate with a big fork full of mussels marinara or lemon chicken at Rao's in East Harlem, Bamonte's in Williamsburg, the Parkside Restaurant in Corona, and Don Peppe in Ozone Park.
When gangsters get out of prison, they are usually placed on supervised release for three years and prohibited from hanging out with other convicted felons or known mob members or associates. Rabito's case, however, appears unique in that his probation officers allegedly told him to stay away from specific restaurants. Probation officials refused to comment.
The story does a pretty phenomenal job capitalizing on all the inherent mobster puns, like how Rabito got "bada-banned" and "still longs for a pizza the action."


New, BLUE- very good condition.
Aluminium racing style road bike. 26" 100 psi rated road tyres with scrader valve. Single speed flip flop hub gear set. Double pivot, aluminium caliper brakes. Racing style pedals with feet housing. Suitable for riders up to 6'5 and 120kg (19 stone). Available in 3 colours.
These retro-style single speed bicycles are ideal for urban commutes as they offer easy maintenance and fast cycling. The single gear ratio and low weight offers an ideal compromise to allow users to both accelerate very fast and maintain a high speed all in one gear. Cycling up small inclines will be easily achieved because of its lightweight chassis and its 'just right' gear ratio. The so called 'flip flop hub' allows the cyclist to free wheel and coast down a hill (like a standard bike), or, by flipping the rear wheel over, the cyclist can have a fixed gear (like that of a track / velodrome bike). The fixed gear is very much an experience; it helps maintain the momentum of the bike via constantly rotating pedals; this encourages the cyclist to keep pedalling. It also allows the cyclist to both accelerate and brake with their feet which allows more control when braking in wet or icy conditions. This is because your feet are in complete control of the rear wheel rather than the brake pads potentially slipping (due to water / ice) or the wheels potentially locking due to the over application of the brakes. So we are bringing retro back. We, at bicycles4u, think these single speed bicycles look and feel great. They have that solid, safe and sturdy feel while maintaining the slim and sophisticated elegance attributed to much more expensive bicycles of this genre.


Unlike last week, there was a little movement in the top 10. Unbeaten Central Florida moved up two spots to No. 9. The Knights became the first team from outside the Power Five conference to be ranked in the selection committee's top 10.
Committee chairman Rob Mullens, the Oregon athletic director, said the group spend "considerable time" discussing Ohio State, which beat Maryland 52-51 in overtime on Saturday, and UCF, coming off a 38-13 victory against CIncinnati.
"We said while UCF might not have the depth of talent of Ohio State, the committee thought they're playing more as an all-around team," Mullens said.
No. 11 was Florida, which could help the Gators secure a New Year's Six bowl bid. Penn State is 12th.
There is a case to be made that there is literally no way UCF would be allowed in the playoff. The conspiracy theorist would say the selection committee has been given their Power Five marching orders and that's that. There is a glass ceiling over UCF no matter the chaos in the other conferences. The less cynical would say UCF's schedule, not as rigorous as the other top teams, would deservedly keep the Knights out even if the alternative is teams that have lost two or even three games.
CFP executive director Bill Hancock has often said there is no glass ceiling on the Group of Five teams. They just need aggressive and fortuitous nonconference scheduling. The example often give is Houston of the American Athletic Conference in 2016. The Cougars, coming off a Peach Bowl victory like UCF this season, beat two highly ranked Power Five teams with star quarterback that season — Oklahoma with Baker Mayfield and Louisville with Lamar Jackson. But they lost three conference games and didn't even earn a major bowl bid.
UCF doesn't have those victories this season. Its game against North Carolina was cancelled by a hurricane, and the Tar Heels aren't any good, anyway. UCF did play and pound Pittsburgh in September and the Panthers have turned out to be a good enough to reach the Atlantic Coast Conference championship game against Clemson in two weeks.
UCF needs all these teams to win their conference titles and Alabama to win the Southeastern Conference at 13-0. At that point Notre Dame would likely reach the playoff no matter what it does against Southern California this weekend. Let's just assume the Irish win and are 12-0 and in.
Assuming Clemson gets a mulligan and gets into the playoff, every other team would have at least two losses. At that point, wouldn't the committee have to give UCF a chance?


text:
'Messi is loved!' - PSG coach Galtier gushes over star after seeing him up close
Ryan Tolmich
The club's new manager raved about his star attacker
Paris Saint-Germain boss Christophe Galtier heaped praise on Lionel Messi after being quizzed on Thursday about what it felt like to manage the Argentina icon. Galtier took over as PSG's head coach this summer, replacing Messi's compatriot Mauricio Pochettino.
Galtier previously managed against Messi, having led Nice last season, but he now gets to work alongside the ex-Barcelona star up close and has raved about the forward's impact.
What did Galtier say?
"I can not be surprised [by how good he is] because when you have such a record, such a number of matches, such trophies, it is because you are a very great professional," Galtier said.
"He has confirmed it [right away for me]. Leo does all the training sessions, he is involved, he is smiling, he exchanges with his partners, he is an inspiration for our players and I enjoy every moment to see him on the field, to say hello to him every day because he represents the example to follow.
"He has won everything, he just missed the World Cup but at club level he has won everything. He has won individual awards but he is not satisfied, far from it. I think he is happy and when Leo smiles, the team smiles. He is loved and admired by his peers."
Messi's PSG career so far
Messi joined PSG ahead of the 2021-22 season, having left Barcelona on a free transfer during the summer.
He scored 11 goals in 34 games across all competitions in his first season with the club, as PSG once again ran away to a Ligue 1 title.
Messi has netted three times in two matches to start this season, recently scoring a brace in PSG's opener against Clermont Foot.
Copyright © 2023 Goal (Kuwait English) All rights reserved. The information contained in Goal (Kuwait English) may not be published, broadcast, rewritten, or redistributed without the prior written authority of Goal (Kuwait English)


text:
Q: Hghlighted field with red border in Wordpress Contact Form 7 I want to get this effect http://jquery.bassistance.de/validate/demo/ by Wordpress Contact Form 7.
I set in css
.wpcf7-not-valid{
    border:1px solid #d73333!important;
}

But when I insert value into the field the red border do not disappear.

A: Got a good solution. In wp-content\plugins\contact-form-7\includes\js\scripts.js
Changed
$.fn.wpcf7NotValidTip = function(message) {
        return this.each(function() {
            var into = $(this);
            into.append('' + message + '');
            $('span.wpcf7-not-valid-tip').mouseover(function() {
                $(this).fadeOut('fast');
            });
            into.find(':input').mouseover(function() {
                into.find('.wpcf7-not-valid-tip').not(':hidden').fadeOut('fast');
            });
            into.find(':input').focus(function() {
                into.find('.wpcf7-not-valid-tip').not(':hidden').fadeOut('fast');
            });
        });
    };

to this code
$.fn.wpcf7NotValidTip = function(message) {
        return this.each(function() {
            var into = $(this);

            $theParent = into.parent("span");
            $parentInp = $theParent.parent("input");

            into.find(':input').css('border-color', '#d73333');

            into.find(':input').mouseover(function() {
                into.find(':input').css('border-color','#cccccc');
            });
            into.find(':input').focus(function() {
                into.find(':input').css('border-color','#cccccc');
            });
        });
    };

A:
.wpcf7-validation-errors, .wpcf7-mail-sent-ng {
padding: 5px;
color: #E68B8B;
background-color: #FDF5F8 !important;
border: 1px solid #FDE2E2 !important;
width: 518px !important;
}

A: There is no universal solution because it all depends on how you styled your form
Anyway you can try use something like that:
span .wpcf7-not-valid {
    border: 1px solid #ff0000 !important;
}

Note: using !important is never the best way to do anything with css

redpajama_set_name: RedPajamaStackExchange


text:
HUXLEY'S AMERICAN LECTURES.
number and variety of fossil horses than any that the Old World can show. Eohippus and Orohippus from the American Eocene deposits, and Mesohippus from the American Miocene deposits, are most important links in the series (the later members of which are Pliohippus, Hipparion, and Anchitherium, found also in European Tertiary strata), connecting the living one-toed genus Equus with a typically five-toed ancestor common to it and other ungulate mammals. The structure of the feet and teeth of this series of forms, which furnish demonstrative evidence of the evolution of the horse by progressive modification, is placed before the reader in its main features with great clearness, and the description is notably assisted by a full-page woodcut.
The choice of the term "Miltonic" in place of any other for what is sometimes termed the "Mosaic" account or hypothesis of creation, and the statement of the reasons which have led to that choice, are samples of a kind of serious jesting in which Prof. Huxley shows infinite skill and delicacy. There is no doubt, he urges, as to Milton's view of the history of creation, as given in his great poem. On the other hand, were a writer to call this the "Biblical doctrine," he "would be met by the authority of many eminent scholars, to say nothing of men of science, who at various times have absolutely denied that any such doctrine is to be found in Genesis." In fact, we are told by these authorities that the six days of Genesis are six periods that we may make just as long or as short as convenience requires. "A person," says Prof. Huxley, "who is not a Hebrew scholar can only stand aside and admire the marvelous flexibility of a language which admits of such diverse interpretations." The term "Mosaic," in reference to the same doctrine, Prof. Huxley also considers objectionable, because "we are now assured upon the authority of the highest critics, and even of dignitaries of the Church, that there is no evidence that Moses wrote the book of Genesis, or knew anything about it."
"You will understand," he says, "that I give no judgment—it would be an impertinence upon my part to volunteer even a suggestion—upon such a subject. But that being the state of opinion among scholars and the clergy, it is well for the unlearned in Hebrew lore, and for the laity, to avoid entangling themselves in such a vexed question. Happily, Milton leaves us no excuse for doubting what he means, and I shall therefore be safe in speaking of the opinion in question as the Miltonic hypothesis."
The Baltimore address gives us a sketch of the writer's ideal of primary education, of university education, and especially of medical education—how to encourage research, and how best to fill vacancies in a professoriate. He does not hold the view that "you can go into the market and buy research, and that supply will follow demand, as in the ordinary course of commerce." His conviction is that "the best investigators are usually those who have also the responsibilities of instruction." Very valuable for other universities than that of


Perhaps best described as a graphic artist, Mason McFee's work is all sorts of things to all sorts of people; I think you either love it straight away or become seduced by it's charm over time and understanding. I personally love the bizarre but endearing darkness to his work; his style and the media he works with is mixed, but always equally absorbing.
Visit his website to appreciate the full breadth of his folio.


Are you nice, smart and determined to change the world?
OK maybe not the world, but definitely a multi–trillion global industry. Sound like your sort of friendly revolution? Excellent – take a look at the opportunities here and apply today.
Are you a Mid-Snr iOS Developer?
eventcloud is growing. We've shed the start–up mantle and are an established company that's hell bent on growing our business and taking the reins of the event technology sector (in a friendly, helpful way of course). Our eventcloud app is a winner with clients around the world, and we're looking for a Mid-Snr iOS Developer to join our team, and to help us elevate an already established, loved and leading product.
You've worked in or near the events sector. Heck, you've gone to an event and used a provided app or other form of event technology. One thing that makes eventcloud different is that we understand our clients' world. We started there. And we want to ensure that maintain that connection (in every part of our team).
We serve clients around the world, and there are times when you need to engage out of hours.
You don't need to be told to make it better, you seek out opportunities to do so.
We're a small office. Personality is worth its weight in gold.
We'll help you get started. You'll get support. But you need to want to grow and improve and enhance your skills. Trust us, there's no ceiling at eventcloud.
We have a learning culture, and you may be asked to help others develop their skills based on your knowledge and experience.
No waiting around being told what to do.
Your birthday off every year and a host of perks (the bar opens at 4pm on a Friday).
So you think you're a fit? Great. Send an email with your CV, salary expectations and a cover letter describing why you want to join eventcloud to goingup@eventcloud.co No matter what, we'll reply. And we really hope to meet you face to face soon!
Are you a Senior Backend Developer?
eventcloud is growing. We've shed the start–up mantle and are an established company that's hell bent on growing our business and taking the reins of the event technology sector (in a friendly, helpful way of course). Our eventcloud app is a winner with clients around the world, and we're looking for an Senior Backend Developer to join our team, and to help us elevate an already established, loved and leading product.


text:
Food Systems Decision Support Toolbox
Developed by KIT Royal Tropical Institute and Wageningen Economic Research, with funding from the Netherlands Food Partnership, this tool generates practical recommendations for food and nutrition security policy and programming.
It is the product of a series of assignments commissioned by the Dutch Ministry of Foreign Affairs and Ministry of Agriculture, Nature and Food Quality to support their food and nutrition security programming in low- and middle-income countries.
Photo by ©FAO/Luis Tato
A systems approach to food & nutrition security
There is growing recognition that a systemic approach is needed to effectively shape food and nutrition security (FNS) programming – one which takes into account the complexities of how food is produced, traded and consumed in a given context. This is reflected in the Ministry's growing desire to incorporate a food systems approach into their FNS programming.
The Food Systems Decision Support Toolbox applies a food systems lens for country-based FNS policy planning, for example by Netherlands Embassies. It takes decision-makers, such as policymakers and investors, through an analytical process to understand the bigger picture and complexity of a food system. By enabling them to see the key constraints and bottlenecks, it facilitates the decision-making process of how to intervene, where to invest resources, what policies to develop, or which partnerships to use to trigger transformative change with the limited resources available.
KIT and WUR subsequently applied the tool to better understand food systems in Ethiopia, Burkina Faso, Niger and Nigeria with the aim of supporting Dutch FNS programming in those countries. For example, in Nigeria, the tool produced several concrete recommendations to increase access to healthy food, namely through investment in vegetable, fish, milk and poultry value chains.
Learn more about our work to build Inclusive Food Systems
CountryEthiopia, Burkina Faso, Niger & Nigeria
Duration2018 - Present
FundersNetherlands Food Partnership; Dutch Ministry of Foreign Affairs and Dutch Ministry of Agriculture, Nature and Food Quality
PartnersWageningen Economic Research
DowloadThe Food System Decision Support Toolbox
Gerard Baltissen
Mona Dhamankar
Julie Newton
17. Partnership for the goals
The 7 steps of the Food System Decision Support tool
The tool uses system thinking to focus interventions on typical system behaviours (called archetypes) and on leverage points for bringing about transformative change. The stepwise approach identifies which actors can influence and direct this transformation. Taking the different steps helps to match the broader FNS objectives and the context-specific dynamics and relationships in food systems. The seven steps of the tool are outlined in the figure below.
The Food Systems Decision Support Tool uses a seven-step approach to identify trends, underlying systems structures and patterns to map what shapes a food system and how policymakers and other stakeholders can achieve maximum effect with the limited resources available to them. *RNE refers to Royal Netherlands Embassy
As the tool provides an effective overview and a properly substantiated focus, the Ministries are interested in extending this research to other countries. The KIT/Wageningen team is also further developing the tool to enable non-public parties such as NGOs and businesses to use it in the future.
What is a food system?
In recent years, the concept of food systems is increasingly used in debates on food and nutrition security, sustainable agriculture, agri-food value chains, and poverty alleviation. KIT defines* food systems as a system that embraces:
All elements (environment, people, inputs, processes, infrastructure, institutions, etc.)
All activities that relate to the production, processing, distribution, preparation and consumption of food
The outputs of these activities, including socio-economic and environmental outcomes.
Food system map (Van Berkum et al. 2018)
*KIT's definition of a food system is based on Ericksen PJ. 2008. Conceptualizing food systems for global environmental change research. Global Environmental Change 18(1): 234-245
Herramientas para la toma de decisiones en Sistemas Alimentarios
Archetypes: Common systemic behaviours in food systems
Food systems: From concept to practice and vice versa
The Food Systems Decision-Support Tool: Application in the case of the Sahel
The Food Systems Decision-Support Tool Application in the case of Ethiopia
Enhancing Food Systems in Nigeria
g.baltissen@kit.nl+31 (0) 20 56 88 219
M.Dhamankar@kit.nl+31 (0)20 568 8316
J.Newton@kit.nl+31 (0)20 568 8527


text:
FROM python:3.8
ENV PYTHONUNBUFFERED True
COPY requirements.txt ./
RUN python3 -m pip install --no-cache-dir -r requirements.txt
WORKDIR /custom
COPY ./csv_transform.py .
CMD ["python3", "csv_transform.py"]

redpajama_set_name: RedPajamaGithub


The New Year hasn't yet dawned, and still advertisements, commercials and websites are shouting in bold, capital letters about New Year, New You -- in other words, New Year's health resolutions. But the truth about wellness is that it requires year-round dedication, and the most effective changes are often less sweeping and more manageable.
A goal to diet and lose 50 pounds, if needed, can be an excellent way to achieve better health; but in reality, unless that 50 pounds is whittled down in manageable bits, and attended to daily, it will likely never be met.
The desire to slow down and live a less stressful life needs to be acted upon each day, not just on January 1st.
Resolving to exercise more is one of the most positive changes that can be made for greater wellness and quality of life. However, exercise requires time to become a regular habit. Setting a goal to exercise two days a week is better than setting one of six and then "failing" miserably.
Making changes slowly, and sticking to those changes consistently, is the key to improving health in the long run. Having the support of others can also make a big difference in whether or not goals and resolutions are met.
Besides making manageable changes for the long term and having adequate social support to help make those changes into habits, there are other ways to assist in sticking to new routines. Clinical aromatherapy is an effective, natural support for those hoping to stick to New Year's health and wellness resolutions for a lifetime.
Utilizing clinical aromatherapy in this manner may sound unconventional, but in reality, clinical aromatherapy has been scientifically studied and is backed by hospitals.
The Ascents® line of specifically-formulated, 100% natural essential oil blends can assist in making health and wellness a priority that lasts beyond January 31st.
For instance, Ascents® Curb No. 23 calms cravings and keeps snacking to a minimum when following a weight loss program; Calm No. 34 delivers fast, effective relief from stress and anxiety; and Energize No. 17 supplies a boost of motivating energy to assist in powering through even the toughest workouts.
To get on the path to better health in 2014 by purchasing Ascents® clinical aromatherapy blends, or for more information about how Ascents® effectively contributes to individual wellness goals, visit ShopAscents.com.


Psychometric Aptitude Test Pdf Flow Direction Plays a vital role in RRB ALP 2019. In every exam you will get atleast 2-3 questions from this topic. So candidates must focus on this topic and download this Psychometric Aptitude Test Pdf Flow Direction pdf to get perfect questions with best solution regarding Psycho Paper . We have put Previous Year Questions of Psychometric Aptitude Test Pdf Flow Direction that are Asked in RRB ALP Exam.


Hard to find this amount of land so close to town.
Semi timbered with tracks over the property, adjoining state forest on 2 boundaries.
Build your dream country manor and enjoy the fabulous rural lifestyle!


Sabrina has been very passionate about being a fitness and lifestyle coach and has been very involved in the fitness industry for more than eight years. She was a personal trainer, and she was an owner who operated FitnessZeal, an online training and personal training business.
She also operated a fitness business and fitness studio in Austin, Texas from 2010 to 2015 before she moved to California and then now to Colorado where she currently resides. In addition to her fitness experience, Sabrina was a NPC Bikini Competitor in the NPC Bodybuilding division for three years, and she competed in 10 shows where she won first places 4 times and 1 overall.
She is currently more into running, doing home fitness and strength training, and doing outdoor activities since she stopped doing the competitions. She has been involved in different aspects of fitness, from being a studio instructor to being a personal trainer to doing online coaching.
She has been featured in Oxygen Fitness and Austin Fit magazines She is currently working with Gripbell as one of their Gripbell Trainers, and she is operating her own business, Simple & Fit, LLC full time.


text:
package org.support.project.knowledge.control.open;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.support.project.common.exception.ParseException;
import org.support.project.common.log.Log;
import org.support.project.common.log.LogFactory;
import org.support.project.common.util.DateUtils;
import org.support.project.common.util.StringJoinBuilder;
import org.support.project.common.util.StringUtils;
import org.support.project.di.DI;
import org.support.project.di.Instance;
import org.support.project.knowledge.config.AppConfig;
import org.support.project.knowledge.config.SystemConfig;
import org.support.project.knowledge.config.UserConfig;
import org.support.project.knowledge.control.KnowledgeControlBase;
import org.support.project.knowledge.dao.CommentsDao;
import org.support.project.knowledge.dao.DraftItemValuesDao;
import org.support.project.knowledge.dao.ExGroupsDao;
import org.support.project.knowledge.dao.ExUsersDao;
import org.support.project.knowledge.dao.KnowledgeHistoriesDao;
import org.support.project.knowledge.dao.KnowledgeItemValuesDao;
import org.support.project.knowledge.dao.KnowledgesDao;
import org.support.project.knowledge.dao.LikeCommentsDao;
import org.support.project.knowledge.dao.LikesDao;
import org.support.project.knowledge.dao.PinsDao;
import org.support.project.knowledge.dao.StocksDao;
import org.support.project.knowledge.dao.TagsDao;
import org.support.project.knowledge.dao.TemplateMastersDao;
import org.support.project.knowledge.entity.CommentsEntity;
import org.support.project.knowledge.entity.DraftItemValuesEntity;
import org.support.project.knowledge.entity.KnowledgeHistoriesEntity;
import org.support.project.knowledge.entity.KnowledgeItemValuesEntity;
import org.support.project.knowledge.entity.KnowledgesEntity;
import org.support.project.knowledge.entity.LikeCommentsEntity;
import org.support.project.knowledge.entity.LikesEntity;
import org.support.project.knowledge.entity.PinsEntity;
import org.support.project.knowledge.entity.StocksEntity;
import org.support.project.knowledge.entity.TagsEntity;
import org.support.project.knowledge.entity.TemplateItemsEntity;
import org.support.project.knowledge.entity.TemplateMastersEntity;
import org.support.project.knowledge.logic.DiffLogic;
import org.support.project.knowledge.logic.EventsLogic;
import org.support.project.knowledge.logic.GroupLogic;
import org.support.project.knowledge.logic.KeywordLogic;
import org.support.project.knowledge.logic.KnowledgeLogic;
import org.support.project.knowledge.logic.LikeLogic;
import org.support.project.knowledge.logic.MarkdownLogic;
import org.support.project.knowledge.logic.TagLogic;
import org.support.project.knowledge.logic.TargetLogic;
import org.support.project.knowledge.logic.TemplateLogic;
import org.support.project.knowledge.logic.TimeZoneLogic;
import org.support.project.knowledge.logic.UploadedFileLogic;
import org.support.project.knowledge.logic.activity.Activity;
import org.support.project.knowledge.logic.activity.ActivityLogic;
import org.support.project.knowledge.vo.LikeCount;
import org.support.project.knowledge.vo.ListData;
import org.support.project.knowledge.vo.MarkDown;
import org.support.project.knowledge.vo.Participations;
import org.support.project.knowledge.vo.StockKnowledge;
import org.support.project.knowledge.vo.UploadFile;
import org.support.project.web.bean.LabelValue;
import org.support.project.web.bean.LoginedUser;
import org.support.project.web.boundary.Boundary;
import org.support.project.web.common.HttpStatus;
import org.support.project.web.common.HttpUtil;
import org.support.project.web.control.service.Get;
import org.support.project.web.control.service.Post;
import org.support.project.web.dao.SystemConfigsDao;
import org.support.project.web.dao.UserConfigsDao;
import org.support.project.web.dao.UsersDao;
import org.support.project.web.entity.GroupsEntity;
import org.support.project.web.entity.SystemConfigsEntity;
import org.support.project.web.entity.UserConfigsEntity;
import org.support.project.web.entity.UsersEntity;
import org.support.project.web.exception.InvalidParamException;

/**
 * ナレッジ操作のコントロール
 *
 * @author Koda
 */
@DI(instance = Instance.Prototype)
public class KnowledgeControl extends KnowledgeControlBase {
    /** ログ */
    private static final Log LOG = LogFactory.getLog(KnowledgeControl.class);
    /** Cookieに保持する閲覧履歴の件数 */
    private static final int COOKIE_COUNT = 20;
    /** Cookieに保持する閲覧履歴の区切り文字 */
    private static final String COOKIE_SEPARATOR = "-";
    /** ナレッジ一覧に表示する件数 */
    public static final int PAGE_LIMIT = 50;
    /** お気に入りに表示する件数 */
    public static final int FAV_PAGE_LIMIT = 10;

    /**
     * ナレッジを表示
     *
     * @return
     * @throws InvalidParamException
     * @throws ParseException
     */
    @Get(publishToken = "knowledge")
    public Boundary view() throws InvalidParamException, ParseException {
        // 共通処理呼の表示条件の保持の呼び出し
        setViewParam();

        Long knowledgeId = super.getPathLong(Long.valueOf(-1));

        SystemConfigsDao dao = SystemConfigsDao.get();
        SystemConfigsEntity config = dao.selectOnKey(SystemConfig.SYSTEM_URL, AppConfig.get().getSystemName());
        StringBuilder url = new StringBuilder();
        if (config == null) {
            url.append(HttpUtil.getContextUrl(getRequest()));
        } else {
            url.append(config.getConfigValue());
        }
        url.append("/open.knowledge/view/").append(knowledgeId);
        setAttribute("url", url.toString());

        KnowledgeLogic knowledgeLogic = KnowledgeLogic.get();
        LoginedUser loginedUser = getLoginedUser();

        if (loginedUser == null) {
            KnowledgesEntity entity = KnowledgesDao.get().selectOnKey(knowledgeId);
            if (entity == null) {
                return sendError(HttpStatus.SC_404_NOT_FOUND, "NOT FOUND");
            }

            if (!entity.getPublicFlag().equals(KnowledgeLogic.PUBLIC_FLAG_PUBLIC)) {
                return super.redirect(getRequest().getContextPath() + "/protect.knowledge/view/" + knowledgeId);
            }
        }

        KnowledgesEntity entity = knowledgeLogic.selectWithTags(knowledgeId, getLoginedUser());
        if (entity == null) {
            return sendError(HttpStatus.SC_404_NOT_FOUND, "NOT FOUND");
        }

        // 今見たナレッジの情報をCookieに保存
        List<String> ids = new ArrayList<String>();
        ids.add(String.valueOf(knowledgeId));
        String history = getCookie(SystemConfig.COOKIE_KEY_HISTORY);
        LOG.debug("history: " + history);
        if (history.indexOf(COOKIE_SEPARATOR) != -1) {
            String[] historyIds = history.split(COOKIE_SEPARATOR);
            for (int i = 0; i < historyIds.length; i++) {
                if (!ids.contains(historyIds[i]) && StringUtils.isLong(historyIds[i])) {
                    ids.add(historyIds[i]);
                }
                if (ids.size() >= COOKIE_COUNT) {
                    break;
                }
            }
        } else {
            if (!ids.contains(history)) {
                ids.add(history);
            }
        }
        String cookieHistory = String.join(COOKIE_SEPARATOR, ids);
        setCookie(SystemConfig.COOKIE_KEY_HISTORY, cookieHistory);

        // Markdownを処理
        entity.setTitle(sanitize(entity.getTitle()));
        MarkDown markDown = MarkdownLogic.get().markdownToHtml(entity.getContent());
        entity.setContent(markDown.getHtml());

        setAttributeOnProperty(entity);

        String offset = super.getParam("offset", String.class);
        if (StringUtils.isEmpty(offset)) {
            offset = "0";
        }
        setAttribute("offset", offset);

        // ナレッジに紐づく添付ファイルを取得
        UploadedFileLogic fileLogic = UploadedFileLogic.get();
        List<UploadFile> files = fileLogic.selectOnKnowledgeId(knowledgeId, getRequest().getContextPath());
        setAttribute("files", files);

        // 閲覧履歴を追加
        knowledgeLogic.addViewHistory(knowledgeId, getLoginedUser());

        // いいね!の件数取得
        LikesDao likesDao = LikesDao.get();
        Long count = likesDao.countOnKnowledgeId(knowledgeId);
        setAttribute("like_count", count);

        // コメント取得
        CommentsDao commentsDao = CommentsDao.get();
        List<CommentsEntity> comments = commentsDao.selectOnKnowledgeId(knowledgeId);
        // Markdown を処理
        for (CommentsEntity commentsEntity : comments) {
            MarkDown markDown2 = MarkdownLogic.get().markdownToHtml(commentsEntity.getComment());
            commentsEntity.setComment(markDown2.getHtml());

            Long likeCount = LikeCommentsDao.get().selectOnCommentNo(commentsEntity.getCommentNo());
            commentsEntity.setLikeCount(likeCount);
        }
        setAttribute("comments", comments);

        // 表示するグループを取得
        // List<GroupsEntity> groups = GroupLogic.get().selectGroupsOnKnowledgeId(knowledgeId);
        List<LabelValue> groups = TargetLogic.get().selectTargetsViewOnKnowledgeId(knowledgeId, loginedUser);
        setAttribute("groups", groups);

        // 編集権限
        List<LabelValue> editors = TargetLogic.get().selectEditorsViewOnKnowledgeId(knowledgeId, loginedUser);
        setAttribute("editors", editors);
        List<LabelValue> editors2 = TargetLogic.get().selectEditorsOnKnowledgeId(knowledgeId);
        boolean edit = knowledgeLogic.isEditor(loginedUser, entity, editors2);
        setAttribute("edit", edit);

        ArrayList<Long> knowledgeIds = new ArrayList<Long>();
        knowledgeIds.add(entity.getKnowledgeId());

        // ナレッジの公開先の情報を取得(共通処理)
        setKnowledgeTargets(loginedUser, knowledgeIds);

        //ストック情報を取得
        List<StocksEntity> stocks = StocksDao.get().selectStockOnKnowledge(entity, loginedUser);
        setAttribute("stocks", stocks);

        UserConfigsEntity stealth = UserConfigsDao.get().selectOnKey(UserConfig.STEALTH_ACCESS, AppConfig.get().getSystemName(), getLoginUserId());
        if (stealth == null || !"1".equals(stealth.getConfigValue())) {
            ActivityLogic.get().processActivity(Activity.KNOWLEDGE_SHOW, getLoginedUser(), DateUtils.now(), entity);
        }
        long point = KnowledgesDao.get().selectPoint(entity.getKnowledgeId());
        setAttribute("point", point);

        return forward("view.jsp");
    }

    /**
     * ナレッジの公開先の情報を取得
     * @param loginedUser
     * @param knowledges
     */
    private void setKnowledgeTargetsWithConv(LoginedUser loginedUser, List<KnowledgesEntity> knowledges) {
        ArrayList<Long> knowledgeIds = new ArrayList<>();
        for (KnowledgesEntity knowledgesEntity : knowledges) {
            knowledgeIds.add(knowledgesEntity.getKnowledgeId());
        }
        setKnowledgeTargets(loginedUser, knowledgeIds);
    }
    /**
     * ナレッジの公開先の情報を取得
     * @param loginedUser
     * @param knowledgeIds
     */
    private void setKnowledgeTargets(LoginedUser loginedUser, List<Long> knowledgeIds) {
        TargetLogic targetLogic = TargetLogic.get();
        Map<Long, List<LabelValue>> targets = targetLogic.selectTargetsOnKnowledgeIds(knowledgeIds, loginedUser);
        setAttribute("targets", targets);
        setAttribute("targetLogic", targetLogic);
    }

    /**
     * タグとグループの情報を取得(一覧画面の右側のサブリスト部分に表示する情報をセット)
     * @param loginedUser
     */
    private void setSublistInformations(LoginedUser loginedUser) {
        TagsDao tagsDao = TagsDao.get();
        ExGroupsDao groupsDao = ExGroupsDao.get();

        // タグとグループの情報を取得(画面右側のサブリスト部分に表示する)
        if (loginedUser != null && loginedUser.isAdmin()) {
            // 管理者であれば、ナレッジの件数は、参照権限を考慮していない
            List<TagsEntity> tags = tagsDao.selectTagsWithCount(0, FAV_PAGE_LIMIT);
            setAttribute("tags", tags);

            List<GroupsEntity> groups = groupsDao.selectGroupsWithCount(0, FAV_PAGE_LIMIT);
            setAttribute("groups", groups);
        } else {
            TagLogic tagLogic = TagLogic.get();
            List<TagsEntity> tags = tagLogic.selectTagsWithCount(loginedUser, 0, FAV_PAGE_LIMIT);
            setAttribute("tags", tags);

            if (loginedUser != null) {
                GroupLogic groupLogic = GroupLogic.get();
                List<GroupsEntity> groups = groupLogic.selectMyGroup(loginedUser, 0, FAV_PAGE_LIMIT);
                setAttribute("groups", groups);
            }
        }
        LOG.trace("タグ、グループ取得完了");

        List<TemplateMastersEntity> templateList = TemplateLogic.get().selectAll();
        Map<Integer, TemplateMastersEntity> templates = new LinkedHashMap<>();
        for (TemplateMastersEntity templateMastersEntity : templateList) {
            templates.put(templateMastersEntity.getTypeId(), templateMastersEntity);
        }
        setAttribute("templates", templates);
    }

    /**
     * 一覧に表示するオフセット(ページ番号)を取得する
     * @return
     * @throws InvalidParamException
     */
    private Integer getOffsetParameter() throws InvalidParamException {
        Integer offset = super.getPathInteger(0);
        int previous = offset - 1;
        if (previous < 0) {
            previous = 0;
        }
        setAttribute("offset", offset);
        setAttribute("previous", previous);
        setAttribute("next", offset + 1);
        return offset;
    }

    /**
     * リストを表示
     *
     * @return
     * @throws Exception
     */
    @Get
    public Boundary list() throws Exception {
        LOG.trace("Call list");
        Integer offset = getOffsetParameter();

        String keyword = getParam("keyword");
        setAttribute("searchKeyword", keyword);

        // ログインユーザ情報を最新化
        // TODO 毎回最新化するのは、パフォーマンスが悪い?グループ情報が更新になった場合に、影響があるユーザの一覧を保持しておき、
        // そのユーザのみを更新した方が良いかも。いったんは、ナレッジの一覧を表示する際に、毎回更新してみる(それほど負荷が高くなさそうなので)
        updateLoginInfo();

        // 共通処理呼の表示条件の保持の呼び出し
        setViewParam();

        TagsDao tagsDao = TagsDao.get();
        ExGroupsDao groupsDao = ExGroupsDao.get();
        KnowledgeLogic knowledgeLogic = KnowledgeLogic.get();
        KeywordLogic keywordLogic = KeywordLogic.get();

        LoginedUser loginedUser = super.getLoginedUser();
        String tag = getParam("tag");
        String group = getParam("group");
        String user = getParam("user");
        String tagNames = getParam("tagNames");
        String groupNames = getParam("groupNames");
        String creators = getParam("creators");
        String[] templates = getParam("template", String[].class);

        boolean hiddenFilter = false;
        if ("quickFilter".equals(getParam("from"))) {
            if (templates == null) {
                templates = new String[0];
            }
            hiddenFilter = true;
            if (getLoginedUser() != null && getLoginUserId() != Integer.MIN_VALUE) {
                UserConfigsEntity config = UserConfigsDao.get().selectOnKey("LIST_FILTERS", AppConfig.get().getSystemName(), getLoginUserId());
                // Filterの設定を変更した
                if (config == null) {
                    config = new UserConfigsEntity();
                    config.setSystemName(AppConfig.get().getSystemName());
                    config.setConfigName("LIST_FILTERS");
                    config.setUserId(getLoginUserId());
                }
                StringJoinBuilder<String> builder = new StringJoinBuilder<>();
                for (String template : templates) {
                    builder.append(template);
                }
                String value = builder.join(",");
                if (!value.equals(config.getConfigValue())) {
                    config.setConfigValue(value);
                    UserConfigsDao.get().save(config);
                }
            }
            setAttribute("params", ""); // Filterの設定変更の場合は、検索パラメータをクリア
        } else {
            if (getLoginedUser() != null && getLoginUserId() != Integer.MIN_VALUE) {
                UserConfigsEntity config = UserConfigsDao.get().selectOnKey("LIST_FILTERS", AppConfig.get().getSystemName(), getLoginUserId());
                if (templates == null) {
                    // 検索画面からきていない
                    if (config != null) {
                        templates = config.getConfigValue().split(",");
                    }
                    // フィルタの条件を変更していないので、フィルタは表示しない
                    if (StringUtils.isEmpty(keyword)) {
                        hiddenFilter = true;
                    }
                }
            }
        }

        String keywordSortTypeString = getCookie(SystemConfig.COOKIE_KEY_KEYWORD_SORT_TYPE);
        int keywordSortType;
        if ("" == keywordSortTypeString) {
            keywordSortType = KnowledgeLogic.KEYWORD_SORT_TYPE_SCORE;
        } else {
            keywordSortType = Integer.valueOf(keywordSortTypeString);
        }
        knowledgeLogic.setKeywordSortType(keywordSortType);
        setAttribute("keywordSortType", keywordSortType);

        List<KnowledgesEntity> knowledges = new ArrayList<>();
        try {
            if (StringUtils.isInteger(tag)) {
                // タグを選択している
                LOG.trace("show on Tag");
                knowledges.addAll(knowledgeLogic.showKnowledgeOnTag(tag, loginedUser, offset * PAGE_LIMIT, PAGE_LIMIT));
                TagsEntity tagsEntity = tagsDao.selectOnKey(new Integer(tag));
                List<Integer> tagIds = new ArrayList<Integer>();
                String name = "";
                if (tagsEntity != null) {
                    tagIds.add(tagsEntity.getTagId());
                    name = tagsEntity.getTagName();
                }
                setAttribute("selectedTag", tagsEntity);
                setAttribute("selectedTagIds", tagIds);
                setAttribute("searchKeyword", keywordLogic.toTagsQuery(name) + keyword);
            } else if (StringUtils.isInteger(group)) {
                // グループを選択している
                LOG.trace("show on Group");
                knowledges.addAll(knowledgeLogic.showKnowledgeOnGroup(group, loginedUser, offset * PAGE_LIMIT, PAGE_LIMIT));
                GroupsEntity groupsEntity = groupsDao.selectOnKey(new Integer(group));
                List<Integer> groupIds = new ArrayList<Integer>();
                String name = "";
                if (groupsEntity != null) {
                    groupIds.add(groupsEntity.getGroupId());
                    name = groupsEntity.getGroupName();
                }
                setAttribute("selectedGroup", groupsEntity);
                setAttribute("selectedGroupIds", groupIds);
                setAttribute("searchKeyword", keywordLogic.toGroupsQuery(name) + keyword);
            } else if (StringUtils.isNotEmpty(user) && StringUtils.isInteger(user)) {
                // ユーザを選択している
                LOG.trace("show on User");
                int userId = Integer.parseInt(user);
                knowledges.addAll(knowledgeLogic.showKnowledgeOnUser(userId, loginedUser, offset * PAGE_LIMIT, PAGE_LIMIT));
                UsersEntity usersEntity = UsersDao.get().selectOnKey(userId);
                usersEntity.setPassword("");
                setAttribute("selectedUser", usersEntity);
            } else if (StringUtils.isNotEmpty(tagNames) || StringUtils.isNotEmpty(groupNames)) {
                // タグとキーワードで検索
                LOG.trace("show on Tags and Groups and keyword");
                String searchKeyword = "";
                String[] taglist = tagNames.split(",");
                List<TagsEntity> tags = new ArrayList<TagsEntity>();
                List<Integer> tagIds = new ArrayList<Integer>();
                for (String string : taglist) {
                    String tagname = string.trim();
                    if (tagname.startsWith(" ") && tagname.length() > " ".length()) {
                        tagname = tagname.substring(" ".length());
                    }
                    TagsEntity tagsEntity = tagsDao.selectOnTagName(tagname);
                    if (tagsEntity != null) {
                        tags.add(tagsEntity);
                        tagIds.add(tagsEntity.getTagId());
                    }
                }
                if (0 < tags.size()) {
                    searchKeyword += keywordLogic.toTagsQuery(tagNames.replaceAll("[\\xc2\\xa0]", ""));
                }

                List<GroupsEntity> groups = new ArrayList<GroupsEntity>();
                List<Integer> groupIds = new ArrayList<Integer>();
                if (loginedUser != null) {
                    String[] grouplist = groupNames.split(",");
                    for (String string : grouplist) {
                        String groupname = string.trim();
                        if (groupname.startsWith(" ") && groupname.length() > " ".length()) {
                            groupname = groupname.substring(" ".length());
                        }
                        GroupsEntity groupsEntity = groupsDao.selectOnGroupName(groupname);
                        if (groupsEntity != null) {
                            groups.add(groupsEntity);
                            groupIds.add(groupsEntity.getGroupId());
                        }
                    }
                    if (0 < groups.size()) {
                        searchKeyword += keywordLogic.toGroupsQuery(groupNames.replaceAll("[\\xc2\\xa0]", ""));
                    }
                }

                setAttribute("selectedTags", tags);
                setAttribute("selectedGroups", groups);
                setAttribute("selectedTagIds", tagIds);
                setAttribute("selectedGroupIds", groupIds);
                setAttribute("searchKeyword", searchKeyword + keyword);

                knowledges.addAll(knowledgeLogic.searchKnowledge(keyword, tags, groups, null, templates, loginedUser, offset * PAGE_LIMIT, PAGE_LIMIT));
            } else {
                // その他(キーワード検索)
                LOG.trace("search");
                List<GroupsEntity> groups = null;
                List<TagsEntity> tags = null;
                List<Integer> groupIds = new ArrayList<Integer>();
                List<Integer> tagIds = new ArrayList<Integer>();

                if (loginedUser != null) {
                    String groupKeyword = keywordLogic.parseQuery("groups", keyword);
                    if (groupKeyword != null) {
                        groups = new ArrayList<GroupsEntity>();
                        for (String groupName : groupKeyword.split(",")) {
                            GroupsEntity groupsEntity = groupsDao.selectOnGroupName(groupName);
                            if (groupsEntity != null) {
                                groups.add(groupsEntity);
                                groupIds.add(groupsEntity.getGroupId());
                            }
                        }
                        setAttribute("selectedGroups", groups);
                        setAttribute("selectedGroupIds", groupIds);
                    }
                }

                String tagKeyword = keywordLogic.parseQuery("tags", keyword);
                if (tagKeyword != null) {
                    tags = new ArrayList<TagsEntity>();
                    for (String tagName : tagKeyword.split(",")) {
                        TagsEntity tagsEntity = tagsDao.selectOnTagName(tagName);
                        if (tagsEntity != null) {
                            tags.add(tagsEntity);
                            tagIds.add(tagsEntity.getTagId());
                        }
                    }
                    setAttribute("selectedTags", tags);
                    setAttribute("selectedTagIds", tagIds);
                }

                keyword = keywordLogic.parseKeyword(keyword);

                setAttribute("keyword", keyword);

                List <UsersEntity> creatorUserEntities = new ArrayList<>();
                if (StringUtils.isNotEmpty(creators)) {
                    String[] creatorsArray = creators.split(",");
                    for (String userName : creatorsArray) {
                        List<UsersEntity> users = ExUsersDao.get().selectByUserName(userName);
                        creatorUserEntities.addAll(users);
                    }
                }
                setAttribute("creators", creatorUserEntities);

                knowledges.addAll(knowledgeLogic.searchKnowledge(keyword, tags, groups, creatorUserEntities, templates, loginedUser, offset * PAGE_LIMIT, PAGE_LIMIT));
            }

            // pin留めの記事取得
            if (0 == offset.intValue()) {
                List<PinsEntity> pins = PinsDao.get().selectAll();
                for (PinsEntity pin : pins) {
                    KnowledgesEntity k = KnowledgeLogic.get().select(pin.getKnowledgeId(), loginedUser);
                    if (k != null) {
                        Iterator<KnowledgesEntity> iterator = knowledges.iterator();
                        while (iterator.hasNext()) {
                            KnowledgesEntity knowledgesEntity = (KnowledgesEntity) iterator.next();
                            if (knowledgesEntity.getKnowledgeId().intValue() == pin.getKnowledgeId().intValue()) {
                                iterator.remove();
                            }
                        }
                        k.setPin(true);
                        knowledges.add(0, k); // 先頭に追加
                    }
                }
            }

            List<StockKnowledge> stocks = knowledgeLogic.setStockInfo(knowledges, loginedUser);
            KnowledgeLogic.get().setViewed(stocks, getLoginedUser());
            setAttribute("knowledges", stocks);
            LOG.trace("検索終了");

            if (templates != null) {
                List<TemplateMastersEntity> templateItems = new ArrayList<>();
                for (String template: templates) {
                    if (StringUtils.isNotEmpty(template) && StringUtils.isInteger(template)) {
                        TemplateMastersEntity templateMastersEntity = TemplateMastersDao.get().selectOnKey(new Integer(template));
                        templateItems.add(templateMastersEntity);
                    }
                }
                if (LOG.isDebugEnabled()) {
                    LOG.debug(templateItems);
                }
                if (!hiddenFilter) {
                    setAttribute("types", templateItems);
                }
                setAttribute("selectedTemplates", templateItems);
            }
            // ナレッジの公開先の情報を取得
            setKnowledgeTargetsWithConv(loginedUser, knowledges);
            // タグとグループの情報を取得(一覧画面の右側のサブリスト部分に表示する情報をセット)
            setSublistInformations(loginedUser);

            return forward("list.jsp");
        } catch (InvalidParamException e) {
            return forward("list.jsp");
        }
    }

    /**
     * イベント一覧
     *
     * @return
     * @throws InvalidParamException
     */
    @Get
    public Boundary events() throws InvalidParamException {
        String date = getParam("date");
        String timezone = getParam("timezone");
        LoginedUser loginedUser = super.getLoginedUser();
        if (StringUtils.isEmpty(date) || StringUtils.isEmpty(timezone)) {
            return sendError(HttpStatus.SC_400_BAD_REQUEST, "BAD REQUEST");
        }
        if (!TimeZoneLogic.get().exist(timezone)) {
            return sendError(HttpStatus.SC_400_BAD_REQUEST, "BAD REQUEST");
        }
        DateFormat monthformat = new SimpleDateFormat("yyyyMMdd");
        List<KnowledgesEntity> knowledges;
        try {
            Date d = monthformat.parse(date);
            setAttribute("start", d);
            knowledges = EventsLogic.get().eventKnowledgeList(date, timezone, loginedUser);
            List<StockKnowledge> stocks = KnowledgeLogic.get().setStockInfo(knowledges, loginedUser);
            for (StockKnowledge stock : stocks) {
                Participations participations = EventsLogic.get().isParticipation(stock.getKnowledgeId(), getLoginUserId());
                stock.setParticipations(participations);
            }
            KnowledgeLogic.get().setViewed(stocks, getLoginedUser());
            setAttribute("knowledges", stocks);
        } catch (java.text.ParseException e) {
            return sendError(HttpStatus.SC_400_BAD_REQUEST, "BAD REQUEST");
        }
        // ナレッジの公開先の情報を取得
        setKnowledgeTargetsWithConv(loginedUser, knowledges);
        // タグとグループの情報を取得(一覧画面の右側のサブリスト部分に表示する情報をセット)
        setSublistInformations(loginedUser);

        return forward("events.jsp");
    }

    /**
     * 閲覧履歴の表示
     *
     * @return
     * @throws InvalidParamException
     */
    @Get
    public Boundary show_history() throws InvalidParamException {
        LoginedUser loginedUser = super.getLoginedUser();
        KnowledgeLogic knowledgeLogic = KnowledgeLogic.get();

        // History表示
        String history = getCookie(SystemConfig.COOKIE_KEY_HISTORY);
        List<String> historyIds = new ArrayList<>();
        ArrayList<Long> knowledgeIds = new ArrayList<>();
        LOG.debug("history: " + history);
        if (history.indexOf(COOKIE_SEPARATOR) != -1) {
            String[] splits = history.split(COOKIE_SEPARATOR);
            for (String string : splits) {
                if (StringUtils.isLong(string)) {
                    historyIds.add(string);
                    knowledgeIds.add(new Long(string));
                }
            }
        } else {
            if (StringUtils.isLong(history)) {
                historyIds.add(history);
                knowledgeIds.add(new Long(history));
            }
        }
        List<KnowledgesEntity> histories = knowledgeLogic.getKnowledges(historyIds, loginedUser);
        List<StockKnowledge> stocks = knowledgeLogic.setStockInfo(histories, loginedUser);
        KnowledgeLogic.get().setViewed(stocks, getLoginedUser());
        setAttribute("histories", stocks);
        LOG.trace("履歴取得完了");

        // ナレッジの公開先の情報を取得
        setKnowledgeTargets(loginedUser, knowledgeIds);
        // タグとグループの情報を取得(一覧画面の右側のサブリスト部分に表示する情報をセット)
        setSublistInformations(loginedUser);

        return forward("show_history.jsp");
    }

    /**
     * 人気のKnowledgeを表示
     *
     * @return
     * @throws InvalidParamException
     */
    @Get
    public Boundary show_popularity() throws InvalidParamException {
        LoginedUser loginedUser = super.getLoginedUser();
        KnowledgeLogic knowledgeLogic = KnowledgeLogic.get();

        List<KnowledgesEntity> list = knowledgeLogic.getPopularityKnowledges(loginedUser, 0, 20);
        List<StockKnowledge> stocks = knowledgeLogic.setStockInfo(list, loginedUser);
        KnowledgeLogic.get().setViewed(stocks, getLoginedUser());
        setAttribute("popularities", stocks);
        LOG.trace("取得完了");
        // ナレッジの公開先の情報を取得
        setKnowledgeTargetsWithConv(loginedUser, list);
        // タグとグループの情報を取得(一覧画面の右側のサブリスト部分に表示する情報をセット)
        setSublistInformations(loginedUser);

        return forward("popularity.jsp");
    }

    /**
     * ストックしたナレッジを表示
     *
     * @return
     * @throws InvalidParamException
     */
    @Get
    public Boundary stocks() throws InvalidParamException {
        Integer offset = getOffsetParameter();
        String stockidstr = getParam("stockid");
        LoginedUser loginedUser = super.getLoginedUser();
        Long stockid = null;
        if (StringUtils.isLong(stockidstr)) {
            stockid = Long.parseLong(stockidstr);
            StocksEntity stocksEntity = StocksDao.get().selectOnKey(stockid);
            if (stocksEntity == null || stocksEntity.getInsertUser().intValue() != getLoginUserId().intValue()) {
                // タグとグループの情報を取得(一覧画面の右側のサブリスト部分に表示する情報をセット)
                setSublistInformations(loginedUser);
                // Stockにアクセスできない
                return forward("stocks.jsp");
            } else {
                setAttribute("stock", stocksEntity);
            }
        }

        KnowledgeLogic knowledgeLogic = KnowledgeLogic.get();
        List<KnowledgesEntity> list = knowledgeLogic.getStocks(loginedUser, offset * PAGE_LIMIT, PAGE_LIMIT, stockid);
        List<StockKnowledge> stocks = knowledgeLogic.setStockInfo(list, loginedUser);
        KnowledgeLogic.get().setViewed(stocks, getLoginedUser());
        setAttribute("popularities", stocks);
        LOG.trace("取得完了");

        // ナレッジの公開先の情報を取得
        setKnowledgeTargetsWithConv(loginedUser, list);
        // タグとグループの情報を取得(一覧画面の右側のサブリスト部分に表示する情報をセット)
        setSublistInformations(loginedUser);

        return forward("stocks.jsp");
    }

    /**
     * いいねを押下
     *
     * @return
     * @throws InvalidParamException
     */
    @Post(subscribeToken="knowledge")
    public Boundary like() throws InvalidParamException {
        Long knowledgeId = super.getPathLong(Long.valueOf(-1));
        Long count = LikeLogic.get().addLike(knowledgeId, getLoginedUser(), getLocale());
        LikeCount likeCount = new LikeCount();
        likeCount.setKnowledgeId(knowledgeId);
        likeCount.setCount(count);
        return send(likeCount);
    }
    /**
     * コメントにイイネを押下
     * @return
     * @throws InvalidParamException
     */
    @Post(subscribeToken="knowledge")
    public Boundary likecomment() throws InvalidParamException {
        Long commentNo = super.getPathLong(Long.valueOf(-1));
        Long count = LikeLogic.get().addLikeComment(commentNo, getLoginedUser(), getLocale());
        LikeCount likeCount = new LikeCount();
        likeCount.setCount(count);
        return send(likeCount);
    }

    /**
     * タイトルとコンテンツの危険なタグをエスケープした結果を返す
     *
     * @param entity
     * @return
     * @throws ParseException
     */
    @Post(subscribeToken = "")
    public Boundary escape(KnowledgesEntity entity) throws ParseException {
        super.setSendEscapeHtml(false);
        entity.setTitle(sanitize(entity.getTitle()));
        entity.setContent(sanitize(entity.getContent()));
        return super.send(entity);
    }

    /**
     * タイトルの危険なタグをサニタイズし、コンテンツのmarkdownをHTMLへ変換する
     *
     * @param entity
     * @return
     * @throws ParseException
     */
    @Post(subscribeToken = "")
    public Boundary marked(KnowledgesEntity entity) throws ParseException {
        super.setSendEscapeHtml(false);
        entity.setTitle(sanitize(entity.getTitle()));
        MarkDown markDown = MarkdownLogic.get().markdownToHtml(entity.getContent());
        entity.setContent(markDown.getHtml());
        return super.send(entity);
    }

    /**
     * 検索画面を表示
     *
     * @return
     */
    @Get
    public Boundary search() {
        KeywordLogic keywordLogic = KeywordLogic.get();
        LoginedUser loginedUser = super.getLoginedUser();
        List<GroupsEntity> groupitems = new ArrayList<GroupsEntity>();
        List<TagsEntity> tagitems = TagsDao.get().selectAll();
        setAttribute("tagitems", tagitems);
        if (loginedUser != null) {
            if (loginedUser.isAdmin()) {
                groupitems = ExGroupsDao.get().selectAll();
            } else {
                groupitems = loginedUser.getGroups();
            }
        }
        setAttribute("groupitems", groupitems);
        // 共通処理呼の表示条件の保持の呼び出し
        setViewParam();

        // groups:やtags:などの検索クエリを分解してフォームに表示するために分解したデータをセットする
        String keyword = getParam("keyword");
        setAttribute("searchKeyword", keywordLogic.parseKeyword(keyword));
        setAttribute("tagNames", keywordLogic.parseQuery("tags", keyword));
        if (loginedUser != null) {
            setAttribute("groupNames", keywordLogic.parseQuery("groups", keyword));
        }
        List<TemplateMastersEntity> templates = TemplateLogic.get().selectAll();
        setAttribute("templates", templates);
        return forward("search.jsp");
    }

    /**
     * いいねを押したユーザを一覧表示
     *
     * @return
     * @throws InvalidParamException
     */
    @Get
    public Boundary likes() throws InvalidParamException {
        // 共通処理呼の表示条件の保持の呼び出し
        setViewParam();

        Long knowledgeId = super.getPathLong(Long.valueOf(-1));
        setAttribute("knowledgeId", knowledgeId);
        // 権限チェック(いったんアクセスできるユーザは全て表示) TODO 登録者のみにする?
        KnowledgeLogic knowledgeLogic = KnowledgeLogic.get();
        KnowledgesEntity entity = knowledgeLogic.select(knowledgeId, getLoginedUser());
        if (entity == null) {
            return sendError(HttpStatus.SC_404_NOT_FOUND, "NOT FOUND");
        }

        Integer page = 0;
        String p = getParamWithDefault("page", "");
        if (StringUtils.isInteger(p)) {
            page = Integer.parseInt(p);
        }

        LikesDao likesDao = LikesDao.get();
        List<LikesEntity> likes = likesDao.selectOnKnowledge(knowledgeId, page * PAGE_LIMIT, PAGE_LIMIT);
        setAttribute("likes", likes);

        int previous = page - 1;
        if (previous < 0) {
            previous = 0;
        }
        setAttribute("page", page);
        setAttribute("previous", previous);
        setAttribute("next", page + 1);

        return forward("likes.jsp");
    }

    /**
     * いいねを押したユーザを一覧表示(コメントに対し)
     *
     * @return
     * @throws InvalidParamException
     */
    @Get
    public Boundary likecomments() throws InvalidParamException {
        // 共通処理呼の表示条件の保持の呼び出し
        setViewParam();

        Long commentNo = super.getPathLong(Long.valueOf(-1));
        CommentsEntity comment = CommentsDao.get().selectOnKey(commentNo);
        if (comment == null) {
            return sendError(HttpStatus.SC_404_NOT_FOUND, "NOT FOUND");
        }
        setAttribute("knowledgeId", comment.getKnowledgeId());
        setAttribute("commentNo", comment.getKnowledgeId());

        Integer page = 0;
        String p = getParamWithDefault("page", "");
        if (StringUtils.isInteger(p)) {
            page = Integer.parseInt(p);
        }

        List<LikeCommentsEntity> likes = LikeCommentsDao.get().selectOnCommentNo(commentNo, page * PAGE_LIMIT, PAGE_LIMIT);
        setAttribute("likes", likes);

        int previous = page - 1;
        if (previous < 0) {
            previous = 0;
        }
        setAttribute("page", page);
        setAttribute("previous", previous);
        setAttribute("next", page + 1);

        return forward("likes.jsp");
    }

    /**
     * 編集履歴の表示
     *
     * @return
     * @throws InvalidParamException
     */
    @Get
    public Boundary histories() throws InvalidParamException {
        // 共通処理呼の表示条件の保持の呼び出し
        setViewParam();

        Long knowledgeId = super.getPathLong(Long.valueOf(-1));
        setAttribute("knowledgeId", knowledgeId);
        // 権限チェック(いったんアクセスできるユーザは全て表示)
        KnowledgeLogic knowledgeLogic = KnowledgeLogic.get();
        KnowledgesEntity entity = knowledgeLogic.select(knowledgeId, getLoginedUser());
        if (entity == null) {
            return sendError(HttpStatus.SC_404_NOT_FOUND, "NOT FOUND");
        }

        Integer page = 0;
        String p = getParamWithDefault("page", "");
        if (StringUtils.isInteger(p)) {
            page = Integer.parseInt(p);
        }
        int previous = page - 1;
        if (previous < 0) {
            previous = 0;
        }
        setAttribute("page", page);
        setAttribute("previous", previous);
        setAttribute("next", page + 1);

        // 履歴を取得
        KnowledgeHistoriesDao historiesDao = KnowledgeHistoriesDao.get();
        List<KnowledgeHistoriesEntity> histories = historiesDao.selectOnKnowledge(knowledgeId, page * PAGE_LIMIT, PAGE_LIMIT);
        setAttribute("histories", histories);

        return forward("histories.jsp");
    }

    /**
     * 編集履歴の更新内容表示
     *
     * @return
     * @throws InvalidParamException
     */
    @Get
    public Boundary history() throws InvalidParamException {
        // 共通処理呼の表示条件の保持の呼び出し
        setViewParam();

        Long knowledgeId = super.getPathLong(Long.valueOf(-1));
        setAttribute("knowledgeId", knowledgeId);
        // 権限チェック(いったんアクセスできるユーザは全て表示)
        KnowledgeLogic knowledgeLogic = KnowledgeLogic.get();
        KnowledgesEntity entity = knowledgeLogic.select(knowledgeId, getLoginedUser());
        if (entity == null) {
            return sendError(HttpStatus.SC_404_NOT_FOUND, "NOT FOUND");
        }

        Integer page = 0;
        String p = getParamWithDefault("page", "");
        if (StringUtils.isInteger(p)) {
            page = Integer.parseInt(p);
        }
        setAttribute("page", page);

        Integer historyNo = 0;
        String h = getParamWithDefault("history_no", "");
        if (StringUtils.isInteger(h)) {
            historyNo = Integer.parseInt(h);
        }

        KnowledgeHistoriesDao historiesDao = KnowledgeHistoriesDao.get();
        KnowledgeHistoriesEntity history = historiesDao.selectOnKeyWithName(historyNo, knowledgeId);
        setAttribute("history", history);
        setAttribute("now", entity);

        List<String> changes = DiffLogic.get().diff(history.getContent(), entity.getContent());
        setAttribute("changes", changes);

        return forward("history.jsp");
    }

    /**
     * ナレッジのテンプレート情報を取得
     *
     * @return
     * @throws InvalidParamException
     */
    @Get
    public Boundary template() throws InvalidParamException {
        Integer typeId = super.getParam("type_id", Integer.class);
        TemplateMastersEntity template = TemplateMastersDao.get().selectWithItems(typeId);
        if (template == null) {
            // そのテンプレートは既に削除済みの場合、通常のナレッジのテンプレートで表示する(ナレッジのテンプレートは削除できないようにする)
            typeId = TemplateLogic.TYPE_ID_KNOWLEDGE;
            template = TemplateMastersDao.get().selectWithItems(typeId);
        }

        String draftId = super.getParam("draft_id");
        String knowledgeId = super.getParam("knowledge_id");
        if (StringUtils.isNotEmpty(draftId) && StringUtils.isLong(draftId)) {
            List<DraftItemValuesEntity> values = DraftItemValuesDao.get().selectOnDraftId(new Long(draftId));
            List<TemplateItemsEntity> items = template.getItems();
            for (DraftItemValuesEntity val : values) {
                for (TemplateItemsEntity item : items) {
                    if (val.getItemNo().equals(item.getItemNo())) {
                        item.setItemValue(val.getItemValue());
                        break;
                    }
                }
            }
        } else if (StringUtils.isNotEmpty(knowledgeId) && StringUtils.isLong(knowledgeId)) {
            KnowledgeLogic knowledgeLogic = KnowledgeLogic.get();
            KnowledgesEntity entity = knowledgeLogic.select(new Long(knowledgeId), getLoginedUser());
            if (entity == null) {
                return sendError(HttpStatus.SC_404_NOT_FOUND, "NOT FOUND");
            }

            // 保存している値も返す
            List<KnowledgeItemValuesEntity> values = KnowledgeItemValuesDao.get().selectOnKnowledgeId(entity.getKnowledgeId());
            List<TemplateItemsEntity> items = template.getItems();
            for (KnowledgeItemValuesEntity val : values) {
                for (TemplateItemsEntity item : items) {
                    if (val.getItemNo().equals(item.getItemNo())) {
                        item.setItemValue(val.getItemValue());
                        break;
                    }
                }
            }
        }
        return send(template);
    }

    /**
     * オートコンプリートの候補を取得(JSON)
     *
     * @return
     * @throws ParseException
     */
    @Get
    public Boundary items() throws ParseException {
        String q = super.getParameter("q");
        List<KnowledgesEntity> list = KnowledgeLogic.get().selectAccessAbleKnowledge(q, getLoginedUser());
        ListData listdata = new ListData();
        listdata.setItems(list);
        return super.send(listdata);
    }

}